Coverage Summary for Class: Web3InformationRetriever (co.rsk.rpc)

Class Method, % Line, %
Web3InformationRetriever 71.4% (5/7) 87.5% (28/32)
Web3InformationRetriever$MockitoMock$1399703513
Web3InformationRetriever$MockitoMock$1399703513$auxiliary$0q0724Ll
Web3InformationRetriever$MockitoMock$1399703513$auxiliary$bAmJieOQ
Web3InformationRetriever$MockitoMock$1399703513$auxiliary$gjH3qiMJ
Web3InformationRetriever$MockitoMock$1399703513$auxiliary$MnLawO9R
Web3InformationRetriever$MockitoMock$1399703513$auxiliary$yi5vQiZh
Total 71.4% (5/7) 87.5% (28/32)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2019 RSK Labs Ltd. 4  * 5  * This program is free software: you can redistribute it and/or modify 6  * it under the terms of the GNU Lesser General Public License as published by 7  * the Free Software Foundation, either version 3 of the License, or 8  * (at your option) any later version. 9  * 10  * This program is distributed in the hope that it will be useful, 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13  * GNU Lesser General Public License for more details. 14  * 15  * You should have received a copy of the GNU Lesser General Public License 16  * along with this program. If not, see <http://www.gnu.org/licenses/>. 17  */ 18  19 package co.rsk.rpc; 20  21 import co.rsk.core.bc.AccountInformationProvider; 22 import co.rsk.db.RepositoryLocator; 23 import org.ethereum.core.Block; 24 import org.ethereum.core.Blockchain; 25 import org.ethereum.core.Transaction; 26 import org.ethereum.core.TransactionPool; 27 import org.ethereum.rpc.exception.RskJsonRpcRequestException; 28  29 import java.util.List; 30 import java.util.Optional; 31  32 import static org.ethereum.rpc.TypeConverter.stringHexToBigInteger; 33 import static org.ethereum.rpc.exception.RskJsonRpcRequestException.*; 34  35 /** 36  * Retrieves information requested by web3 based on the block identifier: 37  * <p> 38  * HEX String - an integer block number 39  * String "earliest" for the earliest/genesis block 40  * String "latest" - for the latest mined block 41  * String "pending" - for the pending state/transactions 42  */ 43 public class Web3InformationRetriever { 44  private final TransactionPool transactionPool; 45  private final Blockchain blockchain; 46  private final RepositoryLocator locator; 47  48  private static final String EARLIEST = "earliest"; 49  private static final String LATEST = "latest"; 50  private static final String PENDING = "pending"; 51  52  53  public Web3InformationRetriever(TransactionPool transactionPool, Blockchain blockchain, RepositoryLocator locator) { 54  55  this.transactionPool = transactionPool; 56  this.blockchain = blockchain; 57  this.locator = locator; 58  } 59  60  /** 61  * Retrieves the block based on the identifier. 62  * @param identifier {@link Web3InformationRetriever} 63  * @return An optional containing the block if found. 64  * @throws RskJsonRpcRequestException if the identifier is {@link #PENDING}, as it is not implemented yet. 65  */ 66  public Optional<Block> getBlock(String identifier) { 67  if (PENDING.equals(identifier)) { 68  throw unimplemented("This method doesn't support 'pending' as a parameter"); 69  } 70  71  Block block; 72  if (LATEST.equals(identifier)) { 73  block = blockchain.getBestBlock(); 74  } else if (EARLIEST.equals(identifier)) { 75  block = blockchain.getBlockByNumber(0); 76  } else { 77  block = this.blockchain.getBlockByNumber(getBlockNumber(identifier)); 78  } 79  80  return Optional.ofNullable(block); 81  } 82  83  /** 84  * Retrieves an {@link AccountInformationProvider} based on the identifier. 85  * @param identifier {@link Web3InformationRetriever} 86  * @return The {@link AccountInformationProvider} 87  * @throws RskJsonRpcRequestException if the block indicated by the identifier is not found or the state for the 88  * block was not found. 89  */ 90  public AccountInformationProvider getInformationProvider(String identifier) { 91  if (PENDING.equals(identifier)) { 92  return transactionPool.getPendingState(); 93  } 94  95  Optional<Block> optBlock = getBlock(identifier); 96  if (!optBlock.isPresent()) { 97  throw blockNotFound(String.format("Block %s not found", identifier)); 98  } 99  100  Block block = optBlock.get(); 101  return locator.findSnapshotAt(block.getHeader()).orElseThrow(() -> RskJsonRpcRequestException 102  .stateNotFound(String.format("State not found for block with hash %s", block.getHash()))); 103  } 104  105  /** 106  * Retrieves an list of {@link Transaction} based on the identifier 107  * @param identifier {@link Web3InformationRetriever} 108  * @return The {@link Transaction Transactions} of {@link TransactionPool} if the identifier is {@link #PENDING}, 109  * if not, the ones on the specified block. 110  * @throws RskJsonRpcRequestException if the block indicated by the identifier is not foundl. 111  */ 112  public List<Transaction> getTransactions(String identifier) { 113  if (PENDING.equals(identifier)) { 114  return transactionPool.getPendingTransactions(); 115  } 116  117  Optional<Block> block = getBlock(identifier); 118  119  return block.map(Block::getTransactionsList) 120  .orElseThrow(() -> 121  blockNotFound(String.format("Block %s not found", identifier))); 122  123  } 124  125  private long getBlockNumber(String identifier) { 126  long blockNumber; 127  try { 128  blockNumber = stringHexToBigInteger(identifier).longValue(); 129  } catch (NumberFormatException | StringIndexOutOfBoundsException e) { 130  throw invalidParamError(String.format("invalid blocknumber %s", identifier)); 131  } 132  return blockNumber; 133  } 134 }