Coverage Summary for Class: ReceiptStoreImpl (org.ethereum.db)

Class Class, % Method, % Line, %
ReceiptStoreImpl 100% (1/1) 75% (6/8) 84.6% (44/52)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2017 RSK Labs Ltd. 4  * (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>) 5  * 6  * This program is free software: you can redistribute it and/or modify 7  * it under the terms of the GNU Lesser General Public License as published by 8  * the Free Software Foundation, either version 3 of the License, or 9  * (at your option) any later version. 10  * 11  * This program is distributed in the hope that it will be useful, 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14  * GNU Lesser General Public License for more details. 15  * 16  * You should have received a copy of the GNU Lesser General Public License 17  * along with this program. If not, see <http://www.gnu.org/licenses/>. 18  */ 19  20 package org.ethereum.db; 21  22 import co.rsk.crypto.Keccak256; 23 import org.ethereum.core.Block; 24 import org.ethereum.core.TransactionReceipt; 25 import org.ethereum.datasource.KeyValueDataSource; 26 import org.ethereum.util.RLP; 27 import org.ethereum.util.RLPList; 28  29 import java.util.ArrayList; 30 import java.util.Arrays; 31 import java.util.List; 32 import java.util.Optional; 33  34 /** 35  * Created by Ruben on 6/1/2016. 36  * Class used to store transaction receipts 37  */ 38  39 public class ReceiptStoreImpl implements ReceiptStore { 40  private KeyValueDataSource receiptsDS; 41  42  public ReceiptStoreImpl(KeyValueDataSource receiptsDS){ 43  this.receiptsDS = receiptsDS; 44  } 45  46  @Override 47  public void add(byte[] blockHash, int transactionIndex, TransactionReceipt receipt){ 48  byte[] txHash = receipt.getTransaction().getHash().getBytes(); 49  50  TransactionInfo newTxInfo = new TransactionInfo(receipt, blockHash, transactionIndex); 51  52  List<TransactionInfo> txsInfo = getAll(txHash); 53  54  txsInfo.add(newTxInfo); 55  56  List<byte[]> encodedTxs = new ArrayList<>(); 57  58  for (TransactionInfo ti : txsInfo) { 59  encodedTxs.add(ti.getEncoded()); 60  } 61  62  byte[][] txsBytes = encodedTxs.toArray(new byte[encodedTxs.size()][]); 63  64  receiptsDS.put(receipt.getTransaction().getHash().getBytes(), RLP.encodeList(txsBytes)); 65  } 66  67  @Override 68  public TransactionInfo get(byte[] transactionHash){ 69  List<TransactionInfo> txs = getAll(transactionHash); 70  71  if (txs.isEmpty()) { 72  return null; 73  } 74  75  return txs.get(txs.size() - 1); 76  } 77  78  @Override 79  public Optional<TransactionInfo> get(Keccak256 transactionHash, Keccak256 blockHash) { 80  // it is not guaranteed that there will be only one matching TransactionInfo, but if there were more than one, 81  // they would be exactly the same 82  return getAll(transactionHash.getBytes()).stream() 83  .filter(ti -> Arrays.equals(ti.getBlockHash(), blockHash.getBytes())) 84  .findAny(); 85  } 86  87  @Override 88  public TransactionInfo getInMainChain(byte[] transactionHash, BlockStore store) { 89  List<TransactionInfo> tis = this.getAll(transactionHash); 90  91  if (tis.isEmpty()) { 92  return null; 93  } 94  95  for (TransactionInfo ti : tis) { 96  byte[] bhash = ti.getBlockHash(); 97  98  Block block = store.getBlockByHash(bhash); 99  100  if (block == null) { 101  continue; 102  } 103  104  Block mblock = store.getChainBlockByNumber(block.getNumber()); 105  106  if (mblock == null) { 107  continue; 108  } 109  110  if (Arrays.equals(bhash, mblock.getHash().getBytes())) { 111  return ti; 112  } 113  } 114  115  return null; 116  } 117  118  @Override 119  public List<TransactionInfo> getAll(byte[] transactionHash) { 120  byte[] txsBytes = receiptsDS.get(transactionHash); 121  122  if (txsBytes == null || txsBytes.length == 0) { 123  return new ArrayList<TransactionInfo>(); 124  } 125  126  List<TransactionInfo> txsInfo = new ArrayList<>(); 127  RLPList txsList = (RLPList) RLP.decode2(txsBytes).get(0); 128  129  for (int i = 0; i < txsList.size(); ++i) { 130  RLPList rlpData = ((RLPList) txsList.get(i)); 131  txsInfo.add(new TransactionInfo(rlpData.getRLPData())); 132  } 133  134  return txsInfo; 135  } 136  137  @Override 138  public void saveMultiple(byte[] blockHash, List<TransactionReceipt> receipts) { 139  int i = 0; 140  for (TransactionReceipt receipt : receipts) { 141  this.add(blockHash, i++, receipt); 142  } 143  } 144  145  @Override 146  public void flush() { 147  this.receiptsDS.flush(); 148  } 149 }