Coverage Summary for Class: EthModuleTransactionInstant (co.rsk.rpc.modules.eth)

Class Class, % Method, % Line, %
EthModuleTransactionInstant 0% (0/1) 0% (0/5) 0% (0/32)


1 /* 2  * This file is part of RskJ 3  * Copyright (C) 2018 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.modules.eth; 20  21 import co.rsk.core.Wallet; 22 import co.rsk.core.bc.BlockExecutor; 23 import co.rsk.crypto.Keccak256; 24 import co.rsk.mine.MinerClient; 25 import co.rsk.mine.MinerServer; 26 import co.rsk.net.TransactionGateway; 27 import org.ethereum.config.Constants; 28 import org.ethereum.core.Blockchain; 29 import org.ethereum.core.TransactionPool; 30 import org.ethereum.db.TransactionInfo; 31 import org.ethereum.rpc.TypeConverter; 32 import org.ethereum.rpc.Web3; 33 import org.ethereum.rpc.exception.RskJsonRpcRequestException; 34 import org.ethereum.vm.program.ProgramResult; 35  36 import java.util.Optional; 37  38 import static org.ethereum.rpc.exception.RskJsonRpcRequestException.transactionRevertedExecutionError; 39 import static org.ethereum.rpc.exception.RskJsonRpcRequestException.unknownError; 40  41 public class EthModuleTransactionInstant extends EthModuleTransactionBase { 42  43  private final MinerServer minerServer; 44  private final MinerClient minerClient; 45  private final Blockchain blockchain; 46  private final BlockExecutor blockExecutor; 47  48  public EthModuleTransactionInstant( 49  Constants constants, 50  Wallet wallet, 51  TransactionPool transactionPool, 52  MinerServer minerServer, 53  MinerClient minerClient, 54  Blockchain blockchain, 55  TransactionGateway transactionGateway, 56  BlockExecutor blockExecutor) { 57  super(constants, wallet, transactionPool, transactionGateway); 58  59  this.minerServer = minerServer; 60  this.minerClient = minerClient; 61  this.blockchain = blockchain; 62  this.blockExecutor = blockExecutor; 63  } 64  65  @Override 66  public synchronized String sendTransaction(Web3.CallArguments args) { 67  try { 68  this.blockExecutor.setRegisterProgramResults(true); 69  70  String txHash = super.sendTransaction(args); 71  72  mineTransaction(); 73  74  return getReturnMessage(txHash); 75  } 76  finally { 77  this.blockExecutor.setRegisterProgramResults(false); 78  } 79  } 80  81  @Override 82  public String sendRawTransaction(String rawData) { 83  try { 84  this.blockExecutor.setRegisterProgramResults(true); 85  86  String txHash = super.sendRawTransaction(rawData); 87  88  mineTransaction(); 89  90  return getReturnMessage(txHash); 91  } 92  finally { 93  this.blockExecutor.setRegisterProgramResults(false); 94  } 95  } 96  97  private void mineTransaction() { 98  minerServer.buildBlockToMine(false); 99  minerClient.mineBlock(); 100  } 101  102  /** 103  * When insta-mining we can query the transaction status and return an error response immediately like Ganache. 104  * This does not apply during regular operation because queued transactions are not immediately executed. 105  */ 106  private String getReturnMessage(String txHash) { 107  TransactionInfo transactionInfo = blockchain.getTransactionInfo(TypeConverter.stringHexToByteArray(txHash)); 108  if (transactionInfo == null) { 109  throw unknownError("Unknown error when sending transaction: transaction wasn't mined"); 110  } 111  112  Keccak256 hash = new Keccak256(txHash.substring(2)); 113  ProgramResult programResult = this.blockExecutor.getProgramResult(hash); 114  115  if (programResult != null && programResult.isRevert()) { 116  Optional<String> revertReason = EthModule.decodeRevertReason(programResult); 117  118  if (revertReason.isPresent()) { 119  throw RskJsonRpcRequestException.transactionRevertedExecutionError(revertReason.get()); 120  } else { 121  throw RskJsonRpcRequestException.transactionRevertedExecutionError(); 122  } 123  } 124  125  if (!transactionInfo.getReceipt().isSuccessful()) { 126  throw transactionRevertedExecutionError(); 127  } 128  129  return txHash; 130  } 131 }