diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c8f6713743..8e8352f0a65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ - Fix the way an advertised host configured with `--p2p-host` is treated when communicating with the originator of a PING packet [#6225](https://github.com/hyperledger/besu/pull/6225) - Fix `poa-block-txs-selection-max-time` option that was inadvertently reset to its default after being configured [#6444](https://github.com/hyperledger/besu/pull/6444) - Fix for tx incorrectly discarded when there is a timeout during block creation [#6563](https://github.com/hyperledger/besu/pull/6563) +- Fix traces so that call gas costing in traces matches other clients traces [#6525](https://github.com/hyperledger/besu/pull/6525) ### Download Links diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByHash.java index 281d7248108..fcfe4dc052e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceByHash.java @@ -78,19 +78,18 @@ private TransactionTrace getTransactionTrace(final Block block, final Hash trans return Tracer.processTracing( blockchainQueries, Optional.of(block.getHeader()), - mutableWorldState -> { - return blockTracerSupplier - .get() - .trace( - mutableWorldState, - block, - new DebugOperationTracer(new TraceOptions(false, false, true))) - .map(BlockTrace::getTransactionTraces) - .orElse(Collections.emptyList()) - .stream() - .filter(trxTrace -> trxTrace.getTransaction().getHash().equals(transactionHash)) - .findFirst(); - }) + mutableWorldState -> + blockTracerSupplier + .get() + .trace( + mutableWorldState, + block, + new DebugOperationTracer(new TraceOptions(false, false, true), false)) + .map(BlockTrace::getTransactionTraces) + .orElse(Collections.emptyList()) + .stream() + .filter(trxTrace -> trxTrace.getTransaction().getHash().equals(transactionHash)) + .findFirst()) .orElseThrow(); } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceCall.java index f9a41f353a3..1aa6316b04b 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/AbstractTraceCall.java @@ -36,11 +36,20 @@ public abstract class AbstractTraceCall extends AbstractTraceByBlock { private static final Logger LOG = LoggerFactory.getLogger(AbstractTraceCall.class); - public AbstractTraceCall( + /** + * A flag to indicate if call operations should trace just the operation cost (false, Geth style, + * debug_ series RPCs) or the operation cost and all gas granted to the child call (true, Parity + * style, trace_ series RPCs) + */ + private final boolean recordChildCallGas; + + protected AbstractTraceCall( final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule, - final TransactionSimulator transactionSimulator) { + final TransactionSimulator transactionSimulator, + final boolean recordChildCallGas) { super(blockchainQueries, protocolSchedule, transactionSimulator); + this.recordChildCallGas = recordChildCallGas; } @Override @@ -65,7 +74,7 @@ protected Object resultByBlockNumber( return new JsonRpcErrorResponse(requestContext.getRequest().getId(), BLOCK_NOT_FOUND); } - final DebugOperationTracer tracer = new DebugOperationTracer(traceOptions); + final DebugOperationTracer tracer = new DebugOperationTracer(traceOptions, recordChildCallGas); return transactionSimulator .process( callParams, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java index 89a897df37d..f4a56f05eb5 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugAccountAt.java @@ -98,7 +98,7 @@ protected Object resultByBlockHash( .trace( mutableWorldState, blockHash, - new DebugOperationTracer(new TraceOptions(false, true, true))) + new DebugOperationTracer(new TraceOptions(false, true, true), false)) .map(BlockTrace::getTransactionTraces) .orElse(Collections.emptyList()) .stream() diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java index 6dab0436a84..3a1dee65608 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlock.java @@ -87,7 +87,10 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { mutableWorldState -> blockTracerSupplier .get() - .trace(mutableWorldState, block, new DebugOperationTracer(traceOptions)) + .trace( + mutableWorldState, + block, + new DebugOperationTracer(traceOptions, true)) .map(BlockTrace::getTransactionTraces) .map(DebugTraceTransactionResult::of)) .orElse(null); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java index 3b5f5e734f7..c1caaef2b9e 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHash.java @@ -64,7 +64,10 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { mutableWorldState -> blockTracerSupplier .get() - .trace(mutableWorldState, blockHash, new DebugOperationTracer(traceOptions)) + .trace( + mutableWorldState, + blockHash, + new DebugOperationTracer(traceOptions, true)) .map(BlockTrace::getTransactionTraces) .map(DebugTraceTransactionResult::of)) .orElse(null); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java index 977a1d87936..32d0e02f90c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumber.java @@ -66,13 +66,15 @@ protected Object resultByBlockNumber( Tracer.processTracing( blockchainQueriesSupplier.get(), hash, - mutableWorldState -> { - return blockTracerSupplier - .get() - .trace(mutableWorldState, hash, new DebugOperationTracer(traceOptions)) - .map(BlockTrace::getTransactionTraces) - .map(DebugTraceTransactionResult::of); - })) + mutableWorldState -> + blockTracerSupplier + .get() + .trace( + mutableWorldState, + hash, + new DebugOperationTracer(traceOptions, true)) + .map(BlockTrace::getTransactionTraces) + .map(DebugTraceTransactionResult::of))) .orElse(null); } } diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java index d133aa77524..ae5215282f8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceCall.java @@ -43,7 +43,7 @@ public DebugTraceCall( final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule, final TransactionSimulator transactionSimulator) { - super(blockchainQueries, protocolSchedule, transactionSimulator); + super(blockchainQueries, protocolSchedule, transactionSimulator, true); } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java index 1ce30e243e5..8ce0052b8b8 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransaction.java @@ -73,7 +73,7 @@ private DebugTraceTransactionResult debugTraceTransactionResult( final TraceOptions traceOptions) { final Hash blockHash = transactionWithMetadata.getBlockHash().get(); - final DebugOperationTracer execTracer = new DebugOperationTracer(traceOptions); + final DebugOperationTracer execTracer = new DebugOperationTracer(traceOptions, true); return Tracer.processTracing( blockchain, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java index f4e12554738..cd78d837dfa 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceBlock.java @@ -116,7 +116,7 @@ protected ArrayNodeWrapper traceBlock( "step", "action"); DebugOperationTracer debugOperationTracer = - new DebugOperationTracer(new TraceOptions(false, false, true)); + new DebugOperationTracer(new TraceOptions(false, false, true), false); ExecuteTransactionStep executeTransactionStep = new ExecuteTransactionStep( chainUpdater, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java index 724f3f780f9..439140fa315 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCall.java @@ -41,7 +41,7 @@ public TraceCall( final BlockchainQueries blockchainQueries, final ProtocolSchedule protocolSchedule, final TransactionSimulator transactionSimulator) { - super(blockchainQueries, protocolSchedule, transactionSimulator); + super(blockchainQueries, protocolSchedule, transactionSimulator, false); } @Override diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java index 4ee9ff04e33..a824b35f1eb 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceCallMany.java @@ -66,11 +66,7 @@ protected BlockParameter blockParameter(final JsonRpcRequestContext request) { final Optional maybeBlockParameter = request.getOptionalParameter(1, BlockParameter.class); - if (maybeBlockParameter.isPresent()) { - return maybeBlockParameter.get(); - } - - return BlockParameter.LATEST; + return maybeBlockParameter.orElse(BlockParameter.LATEST); } @Override @@ -153,7 +149,8 @@ private JsonNode getSingleCallResult( final BlockHeader header, final WorldUpdater worldUpdater) { final Set traceTypes = traceTypeParameter.getTraceTypes(); - final DebugOperationTracer tracer = new DebugOperationTracer(buildTraceOptions(traceTypes)); + final DebugOperationTracer tracer = + new DebugOperationTracer(buildTraceOptions(traceTypes), false); final Optional maybeSimulatorResult = transactionSimulator.processWithWorldUpdater( callParameter, buildTransactionValidationParams(), tracer, header, worldUpdater); diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java index 1e79cdd2396..1b04ee1d52c 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceFilter.java @@ -161,7 +161,7 @@ private JsonRpcResponse traceFilterWithPipeline( "action"); DebugOperationTracer debugOperationTracer = - new DebugOperationTracer(new TraceOptions(false, false, true)); + new DebugOperationTracer(new TraceOptions(false, false, true), false); ExecuteTransactionStep executeTransactionStep = new ExecuteTransactionStep( chainUpdater, diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java index 8d1f8f6506e..26da6f2f13d 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceRawTransaction.java @@ -89,7 +89,8 @@ public JsonRpcResponse response(final JsonRpcRequestContext requestContext) { } final Set traceTypes = traceTypeParameter.getTraceTypes(); - final DebugOperationTracer tracer = new DebugOperationTracer(buildTraceOptions(traceTypes)); + final DebugOperationTracer tracer = + new DebugOperationTracer(buildTraceOptions(traceTypes), false); final BlockHeader headBlock = blockchainQueriesSupplier.get().headBlockHeader(); return transactionSimulator .process( diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java index f14b88932fc..058fbd47960 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/TraceReplayBlockTransactions.java @@ -93,7 +93,7 @@ protected ArrayNode resultByBlockNumber( return getBlockchainQueries() .getBlockchain() .getBlockByNumber(blockNumber) - .map((block) -> traceBlock(block, traceTypeParameter)) + .map(block -> traceBlock(block, traceTypeParameter)) .orElse(null); } @@ -127,7 +127,7 @@ private ArrayNode traceBlock(final Block block, final TraceTypeParameter traceTy "step", "action"); final DebugOperationTracer debugOperationTracer = - new DebugOperationTracer(new TraceOptions(false, false, true)); + new DebugOperationTracer(new TraceOptions(false, false, true), false); final ExecuteTransactionStep executeTransactionStep = new ExecuteTransactionStep( chainUpdater, diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_all.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_all.json index cc6696ae142..69d19bb5e6d 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_all.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_all.json @@ -167,7 +167,7 @@ "pc" : 21, "op" : "CALLCODE", "gas" : 16755865, - "gasCost" : 700, + "gasCost" : 16494066, "depth" : 1, "stack" : null, "memory" : null, diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_complete.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_complete.json index ef20e1ae4ce..fb84953c078 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_complete.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_complete.json @@ -164,7 +164,7 @@ "pc" : 21, "op" : "CALLCODE", "gas" : 16755865, - "gasCost" : 700, + "gasCost" : 16494066, "depth" : 1, "stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000ffac99" ], "memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ], diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableMemory.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableMemory.json index 5f1ab990f96..73b391f022a 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableMemory.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableMemory.json @@ -167,7 +167,7 @@ "pc" : 21, "op" : "CALLCODE", "gas" : 16755865, - "gasCost" : 700, + "gasCost" : 16494066, "depth" : 1, "stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000ffac99" ], "memory" : null, diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStack.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStack.json index 38e3d77b250..226fcb2cd0f 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStack.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStack.json @@ -167,7 +167,7 @@ "pc" : 21, "op" : "CALLCODE", "gas" : 16755865, - "gasCost" : 700, + "gasCost" : 16494066, "depth" : 1, "stack" : null, "memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ], diff --git a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStorage.json b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStorage.json index ea6bd930442..a515b46b744 100644 --- a/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStorage.json +++ b/ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/debug/trace-call/debug_traceCall_disableStorage.json @@ -167,7 +167,7 @@ "pc" : 21, "op" : "CALLCODE", "gas" : 16755865, - "gasCost" : 700, + "gasCost" : 16494066, "depth" : 1, "stack" : [ "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000020", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000000000", "0000000000000000000000000030000000000000000000000000000000000000", "0000000000000000000000000000000000000000000000000000000000ffac99" ], "memory" : [ "f000000000000000000000000000000000000000000000000000000000000001" ], diff --git a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java index 972da935f35..275bb6e2f78 100644 --- a/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java +++ b/ethereum/core/src/integration-test/java/org/hyperledger/besu/ethereum/vm/TraceTransactionIntegrationTest.java @@ -119,7 +119,7 @@ public void shouldTraceSStoreOperation() { // Now call the transaction to execute the SSTORE. final DebugOperationTracer tracer = - new DebugOperationTracer(new TraceOptions(true, true, true)); + new DebugOperationTracer(new TraceOptions(true, true, true), false); final Transaction executeTransaction = Transaction.builder() .type(TransactionType.FRONTIER) @@ -166,7 +166,7 @@ public void shouldTraceSStoreOperation() { @Test public void shouldTraceContractCreation() { final DebugOperationTracer tracer = - new DebugOperationTracer(new TraceOptions(true, true, true)); + new DebugOperationTracer(new TraceOptions(true, true, true), false); final Transaction transaction = Transaction.readFrom( new BytesValueRLPInput(Bytes.fromHexString(CONTRACT_CREATION_TX), false)); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java index 711f83e3d9a..6644fbf5626 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java @@ -21,6 +21,7 @@ import org.hyperledger.besu.evm.ModificationNotAllowedException; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.AbstractCallOperation; import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import org.hyperledger.besu.evm.tracing.OperationTracer; @@ -39,6 +40,14 @@ public class DebugOperationTracer implements OperationTracer { private final TraceOptions options; + + /** + * A flag to indicate if call operations should trace just the operation cost (false, Geth style, + * debug_ series RPCs) or the operation cost and all gas granted to the child call (true, Parity + * style, trace_ series RPCs) + */ + private final boolean recordChildCallGas; + private List traceFrames = new ArrayList<>(); private TraceFrame lastFrame; @@ -48,8 +57,16 @@ public class DebugOperationTracer implements OperationTracer { private int pc; private int depth; - public DebugOperationTracer(final TraceOptions options) { + /** + * Creates the operation tracer. + * + * @param options The options, as passed in through the RPC + * @param recordChildCallGas A flag on whether to produce geth style (true) or parity style + * (false) gas amounts for call operations + */ + public DebugOperationTracer(final TraceOptions options, final boolean recordChildCallGas) { this.options = options; + this.recordChildCallGas = recordChildCallGas; } @Override @@ -78,14 +95,16 @@ public void tracePostExecution(final MessageFrame frame, final OperationResult o final Optional> storage = captureStorage(frame); final Optional> maybeRefunds = frame.getRefunds().isEmpty() ? Optional.empty() : Optional.of(frame.getRefunds()); + long thisGasCost = operationResult.getGasCost(); + if (recordChildCallGas && currentOperation instanceof AbstractCallOperation) { + thisGasCost += frame.getMessageFrameStack().getFirst().getRemainingGas(); + } lastFrame = new TraceFrame( pc, Optional.of(opcode), gasRemaining, - operationResult.getGasCost() == 0 - ? OptionalLong.empty() - : OptionalLong.of(operationResult.getGasCost()), + thisGasCost == 0 ? OptionalLong.empty() : OptionalLong.of(thisGasCost), frame.getGasRefund(), depth, Optional.ofNullable(operationResult.getHaltReason()), diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index 146213722b5..2a1bb23a097 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -29,12 +29,15 @@ import org.hyperledger.besu.evm.account.MutableAccount; import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.gascalculator.CancunGasCalculator; import org.hyperledger.besu.evm.operation.AbstractOperation; +import org.hyperledger.besu.evm.operation.CallOperation; import org.hyperledger.besu.evm.operation.Operation; import org.hyperledger.besu.evm.operation.Operation.OperationResult; import org.hyperledger.besu.evm.worldstate.WorldUpdater; import java.util.Map; +import java.util.OptionalLong; import java.util.TreeMap; import org.apache.tuweni.bytes.Bytes32; @@ -63,6 +66,8 @@ public OperationResult execute(final MessageFrame frame, final EVM evm) { } }; + private final CallOperation callOperation = new CallOperation(new CancunGasCalculator()); + @Test void shouldRecordProgramCounter() { final MessageFrame frame = validMessageFrame(); @@ -108,7 +113,7 @@ void shouldRecordStackWhenEnabled() { frame.pushStackItem(stackItem1); frame.pushStackItem(stackItem2); frame.pushStackItem(stackItem3); - final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(false, false, true)); + final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(false, false, true), false); assertThat(traceFrame.getStack()).isPresent(); assertThat(traceFrame.getStack().get()).containsExactly(stackItem1, stackItem2, stackItem3); } @@ -116,7 +121,7 @@ void shouldRecordStackWhenEnabled() { @Test void shouldNotRecordStackWhenDisabled() { final TraceFrame traceFrame = - traceFrame(validMessageFrame(), new TraceOptions(false, false, false)); + traceFrame(validMessageFrame(), new TraceOptions(false, false, false), false); assertThat(traceFrame.getStack()).isEmpty(); } @@ -129,7 +134,7 @@ void shouldRecordMemoryWhenEnabled() { frame.writeMemory(0, 32, word1); frame.writeMemory(32, 32, word2); frame.writeMemory(64, 32, word3); - final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(false, true, false)); + final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(false, true, false), false); assertThat(traceFrame.getMemory()).isPresent(); assertThat(traceFrame.getMemory().get()).containsExactly(word1, word2, word3); } @@ -137,7 +142,7 @@ void shouldRecordMemoryWhenEnabled() { @Test void shouldNotRecordMemoryWhenDisabled() { final TraceFrame traceFrame = - traceFrame(validMessageFrame(), new TraceOptions(false, false, false)); + traceFrame(validMessageFrame(), new TraceOptions(false, false, false), false); assertThat(traceFrame.getMemory()).isEmpty(); } @@ -145,7 +150,7 @@ void shouldNotRecordMemoryWhenDisabled() { void shouldRecordStorageWhenEnabled() { final MessageFrame frame = validMessageFrame(); final Map updatedStorage = setupStorageForCapture(frame); - final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(true, false, false)); + final TraceFrame traceFrame = traceFrame(frame, new TraceOptions(true, false, false), false); assertThat(traceFrame.getStorage()).isPresent(); assertThat(traceFrame.getStorage()).contains(updatedStorage); } @@ -153,17 +158,41 @@ void shouldRecordStorageWhenEnabled() { @Test void shouldNotRecordStorageWhenDisabled() { final TraceFrame traceFrame = - traceFrame(validMessageFrame(), new TraceOptions(false, false, false)); + traceFrame(validMessageFrame(), new TraceOptions(false, false, false), false); assertThat(traceFrame.getStorage()).isEmpty(); } + @Test + void shouldNotAddGasWhenDisabled() { + final TraceFrame traceFrame = + traceFrame(validCallFrame(), new TraceOptions(false, false, false), false); + assertThat(traceFrame.getGasCost()).isEqualTo(OptionalLong.of(20)); + } + + @Test + void shouldAddGasWhenEnabled() { + final TraceFrame traceFrame = + traceFrame(validCallFrame(), new TraceOptions(false, false, false), true); + assertThat(traceFrame.getGasCost()).isEqualTo(OptionalLong.of(1020L)); + } + + @Test + void childGasFlagDoesNotMatterForNonCallOperations() { + final TraceFrame flagDisabledTracer = + traceFrame(validMessageFrame(), new TraceOptions(false, false, false), false); + final TraceFrame flagEnabledTracer = + traceFrame(validMessageFrame(), new TraceOptions(false, false, false), true); + + assertThat(flagEnabledTracer.getGasCost()).isEqualTo(flagDisabledTracer.getGasCost()); + } + @Test void shouldCaptureFrameWhenExceptionalHaltOccurs() { final MessageFrame frame = validMessageFrame(); final Map updatedStorage = setupStorageForCapture(frame); final DebugOperationTracer tracer = - new DebugOperationTracer(new TraceOptions(true, true, true)); + new DebugOperationTracer(new TraceOptions(true, true, true), false); tracer.tracePostExecution( frame, new OperationResult(50L, ExceptionalHaltReason.INSUFFICIENT_GAS)); @@ -174,11 +203,12 @@ void shouldCaptureFrameWhenExceptionalHaltOccurs() { } private TraceFrame traceFrame(final MessageFrame frame) { - return traceFrame(frame, new TraceOptions(false, false, false)); + return traceFrame(frame, new TraceOptions(false, false, false), false); } - private TraceFrame traceFrame(final MessageFrame frame, final TraceOptions traceOptions) { - final DebugOperationTracer tracer = new DebugOperationTracer(traceOptions); + private TraceFrame traceFrame( + final MessageFrame frame, final TraceOptions traceOptions, final boolean additionalCallGas) { + final DebugOperationTracer tracer = new DebugOperationTracer(traceOptions, additionalCallGas); tracer.tracePreExecution(frame); OperationResult operationResult = anOperation.execute(frame, null); tracer.tracePostExecution(frame, operationResult); @@ -192,6 +222,13 @@ private MessageFrame validMessageFrame() { return frame; } + private MessageFrame validCallFrame() { + final MessageFrame frame = validMessageFrameBuilder().build(); + frame.setCurrentOperation(callOperation); + frame.setPC(10); + return frame; + } + private TraceFrame getOnlyTraceFrame(final DebugOperationTracer tracer) { Assertions.assertThat(tracer.getTraceFrames()).hasSize(1); return tracer.getTraceFrames().get(0); diff --git a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java index 900fcca7074..014279bf4a6 100644 --- a/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java +++ b/ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java @@ -19,6 +19,7 @@ import static picocli.CommandLine.ScopeType.INHERIT; import org.hyperledger.besu.cli.config.NetworkName; +import org.hyperledger.besu.collections.trie.BytesTrieSet; import org.hyperledger.besu.datatypes.Address; import org.hyperledger.besu.datatypes.Hash; import org.hyperledger.besu.datatypes.Wei; @@ -110,6 +111,13 @@ void setBytes(final String optionValue) { paramLabel = "") private final Long gas = 10_000_000_000L; + @Option( + names = {"--intrinsic-gas"}, + description = "Calculate and charge intrinsic and tx content gas. Default is not to charge.", + scope = INHERIT, + negatable = true) + final Boolean chargeIntrinsicGas = false; + @Option( names = {"--price"}, description = "Price of gas (in GWei) for this invocation", @@ -326,26 +334,6 @@ public void run() { .metricsSystemModule(new MetricsSystemModule()) .build(); - final BlockHeader blockHeader = - BlockHeaderBuilder.create() - .parentHash(Hash.EMPTY) - .coinbase(coinbase) - .difficulty(Difficulty.ONE) - .number(1) - .gasLimit(5000) - .timestamp(Instant.now().toEpochMilli()) - .ommersHash(Hash.EMPTY_LIST_HASH) - .stateRoot(Hash.EMPTY_TRIE_HASH) - .transactionsRoot(Hash.EMPTY) - .receiptsRoot(Hash.EMPTY) - .logsBloom(LogsBloomFilter.empty()) - .gasUsed(0) - .extraData(Bytes.EMPTY) - .mixHash(Hash.EMPTY) - .nonce(0) - .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) - .buildBlockHeader(); - int remainingIters = this.repeat; final ProtocolSpec protocolSpec = component.getProtocolSpec().apply(BlockHeaderBuilder.createDefault().buildBlockHeader()); @@ -360,15 +348,19 @@ public void run() { .sender(sender) .build(); - final long intrinsicGasCost = - protocolSpec - .getGasCalculator() - .transactionIntrinsicGasCost(tx.getPayload(), tx.isContractCreation()); - final long accessListCost = - tx.getAccessList() - .map(list -> protocolSpec.getGasCalculator().accessListGasCost(list)) - .orElse(0L); - long txGas = gas - intrinsicGasCost - accessListCost; + long txGas = gas; + if (chargeIntrinsicGas) { + final long intrinsicGasCost = + protocolSpec + .getGasCalculator() + .transactionIntrinsicGasCost(tx.getPayload(), tx.isContractCreation()); + txGas -= intrinsicGasCost; + final long accessListCost = + tx.getAccessList() + .map(list -> protocolSpec.getGasCalculator().accessListGasCost(list)) + .orElse(0L); + txGas -= accessListCost; + } final EVM evm = protocolSpec.getEvm(); if (codeBytes.isEmpty()) { @@ -395,6 +387,33 @@ public void run() { var contractAccount = updater.getOrCreate(contract); contractAccount.setCode(codeBytes); + final Set
addressList = new BytesTrieSet<>(Address.SIZE); + addressList.add(sender); + addressList.add(contract); + if (EvmSpecVersion.SHANGHAI.compareTo(evm.getEvmVersion()) <= 0) { + addressList.add(coinbase); + } + final BlockHeader blockHeader = + BlockHeaderBuilder.create() + .parentHash(Hash.EMPTY) + .coinbase(coinbase) + .difficulty(Difficulty.ONE) + .number(1) + .gasLimit(5000) + .timestamp(Instant.now().toEpochMilli()) + .ommersHash(Hash.EMPTY_LIST_HASH) + .stateRoot(Hash.EMPTY_TRIE_HASH) + .transactionsRoot(Hash.EMPTY) + .receiptsRoot(Hash.EMPTY) + .logsBloom(LogsBloomFilter.empty()) + .gasUsed(0) + .extraData(Bytes.EMPTY) + .mixHash(Hash.EMPTY) + .nonce(0) + .blockHeaderFunctions(new MainnetBlockHeaderFunctions()) + .baseFee(component.getBlockchain().getChainHeadHeader().getBaseFee().orElse(null)) + .buildBlockHeader(); + MessageFrame initialMessageFrame = MessageFrame.builder() .type(MessageFrame.Type.MESSAGE_CALL) @@ -414,10 +433,7 @@ public void run() { .completer(c -> {}) .miningBeneficiary(blockHeader.getCoinbase()) .blockHashLookup(new CachingBlockHashLookup(blockHeader, component.getBlockchain())) - .accessListWarmAddresses( - EvmSpecVersion.SHANGHAI.compareTo(evm.getEvmVersion()) <= 0 - ? Set.of(coinbase) - : Set.of()) + .accessListWarmAddresses(addressList) .build(); Deque messageFrameStack = initialMessageFrame.getMessageFrameStack(); diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags-disabled.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags-disabled.json index e4b8bc37ac5..adaa08952fd 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags-disabled.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags-disabled.json @@ -84,7 +84,7 @@ {"pc":8,"op":96,"gas":"0x9ffffadec","gasCost":"0x3","memSize":0,"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":10,"op":115,"gas":"0x9ffffade9","gasCost":"0x3","memSize":0,"depth":1,"refund":0,"opName":"PUSH20"}, {"pc":31,"op":100,"gas":"0x9ffffade6","gasCost":"0x3","memSize":0,"depth":1,"refund":0,"opName":"PUSH5"}, - {"pc":37,"op":241,"gas":"0x9ffffade3","gasCost":"0xa28","memSize":0,"depth":1,"refund":0,"opName":"CALL"}, + {"pc":37,"op":241,"gas":"0x9ffffade3","gasCost":"0x900000a28","memSize":0,"depth":1,"refund":0,"opName":"CALL"}, {"pc":0,"op":125,"gas":"0x900000000","gasCost":"0x3","memSize":0,"depth":2,"refund":0,"opName":"PUSH30"}, {"pc":31,"op":96,"gas":"0x8fffffffd","gasCost":"0x3","memSize":0,"depth":2,"refund":0,"opName":"PUSH1"}, {"pc":33,"op":82,"gas":"0x8fffffffa","gasCost":"0x6","memSize":0,"depth":2,"refund":0,"opName":"MSTORE"}, diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags.json index 7ab16b709c7..315b85b3a9d 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/all-trace-flags.json @@ -84,7 +84,7 @@ {"pc":8,"op":96,"gas":"0x9ffffadec","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":10,"op":115,"gas":"0x9ffffade9","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH20"}, {"pc":31,"op":100,"gas":"0x9ffffade6","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xaabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6"],"depth":1,"refund":0,"opName":"PUSH5"}, - {"pc":37,"op":241,"gas":"0x9ffffade3","gasCost":"0xa28","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xaabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6","0x900000000"],"depth":1,"refund":0,"opName":"CALL"}, + {"pc":37,"op":241,"gas":"0x9ffffade3","gasCost":"0x900000a28","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xaabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6","0x900000000"],"depth":1,"refund":0,"opName":"CALL"}, {"pc":0,"op":125,"gas":"0x900000000","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH30"}, {"pc":31,"op":96,"gas":"0x8fffffffd","gasCost":"0x3","memSize":0,"stack":["0x111122223333444455556666777788889999aaaabbbbccccddddeeeeffff"],"depth":2,"refund":0,"opName":"PUSH1"}, {"pc":33,"op":82,"gas":"0x8fffffffa","gasCost":"0x6","memSize":0,"stack":["0x111122223333444455556666777788889999aaaabbbbccccddddeeeeffff","0x0"],"depth":2,"refund":0,"opName":"MSTORE"}, diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/no-memory.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/no-memory.json index 14a995d26c2..f735eb23d17 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/no-memory.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/state-test/no-memory.json @@ -82,7 +82,7 @@ {"pc":8,"op":96,"gas":"0x9ffffadec","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}, {"pc":10,"op":115,"gas":"0x9ffffade9","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0"],"depth":1,"refund":0,"opName":"PUSH20"}, {"pc":31,"op":100,"gas":"0x9ffffade6","gasCost":"0x3","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xaabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6"],"depth":1,"refund":0,"opName":"PUSH5"}, - {"pc":37,"op":241,"gas":"0x9ffffade3","gasCost":"0xa28","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xaabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6","0x900000000"],"depth":1,"refund":0,"opName":"CALL"}, + {"pc":37,"op":241,"gas":"0x9ffffade3","gasCost":"0x900000a28","memSize":0,"stack":["0x0","0x0","0x0","0x0","0x0","0xaabbccdd5c57f15886f9b263e2f6d2d6c7b5ec6","0x900000000"],"depth":1,"refund":0,"opName":"CALL"}, {"pc":0,"op":125,"gas":"0x900000000","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH30"}, {"pc":31,"op":96,"gas":"0x8fffffffd","gasCost":"0x3","memSize":0,"stack":["0x111122223333444455556666777788889999aaaabbbbccccddddeeeeffff"],"depth":2,"refund":0,"opName":"PUSH1"}, {"pc":33,"op":82,"gas":"0x8fffffffa","gasCost":"0x6","memSize":0,"stack":["0x111122223333444455556666777788889999aaaabbbbccccddddeeeeffff","0x0"],"depth":2,"refund":0,"opName":"MSTORE"}, diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json index fec350ff333..7ffca7e466a 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/badcode.json @@ -7,8 +7,8 @@ ], "stdin": "", "stdout": [ - {"pc":0,"op":96,"gas":"0x2540b91f8","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, - {"pc":2,"op":239,"gas":"0x2540b91f5","gasCost":"0x0","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"}, - {"gasUser":"0x2540b91f8","gasTotal":"0x2540b91f8","output":"0x"} + {"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":239,"gas":"0x2540be3fd","gasCost":"0x0","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"INVALID","error":"Bad instruction"}, + {"gasUser":"0x2540be400","gasTotal":"0x2540be400","output":"0x"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json new file mode 100644 index 00000000000..6ea64e18cf6 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/charge-intrinsic.json @@ -0,0 +1,75 @@ +{ + "cli": [ + "--notime", + "--json", + "--code", + "60408053604060405560406000604060006000305af16040f3", + "--receiver", + "0xc0de", + "--contract", + "0xc0de", + "--gas", + "46180", + "--input", + "0xbadbadc0de", + "--intrinsic-gas" + ], + "stdin": "", + "stdout": [ + {"pc":0,"op":96,"gas":"0x620c","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0x6209","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0x6206","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0x61fa","gasCost":"0x3","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0x61f7","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0x61f4","gasCost":"0x5654","memSize":96,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"SSTORE"}, + {"pc":9,"op":96,"gas":"0xba0","gasCost":"0x3","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":11,"op":96,"gas":"0xb9d","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":13,"op":96,"gas":"0xb9a","gasCost":"0x3","memSize":96,"stack":["0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":15,"op":96,"gas":"0xb97","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":17,"op":96,"gas":"0xb94","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":19,"op":48,"gas":"0xb91","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0"],"depth":1,"refund":0,"opName":"ADDRESS"}, + {"pc":20,"op":90,"gas":"0xb8f","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de"],"depth":1,"refund":0,"opName":"GAS"}, + {"pc":21,"op":241,"gas":"0xb8d","gasCost":"0xb61","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de","0xb8d"],"depth":1,"refund":0,"opName":"CALL"}, + {"pc":0,"op":96,"gas":"0xafd","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0xafa","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":2,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0xaf7","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":2,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0xaeb","gasCost":"0x3","memSize":96,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0xae8","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0xae5","gasCost":"0x64","memSize":96,"stack":["0x40","0x40"],"depth":2,"refund":0,"opName":"SSTORE"}, + {"pc":9,"op":96,"gas":"0xa81","gasCost":"0x3","memSize":96,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":11,"op":96,"gas":"0xa7e","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":13,"op":96,"gas":"0xa7b","gasCost":"0x3","memSize":96,"stack":["0x40","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":15,"op":96,"gas":"0xa78","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":17,"op":96,"gas":"0xa75","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":19,"op":48,"gas":"0xa72","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0"],"depth":2,"refund":0,"opName":"ADDRESS"}, + {"pc":20,"op":90,"gas":"0xa70","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de"],"depth":2,"refund":0,"opName":"GAS"}, + {"pc":21,"op":241,"gas":"0xa6e","gasCost":"0xa46","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de","0xa6e"],"depth":2,"refund":0,"opName":"CALL"}, + {"pc":0,"op":96,"gas":"0x9e2","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0x9df","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":3,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0x9dc","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":3,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0x9d0","gasCost":"0x3","memSize":96,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0x9cd","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0x9ca","gasCost":"0x64","memSize":96,"stack":["0x40","0x40"],"depth":3,"refund":0,"opName":"SSTORE"}, + {"pc":9,"op":96,"gas":"0x966","gasCost":"0x3","memSize":96,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":11,"op":96,"gas":"0x963","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":13,"op":96,"gas":"0x960","gasCost":"0x3","memSize":96,"stack":["0x40","0x0"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":15,"op":96,"gas":"0x95d","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":17,"op":96,"gas":"0x95a","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":19,"op":48,"gas":"0x957","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0"],"depth":3,"refund":0,"opName":"ADDRESS"}, + {"pc":20,"op":90,"gas":"0x955","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de"],"depth":3,"refund":0,"opName":"GAS"}, + {"pc":21,"op":241,"gas":"0x953","gasCost":"0x930","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de","0x953"],"depth":3,"refund":0,"opName":"CALL"}, + {"pc":0,"op":96,"gas":"0x8cc","gasCost":"0x3","memSize":0,"stack":[],"depth":4,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0x8c9","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":4,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0x8c6","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":4,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0x8ba","gasCost":"0x3","memSize":96,"stack":[],"depth":4,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0x8b7","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":4,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0x8b4","gasCost":"0x8fc","memSize":96,"stack":["0x40","0x40"],"depth":4,"refund":0,"opName":"SSTORE","error":"Out of gas"}, + {"pc":22,"op":96,"gas":"0x23","gasCost":"0x3","memSize":96,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":24,"op":243,"gas":"0x20","gasCost":"0x0","memSize":96,"stack":["0x0","0x40"],"depth":3,"refund":0,"opName":"RETURN"}, + {"pc":22,"op":96,"gas":"0x48","gasCost":"0x3","memSize":96,"stack":["0x1"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":24,"op":243,"gas":"0x45","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":2,"refund":0,"opName":"RETURN"}, + {"pc":22,"op":96,"gas":"0x71","gasCost":"0x3","memSize":96,"stack":["0x1"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":24,"op":243,"gas":"0x6e","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":1,"refund":0,"opName":"RETURN"}, + {"gasUser":"0x619e","gasTotal":"0x619e","output":"0x40"} + ] +} \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json index 406c2684e26..f23565c64be 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-cold.json @@ -11,47 +11,9 @@ ], "stdin": "", "stdout": [ - { - "pc": 0, - "op": 65, - "gas": "0x2540b91f8", - "gasCost": "0x2", - "memSize": 0, - "stack": [], - "depth": 1, - "refund": 0, - "opName": "COINBASE" - }, - { - "pc": 1, - "op": 49, - "gas": "0x2540b91f6", - "gasCost": "0xa28", - "memSize": 0, - "stack": [ - "0x4444588443c3a91288c5002483449aba1054192b" - ], - "depth": 1, - "refund": 0, - "opName": "BALANCE" - }, - { - "pc": 2, - "op": 255, - "gas": "0x2540b87ce", - "gasCost": "0x1388", - "memSize": 0, - "stack": [ - "0x0" - ], - "depth": 1, - "refund": 0, - "opName": "SELFDESTRUCT" - }, - { - "gasUser": "0x1db2", - "gasTotal": "0x1db2", - "output": "0x" - } + {"pc":0,"op":65,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"COINBASE"}, + {"pc":1,"op":49,"gas":"0x2540be3fe","gasCost":"0xa28","memSize":0,"stack":["0x4444588443c3a91288c5002483449aba1054192b"],"depth":1,"refund":0,"opName":"BALANCE"}, + {"pc":2,"op":255,"gas":"0x2540bd9d6","gasCost":"0x1388","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SELFDESTRUCT"}, + {"gasUser":"0x1db2","gasTotal":"0x1db2","output":"0x"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json index 9140a0268c8..79ca8e5bf35 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/coinbase-warm.json @@ -11,47 +11,9 @@ ], "stdin": "", "stdout": [ - { - "pc": 0, - "op": 65, - "gas": "0x2540b91f8", - "gasCost": "0x2", - "memSize": 0, - "stack": [], - "depth": 1, - "refund": 0, - "opName": "COINBASE" - }, - { - "pc": 1, - "op": 49, - "gas": "0x2540b91f6", - "gasCost": "0x64", - "memSize": 0, - "stack": [ - "0x4444588443c3a91288c5002483449aba1054192b" - ], - "depth": 1, - "refund": 0, - "opName": "BALANCE" - }, - { - "pc": 2, - "op": 255, - "gas": "0x2540b9192", - "gasCost": "0x1388", - "memSize": 0, - "stack": [ - "0x0" - ], - "depth": 1, - "refund": 0, - "opName": "SELFDESTRUCT" - }, - { - "gasUser": "0x13ee", - "gasTotal": "0x13ee", - "output": "0x" - } + {"pc":0,"op":65,"gas":"0x2540be400","gasCost":"0x2","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"COINBASE"}, + {"pc":1,"op":49,"gas":"0x2540be3fe","gasCost":"0x64","memSize":0,"stack":["0x4444588443c3a91288c5002483449aba1054192b"],"depth":1,"refund":0,"opName":"BALANCE"}, + {"pc":2,"op":255,"gas":"0x2540be39a","gasCost":"0x1388","memSize":0,"stack":["0x0"],"depth":1,"refund":0,"opName":"SELFDESTRUCT"}, + {"gasUser":"0x13ee","gasTotal":"0x13ee","output":"0x"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json index c919d748ddc..875ceb81b12 100644 --- a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/revert.json @@ -7,12 +7,12 @@ ], "stdin": "", "stdout": [ - {"pc":0,"op":99,"gas":"0x2540b91f8","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH4"}, - {"pc":5,"op":96,"gas":"0x2540b91f5","gasCost":"0x3","memSize":0,"stack":["0x4e6f7065"],"depth":1,"refund":0,"opName":"PUSH1"}, - {"pc":7,"op":82,"gas":"0x2540b91f2","gasCost":"0x6","memSize":0,"stack":["0x4e6f7065","0x0"],"depth":1,"refund":0,"opName":"MSTORE"}, - {"pc":8,"op":96,"gas":"0x2540b91ec","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, - {"pc":10,"op":96,"gas":"0x2540b91e9","gasCost":"0x3","memSize":32,"stack":["0x4"],"depth":1,"refund":0,"opName":"PUSH1"}, - {"pc":12,"op":253,"gas":"0x2540b91e6","gasCost":"0x0","memSize":32,"stack":["0x4","0x1c"],"depth":1,"refund":0,"opName":"REVERT","error":"Nope"}, + {"pc":0,"op":99,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH4"}, + {"pc":5,"op":96,"gas":"0x2540be3fd","gasCost":"0x3","memSize":0,"stack":["0x4e6f7065"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":7,"op":82,"gas":"0x2540be3fa","gasCost":"0x6","memSize":0,"stack":["0x4e6f7065","0x0"],"depth":1,"refund":0,"opName":"MSTORE"}, + {"pc":8,"op":96,"gas":"0x2540be3f4","gasCost":"0x3","memSize":32,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":10,"op":96,"gas":"0x2540be3f1","gasCost":"0x3","memSize":32,"stack":["0x4"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":12,"op":253,"gas":"0x2540be3ee","gasCost":"0x0","memSize":32,"stack":["0x4","0x1c"],"depth":1,"refund":0,"opName":"REVERT","error":"Nope"}, {"gasUser":"0x12","gasTotal":"0x12","output":"0x4e6f7065"} ] } \ No newline at end of file diff --git a/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json new file mode 100644 index 00000000000..8a7a5500580 --- /dev/null +++ b/ethereum/evmtool/src/test/resources/org/hyperledger/besu/evmtool/trace/warm-contract.json @@ -0,0 +1,72 @@ +{ + "cli": [ + "--notime", + "--json", + "--code", + "60408053604060405560406000604060006000305af16040f3", + "--receiver", + "0xc0de", + "--contract", + "0xc0de", + "--gas", + "25100" + ], + "stdin": "", + "stdout": [ + {"pc":0,"op":96,"gas":"0x620c","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0x6209","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0x6206","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0x61fa","gasCost":"0x3","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0x61f7","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0x61f4","gasCost":"0x5654","memSize":96,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"SSTORE"}, + {"pc":9,"op":96,"gas":"0xba0","gasCost":"0x3","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":11,"op":96,"gas":"0xb9d","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":13,"op":96,"gas":"0xb9a","gasCost":"0x3","memSize":96,"stack":["0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":15,"op":96,"gas":"0xb97","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":17,"op":96,"gas":"0xb94","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":19,"op":48,"gas":"0xb91","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0"],"depth":1,"refund":0,"opName":"ADDRESS"}, + {"pc":20,"op":90,"gas":"0xb8f","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de"],"depth":1,"refund":0,"opName":"GAS"}, + {"pc":21,"op":241,"gas":"0xb8d","gasCost":"0xb61","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de","0xb8d"],"depth":1,"refund":0,"opName":"CALL"}, + {"pc":0,"op":96,"gas":"0xafd","gasCost":"0x3","memSize":0,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0xafa","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":2,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0xaf7","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":2,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0xaeb","gasCost":"0x3","memSize":96,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0xae8","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0xae5","gasCost":"0x64","memSize":96,"stack":["0x40","0x40"],"depth":2,"refund":0,"opName":"SSTORE"}, + {"pc":9,"op":96,"gas":"0xa81","gasCost":"0x3","memSize":96,"stack":[],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":11,"op":96,"gas":"0xa7e","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":13,"op":96,"gas":"0xa7b","gasCost":"0x3","memSize":96,"stack":["0x40","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":15,"op":96,"gas":"0xa78","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":17,"op":96,"gas":"0xa75","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":19,"op":48,"gas":"0xa72","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0"],"depth":2,"refund":0,"opName":"ADDRESS"}, + {"pc":20,"op":90,"gas":"0xa70","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de"],"depth":2,"refund":0,"opName":"GAS"}, + {"pc":21,"op":241,"gas":"0xa6e","gasCost":"0xa46","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de","0xa6e"],"depth":2,"refund":0,"opName":"CALL"}, + {"pc":0,"op":96,"gas":"0x9e2","gasCost":"0x3","memSize":0,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0x9df","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":3,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0x9dc","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":3,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0x9d0","gasCost":"0x3","memSize":96,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0x9cd","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0x9ca","gasCost":"0x64","memSize":96,"stack":["0x40","0x40"],"depth":3,"refund":0,"opName":"SSTORE"}, + {"pc":9,"op":96,"gas":"0x966","gasCost":"0x3","memSize":96,"stack":[],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":11,"op":96,"gas":"0x963","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":13,"op":96,"gas":"0x960","gasCost":"0x3","memSize":96,"stack":["0x40","0x0"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":15,"op":96,"gas":"0x95d","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":17,"op":96,"gas":"0x95a","gasCost":"0x3","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":19,"op":48,"gas":"0x957","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0"],"depth":3,"refund":0,"opName":"ADDRESS"}, + {"pc":20,"op":90,"gas":"0x955","gasCost":"0x2","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de"],"depth":3,"refund":0,"opName":"GAS"}, + {"pc":21,"op":241,"gas":"0x953","gasCost":"0x930","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x0","0xc0de","0x953"],"depth":3,"refund":0,"opName":"CALL"}, + {"pc":0,"op":96,"gas":"0x8cc","gasCost":"0x3","memSize":0,"stack":[],"depth":4,"refund":0,"opName":"PUSH1"}, + {"pc":2,"op":128,"gas":"0x8c9","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":4,"refund":0,"opName":"DUP1"}, + {"pc":3,"op":83,"gas":"0x8c6","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":4,"refund":0,"opName":"MSTORE8"}, + {"pc":4,"op":96,"gas":"0x8ba","gasCost":"0x3","memSize":96,"stack":[],"depth":4,"refund":0,"opName":"PUSH1"}, + {"pc":6,"op":96,"gas":"0x8b7","gasCost":"0x3","memSize":96,"stack":["0x40"],"depth":4,"refund":0,"opName":"PUSH1"}, + {"pc":8,"op":85,"gas":"0x8b4","gasCost":"0x8fc","memSize":96,"stack":["0x40","0x40"],"depth":4,"refund":0,"opName":"SSTORE","error":"Out of gas"}, + {"pc":22,"op":96,"gas":"0x23","gasCost":"0x3","memSize":96,"stack":["0x0"],"depth":3,"refund":0,"opName":"PUSH1"}, + {"pc":24,"op":243,"gas":"0x20","gasCost":"0x0","memSize":96,"stack":["0x0","0x40"],"depth":3,"refund":0,"opName":"RETURN"}, + {"pc":22,"op":96,"gas":"0x48","gasCost":"0x3","memSize":96,"stack":["0x1"],"depth":2,"refund":0,"opName":"PUSH1"}, + {"pc":24,"op":243,"gas":"0x45","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":2,"refund":0,"opName":"RETURN"}, + {"pc":22,"op":96,"gas":"0x71","gasCost":"0x3","memSize":96,"stack":["0x1"],"depth":1,"refund":0,"opName":"PUSH1"}, + {"pc":24,"op":243,"gas":"0x6e","gasCost":"0x0","memSize":96,"stack":["0x1","0x40"],"depth":1,"refund":0,"opName":"RETURN"}, + {"gasUser":"0x619e","gasTotal":"0x619e","output":"0x40"} + ] +} \ No newline at end of file diff --git a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java index 64cb42757ea..e1e399375b7 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/operation/AbstractCallOperation.java @@ -146,7 +146,7 @@ protected long gas(final MessageFrame frame) { * @param frame The current message frame * @return the gas available to execute the child message call */ - protected abstract long gasAvailableForChildCall(MessageFrame frame); + public abstract long gasAvailableForChildCall(MessageFrame frame); /** * Returns whether the child message call should be static. diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java index 04254a718a1..b20004ce89a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java @@ -20,6 +20,7 @@ import org.hyperledger.besu.evm.frame.ExceptionalHaltReason; import org.hyperledger.besu.evm.frame.MessageFrame; +import org.hyperledger.besu.evm.operation.AbstractCallOperation; import org.hyperledger.besu.evm.operation.Operation; import java.io.PrintStream; @@ -174,6 +175,10 @@ public void tracePostExecution( } final int opcode = currentOp.getOpcode(); final Bytes returnData = messageFrame.getReturnData(); + long thisGasCost = executeResult.getGasCost(); + if (currentOp instanceof AbstractCallOperation) { + thisGasCost += messageFrame.getMessageFrameStack().getFirst().getRemainingGas(); + } final StringBuilder sb = new StringBuilder(1024); sb.append("{"); @@ -183,7 +188,7 @@ public void tracePostExecution( } sb.append("\"op\":").append(opcode).append(","); sb.append("\"gas\":\"").append(gas).append("\","); - sb.append("\"gasCost\":\"").append(shortNumber(executeResult.getGasCost())).append("\","); + sb.append("\"gasCost\":\"").append(shortNumber(thisGasCost)).append("\","); if (memory != null) { sb.append("\"memory\":\"").append(memory.toHexString()).append("\","); } diff --git a/evm/src/test/java/org/hyperledger/besu/evm/StandardJsonTracerTest.java b/evm/src/test/java/org/hyperledger/besu/evm/StandardJsonTracerTest.java index 95772986814..70043e22a4d 100644 --- a/evm/src/test/java/org/hyperledger/besu/evm/StandardJsonTracerTest.java +++ b/evm/src/test/java/org/hyperledger/besu/evm/StandardJsonTracerTest.java @@ -49,12 +49,10 @@ void eip3155ModifiedTestCase() { // returnStack was a valid field. It no longer appears in any traces. // (b) the summary line is omitted // (c) pc:3 is in error, the size of the memory before the first MSTORE8 is zero. - // (d) we don't report call requested gas in CALL series operations as a gas cost, just the EVM - // consumed gas - // (e) if memory is zero length, it is not included even if `showMemory` is true - // (f) if return data is zero length or null, it is not included even if `showReturnData` is + // (d) if memory is zero length, it is not included even if `showMemory` is true + // (e) if return data is zero length or null, it is not included even if `showReturnData` is // true - // (g) if error is zero length or null it is not included. + // (f) if error is zero length or null it is not included. assertThat(baos) .hasToString( """ @@ -70,7 +68,7 @@ void eip3155ModifiedTestCase() { {"pc":15,"op":96,"gas":"0x2540b95bf","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40"],"depth":1,"refund":0,"opName":"PUSH1"} {"pc":17,"op":96,"gas":"0x2540b95bc","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"} {"pc":19,"op":90,"gas":"0x2540b95b9","gasCost":"0x2","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2"],"depth":1,"refund":0,"opName":"GAS"} - {"pc":20,"op":250,"gas":"0x2540b95b7","gasCost":"0x2bc","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2","0x2540b95b7"],"depth":1,"refund":0,"opName":"STATICCALL"} + {"pc":20,"op":250,"gas":"0x2540b95b7","gasCost":"0x24abb676c","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0","0x40","0x0","0x2","0x2540b95b7"],"depth":1,"refund":0,"opName":"STATICCALL"} {"pc":21,"op":96,"gas":"0x2540b92a7","gasCost":"0x3","memory":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x1"],"returnData":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","depth":1,"refund":0,"opName":"PUSH1"} {"pc":23,"op":243,"gas":"0x2540b92a4","gasCost":"0x0","memory":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x1","0x40"],"returnData":"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b","depth":1,"refund":0,"opName":"RETURN"} """); @@ -104,7 +102,7 @@ void updatedStorageTestCase() { {"pc":15,"op":96,"gas":"0x2540b95bf","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1","storage":{"0x40":"0x40"}} {"pc":17,"op":96,"gas":"0x2540b95bc","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1","storage":{"0x40":"0x40"}} {"pc":19,"op":90,"gas":"0x2540b95b9","gasCost":"0x2","memSize":96,"depth":1,"refund":0,"opName":"GAS","storage":{"0x40":"0x40"}} - {"pc":20,"op":250,"gas":"0x2540b95b7","gasCost":"0x2bc","memSize":96,"depth":1,"refund":0,"opName":"STATICCALL","storage":{"0x40":"0x40"}} + {"pc":20,"op":250,"gas":"0x2540b95b7","gasCost":"0x24abb676c","memSize":96,"depth":1,"refund":0,"opName":"STATICCALL","storage":{"0x40":"0x40"}} {"pc":21,"op":96,"gas":"0x2540b92a7","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1","storage":{"0x40":"0x40"}} {"pc":23,"op":243,"gas":"0x2540b92a4","gasCost":"0x0","memSize":96,"depth":1,"refund":0,"opName":"RETURN","storage":{"0x40":"0x40"}} """);