Skip to content

Commit

Permalink
Merge pull request #2846 from rsksmart/feature/handle_transaction_revert
Browse files Browse the repository at this point in the history
Handling transaction revert in eth_estimateGas
Vovchyk authored Nov 22, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 821de1f + 9a196df commit fb418b5
Showing 2 changed files with 65 additions and 14 deletions.
36 changes: 22 additions & 14 deletions rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java
Original file line number Diff line number Diff line change
@@ -146,20 +146,7 @@ public String call(CallArgumentsParam argsParam, BlockIdentifierParam bnOrId) {
} else {
res = callConstant(args, block);
}
if (res.isRevert()) {
Pair<String, byte[]> programRevert = decodeProgramRevert(res);
String revertReason = programRevert.getLeft();
byte[] revertData = programRevert.getRight();
if (revertData == null) {
throw RskJsonRpcRequestException.transactionRevertedExecutionError();
}

if (revertReason == null) {
throw RskJsonRpcRequestException.transactionRevertedExecutionError(revertData);
}

throw RskJsonRpcRequestException.transactionRevertedExecutionError(revertReason, revertData);
}
handleTransactionRevertIfHappens(res);
hReturn = HexUtils.toUnformattedJsonHex(res.getHReturn());

return hReturn;
@@ -193,6 +180,9 @@ public String estimateGas(CallArgumentsParam args, @Nonnull BlockIdentifierParam
snapshot
);

ProgramResult res = executor.getResult();
handleTransactionRevertIfHappens(res);

estimation = internalEstimateGas(executor.getResult());

return estimation;
@@ -357,4 +347,22 @@ private ProgramResult callConstantWithState(CallArguments args, Block executionB
hexArgs.getFromAddress()
);
}

private void handleTransactionRevertIfHappens(ProgramResult res) {
if (res.isRevert()) {
Pair<String, byte[]> programRevert = decodeProgramRevert(res);
String revertReason = programRevert.getLeft();
byte[] revertData = programRevert.getRight();

if (revertData == null) {
throw RskJsonRpcRequestException.transactionRevertedExecutionError();
}

if (revertReason == null) {
throw RskJsonRpcRequestException.transactionRevertedExecutionError(revertData);
}

throw RskJsonRpcRequestException.transactionRevertedExecutionError(revertReason, revertData);
}
}
}
43 changes: 43 additions & 0 deletions rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java
Original file line number Diff line number Diff line change
@@ -605,6 +605,49 @@ void whenExecuteEstimateGasWithDataParameter_callExecutorWithData() {
assertArrayEquals(HexUtils.strHexOrStrNumberToByteArray(args.getData()), dataCaptor.getValue());
}

@Test
void testwhenExecuteEstimateGasWithDataParameter_callExecutorWithData() {
CallArguments args = new CallArguments();
Block block = mock(Block.class);
ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class);
when(blockResult.getBlock()).thenReturn(block);
ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class);
when(retriever.retrieveExecutionBlock("latest")).thenReturn(blockResult);
Blockchain blockchain = mock(Blockchain.class);

ProgramResult executorResult = mock(ProgramResult.class);
when(executorResult.isRevert()).thenReturn(true);
TransactionExecutor transactionExecutor = mock(TransactionExecutor.class);
when(transactionExecutor.getResult())
.thenReturn(executorResult);

ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class);
when(reversibleTransactionExecutor.estimateGas(eq(block), any(), any(), any(), any(), any(), any(), any(), any()))
.thenReturn(transactionExecutor);

EthModule eth = new EthModule(
null,
Constants.REGTEST_CHAIN_ID,
blockchain,
null,
reversibleTransactionExecutor,
retriever,
mock(RepositoryLocator.class),
null,
null,
new BridgeSupportFactory(
null, null, null, signatureCache),
config.getGasEstimationCap(),
config.getCallGasCap());

CallArgumentsParam callArgumentsParam = TransactionFactoryHelper.toCallArgumentsParam(args);

RskJsonRpcRequestException exception = assertThrows(RskJsonRpcRequestException.class, () -> {
eth.estimateGas(callArgumentsParam, new BlockIdentifierParam("latest"));
});
assertThat(exception.getMessage(), Matchers.containsString("transaction reverted"));
}

@Test
void whenExecuteEstimateGasWithInputParameter_callExecutorWithInput() {
CallArguments args = new CallArguments();

0 comments on commit fb418b5

Please sign in to comment.