Trace API fixes (#377)

- Correct Reporting of reverts in nested call
- correct reporting and handling of value transfer in nested calls
- correct handling of precompiles via DELEGATECALL & CALLCODE
- Addition of precompiled contract gas costs
- Re-work handling of storage writes
- Initial handling of gas refunds
- fix bug in DELEGATECALL tests, we don't need gas in the stack
  * this has a cascading effect on balances in diff tests
- rework depth detection in flat trace
- two new tests blocks

Signed-off-by: Danno Ferrin <danno.ferrin@gmail.com>
pull/396/head
Danno Ferrin 5 years ago committed by GitHub
parent 9b35c3b658
commit 358ab092b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTrace.java
  2. 24
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java
  3. 15
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/vm/VmOperation.java
  4. 158
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/vm/VmTraceGenerator.java
  5. 6
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHashTest.java
  6. 6
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumberTest.java
  7. 6
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockTest.java
  8. 11
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransactionTest.java
  9. 76
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data/blocks.json
  10. 4
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/chain-data/genesis.json
  11. 24
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x10.json
  12. 8
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x11.json
  13. 16
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x12.json
  14. 24
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x13.json
  15. 16
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x14.json
  16. 1870
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x15.json
  17. 1818
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0x16.json
  18. 92
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0xB.json
  19. 8
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0xC.json
  20. 8
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0xD.json
  21. 24
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0xE.json
  22. 16
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/all/trace_replayBlockTransactions_all_0xF.json
  23. 12
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/flat/trace_replayBlockTransactions_traceOnly_0xB.json
  24. 6
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/statediff/trace_replayBlockTransactions_diffOnly_0xB.json
  25. 8
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/statediff/trace_replayBlockTransactions_diffOnly_0xC.json
  26. 8
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/statediff/trace_replayBlockTransactions_diffOnly_0xD.json
  27. 24
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/statediff/trace_replayBlockTransactions_diffOnly_0xE.json
  28. 78
      ethereum/api/src/test/resources/org/hyperledger/besu/ethereum/api/jsonrpc/trace/specs/vm-trace/trace_replayBlockTransactions_0xB.json
  29. 65
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/debug/TraceFrame.java
  30. 6
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/AbstractMessageProcessor.java
  31. 3
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetContractCreationProcessor.java
  32. 11
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/mainnet/MainnetMessageCallProcessor.java
  33. 19
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java
  34. 19
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/MessageFrame.java
  35. 5
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/OperationTracer.java
  36. 1
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/operations/SStoreOperation.java

@ -41,6 +41,10 @@ public class TransactionTrace {
return transaction.getGasLimit() - result.getGasRemaining();
}
public long getGasLimit() {
return transaction.getGasLimit();
}
public Result getResult() {
return result;
}

@ -18,6 +18,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionT
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.Quantity;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.Trace;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.TracingUtils;
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.flat.FlatTrace.Context;
import org.hyperledger.besu.ethereum.core.Address;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Transaction;
@ -100,7 +101,9 @@ public class FlatTraceGenerator {
int traceFrameIndex = 0;
final List<TraceFrame> traceFrames = transactionTrace.getTraceFrames();
for (final TraceFrame traceFrame : traceFrames) {
cumulativeGasCost += traceFrame.getGasCost().orElse(Gas.ZERO).toLong();
cumulativeGasCost +=
traceFrame.getGasCost().orElse(Gas.ZERO).toLong()
+ traceFrame.getPrecompiledGasCost().orElse(Gas.ZERO).toLong();
final String opcodeString = traceFrame.getOpcode();
if ("CALL".equals(opcodeString)
|| "CALLCODE".equals(opcodeString)
@ -129,7 +132,6 @@ public class FlatTraceGenerator {
} else if ("CREATE".equals(opcodeString) || "CREATE2".equals(opcodeString)) {
currentContext =
handleCreateOperation(
transactionTrace,
smartContractAddress,
flatTraces,
tracesContexts,
@ -137,7 +139,7 @@ public class FlatTraceGenerator {
traceFrameIndex,
traceFrames);
} else if ("REVERT".equals(opcodeString)) {
currentContext.getBuilder().error(Optional.of("Reverted"));
currentContext = handleRevert(tracesContexts, currentContext);
} else if (!traceFrame.getExceptionalHaltReasons().isEmpty()) {
currentContext
.getBuilder()
@ -148,6 +150,7 @@ public class FlatTraceGenerator {
}
traceFrameIndex++;
}
return flatTraces.stream().map(FlatTrace.Builder::build);
}
@ -207,6 +210,7 @@ public class FlatTraceGenerator {
final FlatTrace.Builder traceFrameBuilder = currentContext.getBuilder();
final Result.Builder resultBuilder = traceFrameBuilder.getResultBuilder();
final Action.Builder actionBuilder = traceFrameBuilder.getActionBuilder();
actionBuilder.value(Quantity.create(traceFrame.getValue()));
final Bytes outputData = traceFrame.getOutputData();
if (resultBuilder.getCode() == null) {
resultBuilder.output(outputData.toHexString());
@ -267,7 +271,6 @@ public class FlatTraceGenerator {
}
private static FlatTrace.Context handleCreateOperation(
final TransactionTrace transactionTrace,
final Optional<String> smartContractAddress,
final List<FlatTrace.Builder> flatTraces,
final Deque<FlatTrace.Context> tracesContexts,
@ -287,7 +290,7 @@ public class FlatTraceGenerator {
Action.builder()
.from(smartContractAddress.orElse(callingAddress))
.gas(nextTraceFrame.getGasRemaining().toHexString())
.value(Quantity.create(transactionTrace.getTransaction().getValue()));
.value(Quantity.create(nextTraceFrame.getValue()));
final FlatTrace.Context currentContext =
new FlatTrace.Context(subTraceBuilder.actionBuilder(subTraceActionBuilder));
@ -298,6 +301,17 @@ public class FlatTraceGenerator {
return currentContext;
}
private static Context handleRevert(
final Deque<Context> tracesContexts, final FlatTrace.Context currentContext) {
currentContext.getBuilder().error(Optional.of("Reverted"));
tracesContexts.removeLast();
final FlatTrace.Context nextContext = tracesContexts.peekLast();
if (nextContext != null) {
nextContext.getBuilder().incSubTraces();
}
return nextContext;
}
private static String calculateCallingAddress(final FlatTrace.Context lastContext) {
if (lastContext.getBuilder().getActionBuilder().getCallType() == null) {
return ZERO_ADDRESS_STRING;

@ -14,14 +14,18 @@
*/
package org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.tracing.vm;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
import java.util.Objects;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
@JsonPropertyOrder({"cost", "ex", "pc", "sub"})
@JsonPropertyOrder({"cost", "operation", "ex", "pc", "sub"})
public class VmOperation {
private long cost;
private String operation;
// Information concerning the execution of the operation.
private VmOperationExecutionReport vmOperationExecutionReport;
private long pc;
@ -62,6 +66,15 @@ public class VmOperation {
this.sub = sub;
}
@JsonInclude(NON_NULL)
public String getOperation() {
return operation;
}
public void setOperation(final String operation) {
this.operation = operation;
}
@Override
public int hashCode() {
return Objects.hash(cost, vmOperationExecutionReport, pc, sub);

@ -24,14 +24,10 @@ import org.hyperledger.besu.ethereum.vm.ExceptionalHaltReason;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import com.google.common.collect.MapDifference;
import com.google.common.collect.Maps;
import org.apache.tuweni.bytes.Bytes;
import org.apache.tuweni.units.bigints.UInt256;
@ -44,6 +40,7 @@ public class VmTraceGenerator {
private final TransactionTrace transactionTrace;
private final VmTrace rootVmTrace = new VmTrace();
private final Deque<VmTrace> parentTraces = new ArrayDeque<>();
int lastDepth = 0;
public VmTraceGenerator(final TransactionTrace transactionTrace) {
this.transactionTrace = transactionTrace;
@ -82,18 +79,18 @@ public class VmTraceGenerator {
* @param frame the current trace frame
*/
private void addFrame(final TraceFrame frame) {
if (mustIgnore(frame)) {
return;
handleDepthDecreased(frame);
if (!mustIgnore(frame)) {
initStep(frame);
final VmOperation op = buildVmOperation();
final VmOperationExecutionReport report = generateExecutionReport();
generateTracingMemory(report);
generateTracingPush(report);
generateTracingStorage(report);
handleDepthIncreased(op, report);
completeStep(op, report);
lastDepth = frame.getDepth();
}
initStep(frame);
final VmOperation op = buildVmOperation();
final VmOperationExecutionReport report = generateExecutionReport();
generateTracingMemory(report);
generateTracingPush(report);
generateTracingStorage(report);
handleDepthIncreased(op, report);
handleDepthDecreased();
completeStep(op, report);
}
private boolean mustIgnore(final TraceFrame frame) {
@ -112,53 +109,60 @@ public class VmTraceGenerator {
private void completeStep(final VmOperation op, final VmOperationExecutionReport report) {
// add the operation representation to the list of traces
op.setVmOperationExecutionReport(report);
currentTrace.add(op);
if (currentTrace != null) {
currentTrace.add(op);
}
currentIndex++;
}
private void handleDepthIncreased(final VmOperation op, final VmOperationExecutionReport report) {
// check if next frame depth has increased i.e the current operation is a call
if (currentTraceFrame.depthHasIncreased()
|| "STATICCALL".equals(currentOperation)
|| "CALL".equals(currentOperation)) {
findLastFrameInCall(currentTraceFrame, currentIndex)
.ifPresent(
lastFrameInCall -> {
report.setUsed(lastFrameInCall.getGasRemaining().toLong());
lastFrameInCall
.getStack()
.filter(stack -> stack.length > 0)
.map(stack -> stack[stack.length - 1])
.map(last -> Quantity.create(UInt256.fromHexString(last.toHexString())))
.ifPresent(report::singlePush);
switch (currentTraceFrame.getOpcode()) {
case "DELEGATECALL":
case "CREATE":
case "CREATE2":
break;
default:
switch (currentOperation) {
case "STATICCALL":
case "DELEGATECALL":
case "CALLCODE":
case "CALL":
case "CREATE":
case "CREATE2":
findLastFrameInCall(currentTraceFrame, currentIndex)
.ifPresent(
lastFrameInCall -> {
report.setUsed(lastFrameInCall.getGasRemaining().toLong());
lastFrameInCall
.getStack()
.filter(stack -> stack.length > 0)
.map(stack -> stack[stack.length - 1])
.map(last -> Quantity.create(UInt256.fromHexString(last.toHexString())))
.ifPresent(report::singlePush);
if (!currentOperation.startsWith("CREATE")) {
lastFrameInCall
.getMaybeUpdatedMemory()
.map(
mem ->
new Mem(mem.getValue().toHexString(), mem.getOffset().intValue()))
.ifPresent(report::setMem);
}
});
if (currentTraceFrame.depthHasIncreased()) {
op.setCost(currentTraceFrame.getGasRemainingPostExecution().toLong() + op.getCost());
final VmTrace newSubTrace = new VmTrace();
parentTraces.addLast(newSubTrace);
op.setSub(newSubTrace);
} else {
op.setSub(new VmTrace());
}
}
});
if (currentTraceFrame.getMaybeCode().map(Code::getSize).orElse(0) > 0) {
op.setCost(currentTraceFrame.getGasRemainingPostExecution().toLong() + op.getCost());
final VmTrace newSubTrace = new VmTrace();
parentTraces.addLast(newSubTrace);
op.setSub(newSubTrace);
} else {
if (currentTraceFrame.getPrecompiledGasCost().isPresent()) {
op.setCost(op.getCost() + currentTraceFrame.getPrecompiledGasCost().get().toLong());
}
op.setSub(new VmTrace());
}
break;
default:
break;
}
}
private void handleDepthDecreased() {
private void handleDepthDecreased(final TraceFrame frame) {
// check if next frame depth has decreased i.e the current operation closes the parent trace
if (currentTraceFrame.depthHasDecreased()) {
if (currentTraceFrame != null && frame.getDepth() < lastDepth) {
currentTrace = parentTraces.removeLast();
}
}
@ -168,6 +172,7 @@ public class VmTraceGenerator {
// set gas cost and program counter
op.setCost(currentTraceFrame.getGasCost().orElse(Gas.ZERO).toLong());
op.setPc(currentTraceFrame.getPc());
// op.setOperation(currentOperation);
return op;
}
@ -220,12 +225,14 @@ public class VmTraceGenerator {
private void generateTracingStorage(final VmOperationExecutionReport report) {
// set storage if updated
updatedStorage(currentTraceFrame.getStoragePreExecution(), currentTraceFrame.getStorage())
.map(
storageEntry ->
new Store(
storageEntry.key.toShortHexString(), storageEntry.value.toShortHexString()))
.ifPresent(report::setStore);
currentTraceFrame
.getMaybeUpdatedStorage()
.ifPresent(
entry ->
report.setStore(
new Store(
entry.getOffset().toShortHexString(),
entry.getValue().toShortHexString())));
}
/**
@ -236,39 +243,12 @@ public class VmTraceGenerator {
private void initStep(final TraceFrame frame) {
this.currentTraceFrame = frame;
this.currentOperation = frame.getOpcode();
currentTrace = parentTraces.getLast();
currentTrace = parentTraces.peekLast();
// set smart contract code
currentTrace.setCode(
currentTraceFrame.getMaybeCode().orElse(new Code()).getBytes().toHexString());
}
/**
* Find updated storage from 2 storage captures.
*
* @param firstCapture The first storage capture.
* @param secondCapture The second storage capture.
* @return an {@link Optional} wrapping the diff.
*/
private Optional<StorageEntry> updatedStorage(
final Optional<Map<UInt256, UInt256>> firstCapture,
final Optional<Map<UInt256, UInt256>> secondCapture) {
final Map<UInt256, UInt256> first = firstCapture.orElse(new HashMap<>());
final Map<UInt256, UInt256> second = secondCapture.orElse(new HashMap<>());
final MapDifference<UInt256, UInt256> diff = Maps.difference(first, second);
final Map<UInt256, MapDifference.ValueDifference<UInt256>> entriesDiffering =
diff.entriesDiffering();
if (entriesDiffering.size() > 0) {
final UInt256 firstDiffKey = entriesDiffering.keySet().iterator().next();
final MapDifference.ValueDifference<UInt256> firstDiff = entriesDiffering.get(firstDiffKey);
return Optional.of(new StorageEntry(firstDiffKey, firstDiff.rightValue()));
if (currentTrace != null && "0x".equals(currentTrace.getCode())) {
currentTrace.setCode(
currentTraceFrame.getMaybeCode().orElse(new Code()).getBytes().toHexString());
}
final Map<UInt256, UInt256> onlyOnRight = diff.entriesOnlyOnRight();
if (onlyOnRight.size() > 0) {
final UInt256 firstOnlyOnRightKey = onlyOnRight.keySet().iterator().next();
return Optional.of(
new StorageEntry(firstOnlyOnRightKey, onlyOnRight.get(firstOnlyOnRightKey)));
}
return Optional.empty();
}
/**
@ -290,14 +270,4 @@ public class VmTraceGenerator {
}
return Optional.empty();
}
static class StorageEntry {
private final UInt256 key;
private final UInt256 value;
StorageEntry(final UInt256 key, final UInt256 value) {
this.key = key;
this.value = value;
}
}
}

@ -28,6 +28,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.processor.TransactionT
import org.hyperledger.besu.ethereum.api.jsonrpc.internal.response.JsonRpcSuccessResponse;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.TransactionProcessor;
import org.hyperledger.besu.ethereum.vm.ExceptionalHaltReason;
@ -66,9 +67,11 @@ public class DebugTraceBlockByHashTest {
"NONE",
Gas.of(45),
Optional.of(Gas.of(56)),
Gas.ZERO,
2,
EnumSet.noneOf(ExceptionalHaltReason.class),
null,
Wei.ZERO,
Bytes.EMPTY,
Bytes.EMPTY,
Optional.empty(),
@ -80,9 +83,8 @@ public class DebugTraceBlockByHashTest {
Optional.empty(),
0,
Optional.empty(),
Optional.empty(),
Optional.empty(),
false,
Optional.empty(),
Optional.empty());
final TransactionProcessor.Result transaction1Result = mock(TransactionProcessor.Result.class);

@ -32,6 +32,7 @@ import org.hyperledger.besu.ethereum.api.jsonrpc.internal.results.DebugTraceTran
import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.TransactionProcessor;
import org.hyperledger.besu.ethereum.vm.ExceptionalHaltReason;
@ -71,9 +72,11 @@ public class DebugTraceBlockByNumberTest {
"NONE",
Gas.of(45),
Optional.of(Gas.of(56)),
Gas.ZERO,
2,
EnumSet.noneOf(ExceptionalHaltReason.class),
null,
Wei.ZERO,
Bytes.EMPTY,
Bytes.EMPTY,
Optional.empty(),
@ -85,9 +88,8 @@ public class DebugTraceBlockByNumberTest {
Optional.empty(),
0,
Optional.empty(),
Optional.empty(),
Optional.empty(),
false,
Optional.empty(),
Optional.empty());
final TransactionProcessor.Result transaction1Result = mock(TransactionProcessor.Result.class);

@ -34,6 +34,7 @@ import org.hyperledger.besu.ethereum.api.query.BlockchainQueries;
import org.hyperledger.besu.ethereum.core.Block;
import org.hyperledger.besu.ethereum.core.BlockDataGenerator;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.MainnetBlockHeaderFunctions;
import org.hyperledger.besu.ethereum.mainnet.TransactionProcessor;
@ -84,9 +85,11 @@ public class DebugTraceBlockTest {
"NONE",
Gas.of(45),
Optional.of(Gas.of(56)),
Gas.ZERO,
2,
EnumSet.noneOf(ExceptionalHaltReason.class),
null,
Wei.ZERO,
Bytes.EMPTY,
Bytes.EMPTY,
Optional.empty(),
@ -98,9 +101,8 @@ public class DebugTraceBlockTest {
Optional.empty(),
0,
Optional.empty(),
Optional.empty(),
Optional.empty(),
false,
Optional.empty(),
Optional.empty());
final TransactionProcessor.Result transaction1Result = mock(TransactionProcessor.Result.class);

@ -33,6 +33,7 @@ import org.hyperledger.besu.ethereum.core.BlockHeader;
import org.hyperledger.besu.ethereum.core.Gas;
import org.hyperledger.besu.ethereum.core.Hash;
import org.hyperledger.besu.ethereum.core.Transaction;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.TransactionProcessor.Result;
import org.hyperledger.besu.ethereum.vm.ExceptionalHaltReason;
@ -83,9 +84,11 @@ public class DebugTraceTransactionTest {
"NONE",
Gas.of(45),
Optional.of(Gas.of(56)),
Gas.ZERO,
2,
EnumSet.noneOf(ExceptionalHaltReason.class),
null,
Wei.ZERO,
Bytes.EMPTY,
Bytes.EMPTY,
Optional.empty(),
@ -97,9 +100,8 @@ public class DebugTraceTransactionTest {
Optional.empty(),
0,
Optional.empty(),
Optional.empty(),
Optional.empty(),
false,
Optional.empty(),
Optional.empty());
final List<TraceFrame> traceFrames = Collections.singletonList(traceFrame);
final TransactionTrace transactionTrace =
@ -139,9 +141,11 @@ public class DebugTraceTransactionTest {
"NONE",
Gas.of(45),
Optional.of(Gas.of(56)),
Gas.ZERO,
2,
EnumSet.noneOf(ExceptionalHaltReason.class),
null,
Wei.ZERO,
Bytes.EMPTY,
Bytes.EMPTY,
Optional.empty(),
@ -153,9 +157,8 @@ public class DebugTraceTransactionTest {
Optional.empty(),
0,
Optional.empty(),
Optional.empty(),
Optional.empty(),
false,
Optional.empty(),
Optional.empty());
final List<TraceFrame> traceFrames = Collections.singletonList(traceFrame);
final TransactionTrace transactionTrace =

@ -341,6 +341,80 @@
"to": "0x0140000000000000000000000000000000000000"
}
]
},
{
"number": "0x15",
"transactions": [
{
"comment": "Set contract storage (key,value)'s: (1,1),(2,2)",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0040000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002"
},
{
"comment": "Set contract storage (key,value)'s: (1,3),(2,4)",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0040000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004"
},
{
"comment": "Set contract storage (key,value)'s: (1,3),(1,0)",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0040000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"
},
{
"comment": "Clear contract storage keys 1 and 2",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0040000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000"
}
]
},
{
"number": "0x16",
"transactions": [
{
"comment": "Set contract storage (key,value)'s: (1,1),(2,2)",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0060000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002"
},
{
"comment": "Set contract storage (key,value)'s: (1,3),(2,4)",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0060000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004"
},
{
"comment": "Set contract storage (key,value)'s: (1,3),(1,0)",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0060000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000"
},
{
"comment": "Clear contract storage keys 1 and 2",
"secretKey": "0xc87509a1c067bbde78beb793e6fa76530b6382a4c0241e5e4a9ec0a0f44dc0d3",
"gasLimit": "0xFFFFF2",
"gasPrice": "0xEF",
"to": "0x0060000000000000000000000000000000000000",
"data": "0x00000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000"
}
]
}
]
}
}

@ -51,8 +51,8 @@
},
"0060000000000000000000000000000000000000": {
"comment": "Proxy a call to the address in the first 32 bytes, sending the rest of the input data to this address. Return 32 bytes from sub-call.",
"comment": "0x outSize 6020 outOffset 6000 inputSize 60203603 inputToMem(dupSize 80)6020600037 inOffset 6000 val 34 to 600035 gas 5A DELEGATECALL F4 Return 60206000F3",
"code": "0x60206000602036038060206000376000346000355AF460206000F3",
"comment": "0x outSize 6020 outOffset 6000 inputSize 60203603 inputToMem(dupSize 80)6020600037 inOffset 6000 to 600035 gas 5A DELEGATECALL F4 Return 60206000F3",
"code": "0x602060006020360380602060003760006000355AF460206000F3",
"balance": "0x0"
},
"0070000000000000000000000000000000000000": {

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1a055690e93c2f67b",
"to": "0x1a055690f82c2e969"
"from": "0x1a055690e93c2f49d",
"to": "0x1a055690f82c2e78b"
}
},
"code": "=",
@ -32,8 +32,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0babcdea",
"to": "0xffffffffffffffffffffffffffffffffe1cabdafc"
"from": "0xfffffffffffffffffffffffffffffffff0babcfc8",
"to": "0xffffffffffffffffffffffffffffffffe1cabdcda"
}
},
"code": "=",
@ -88,8 +88,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1a055690f82c2e969",
"to": "0x1a055691071c2dc57"
"from": "0x1a055690f82c2e78b",
"to": "0x1a055691071c2da79"
}
},
"code": "=",
@ -99,8 +99,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffe1cabdafc",
"to": "0xffffffffffffffffffffffffffffffffd2dabe80e"
"from": "0xffffffffffffffffffffffffffffffffe1cabdcda",
"to": "0xffffffffffffffffffffffffffffffffd2dabe9ec"
}
},
"code": "=",
@ -155,8 +155,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1a055691071c2dc57",
"to": "0x1a055691160c2cf45"
"from": "0x1a055691071c2da79",
"to": "0x1a055691160c2cd67"
}
},
"code": "=",
@ -166,8 +166,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffd2dabe80e",
"to": "0xffffffffffffffffffffffffffffffffc3eabf520"
"from": "0xffffffffffffffffffffffffffffffffd2dabe9ec",
"to": "0xffffffffffffffffffffffffffffffffc3eabf6fe"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1bc16d678af8acf45",
"to": "0x1bc16d678afd772be"
"from": "0x1bc16d678af8acd67",
"to": "0x1bc16d678afd770e0"
}
},
"code": "=",
@ -32,8 +32,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffc3eabf520",
"to": "0xffffffffffffffffffffffffffffffffc3e5f51a7"
"from": "0xffffffffffffffffffffffffffffffffc3eabf6fe",
"to": "0xffffffffffffffffffffffffffffffffc3e5f5385"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1d7d843dffe9f72be",
"to": "0x1d7d843dffeec2438"
"from": "0x1d7d843dffe9f70e0",
"to": "0x1d7d843dffeec225a"
}
},
"code": "=",
@ -32,8 +32,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffc3e5f51a7",
"to": "0xffffffffffffffffffffffffffffffffc3e12a02d"
"from": "0xffffffffffffffffffffffffffffffffc3e5f5385",
"to": "0xffffffffffffffffffffffffffffffffc3e12a20b"
}
},
"code": "=",
@ -187,8 +187,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1d7d843dffeec2438",
"to": "0x1d7d843dfff38d5b2"
"from": "0x1d7d843dffeec225a",
"to": "0x1d7d843dfff38d3d4"
}
},
"code": "=",
@ -198,8 +198,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffc3e12a02d",
"to": "0xffffffffffffffffffffffffffffffffc3dc5eeb3"
"from": "0xffffffffffffffffffffffffffffffffc3e12a20b",
"to": "0xffffffffffffffffffffffffffffffffc3dc5f091"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1f399b1474e00d5b2",
"to": "0x1f399b1474ec5ecd6"
"from": "0x1f399b1474e00d3d4",
"to": "0x1f399b1474ec5eaf8"
}
},
"code": "=",
@ -179,8 +179,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1f399b1474ec5ecd6",
"to": "0x1f399b1474f4c9d41"
"from": "0x1f399b1474ec5eaf8",
"to": "0x1f399b1474f4c9b63"
}
},
"code": "=",
@ -654,8 +654,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1f399b1474f4c9d41",
"to": "0x1f399b1475011b465"
"from": "0x1f399b1474f4c9b63",
"to": "0x1f399b1475011b287"
}
},
"code": "=",
@ -812,8 +812,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1f399b1475011b465",
"to": "0x1f399b147509864d0"
"from": "0x1f399b1475011b287",
"to": "0x1f399b147509862f2"
}
},
"code": "=",
@ -1263,8 +1263,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1f399b147509864d0",
"to": "0x1f399b147515d7bf4"
"from": "0x1f399b147509862f2",
"to": "0x1f399b147515d7a16"
}
},
"code": "=",
@ -1421,8 +1421,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1f399b147515d7bf4",
"to": "0x1f399b14751e4016d"
"from": "0x1f399b147515d7a16",
"to": "0x1f399b14751e3ff8f"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x20f5b1eaea0ac016d",
"to": "0x20f5b1eaea24cac3f"
"from": "0x20f5b1eaea0abff8f",
"to": "0x20f5b1eaea24caa61"
}
},
"code": "=",
@ -69,8 +69,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffc3dc5eeb3",
"to": "0xffffffffffffffffffffffffffffffffc3c2543e1"
"from": "0xffffffffffffffffffffffffffffffffc3dc5f091",
"to": "0xffffffffffffffffffffffffffffffffc3c2545bf"
}
},
"code": "=",
@ -437,8 +437,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x20f5b1eaea24cac3f",
"to": "0x20f5b1eaea3eca4c0"
"from": "0x20f5b1eaea24caa61",
"to": "0x20f5b1eaea3eca2e2"
}
},
"code": "=",
@ -485,8 +485,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffc3c2543e1",
"to": "0xffffffffffffffffffffffffffffffffc3a854b60"
"from": "0xffffffffffffffffffffffffffffffffc3c2545bf",
"to": "0xffffffffffffffffffffffffffffffffc3a854d3e"
}
},
"code": "=",

@ -16,13 +16,13 @@
"jsonrpc": "2.0",
"result": [
{
"output": "0xf000000000000000000000000000000000000000000000000000000000000001",
"output": "0xf000000000000000000000000000000000000000000000000000000000000002",
"stateDiff": {
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1158e460918415e6b",
"to": "0x1158e46091891dad5"
"to": "0x1158e46091891d8f7"
}
},
"code": "=",
@ -33,7 +33,7 @@
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffffd4565fa",
"to": "0xffffffffffffffffffffffffffffffffffcf4e990"
"to": "0xffffffffffffffffffffffffffffffffffcf4eb6e"
}
},
"code": "=",
@ -57,8 +57,8 @@
"value": "0x0"
},
"result": {
"gasUsed": "0x30a",
"output": "0xf000000000000000000000000000000000000000000000000000000000000001"
"gasUsed": "0x308",
"output": "0xf000000000000000000000000000000000000000000000000000000000000002"
},
"subtraces": 1,
"traceAddress": [],
@ -68,14 +68,14 @@
"action": {
"callType": "delegatecall",
"from": "0x0060000000000000000000000000000000000000",
"gas": "0xfbab36",
"input": "0x",
"gas": "0xfbab38",
"input": "0xf000000000000000000000000000000000000000000000000000000000000001",
"to": "0x0030000000000000000000000000000000000000",
"value": "0x0"
},
"result": {
"gasUsed": "0x1b",
"output": "0x0000000000000000000000000000000000000000000000000000000000000001"
"output": "0xf000000000000000000000000000000000000000000000000000000000000002"
},
"subtraces": 0,
"traceAddress": [
@ -86,7 +86,7 @@
],
"transactionHash": "0x6f77512ee9d43474a884c0703c86712fb98dca772fa6e12252786e3e23f196c1",
"vmTrace": {
"code": "0x60206000602036038060206000376000346000355af460206000f3",
"code": "0x602060006020360380602060003760006000355af460206000f3",
"ops": [
{
"cost": 3,
@ -220,19 +220,6 @@
"pc": 14,
"sub": null
},
{
"cost": 2,
"ex": {
"mem": null,
"push": [
"0x0"
],
"store": null,
"used": 16755873
},
"pc": 16,
"sub": null
},
{
"cost": 3,
"ex": {
@ -241,9 +228,9 @@
"0x0"
],
"store": null,
"used": 16755870
"used": 16755872
},
"pc": 17,
"pc": 16,
"sub": null
},
{
@ -254,9 +241,9 @@
"0x30000000000000000000000000000000000000"
],
"store": null,
"used": 16755867
"used": 16755869
},
"pc": 19,
"pc": 18,
"sub": null
},
{
@ -264,25 +251,28 @@
"ex": {
"mem": null,
"push": [
"0xffac99"
"0xffac9b"
],
"store": null,
"used": 16755865
"used": 16755867
},
"pc": 20,
"pc": 19,
"sub": null
},
{
"cost": 16494066,
"cost": 16494068,
"ex": {
"mem": null,
"mem": {
"data": "0xf000000000000000000000000000000000000000000000000000000000000002",
"off": 0
},
"push": [
"0x1"
],
"store": null,
"used": 16755138
"used": 16755140
},
"pc": 21,
"pc": 20,
"sub": {
"code": "0x60003560010160005260206000f3",
"ops": [
@ -294,7 +284,7 @@
"0x0"
],
"store": null,
"used": 16493363
"used": 16493365
},
"pc": 0,
"sub": null
@ -304,10 +294,10 @@
"ex": {
"mem": null,
"push": [
"0x0"
"0xf000000000000000000000000000000000000000000000000000000000000001"
],
"store": null,
"used": 16493360
"used": 16493362
},
"pc": 2,
"sub": null
@ -320,7 +310,7 @@
"0x1"
],
"store": null,
"used": 16493357
"used": 16493359
},
"pc": 3,
"sub": null
@ -330,10 +320,10 @@
"ex": {
"mem": null,
"push": [
"0x1"
"0xf000000000000000000000000000000000000000000000000000000000000002"
],
"store": null,
"used": 16493354
"used": 16493356
},
"pc": 5,
"sub": null
@ -346,7 +336,7 @@
"0x0"
],
"store": null,
"used": 16493351
"used": 16493353
},
"pc": 6,
"sub": null
@ -355,12 +345,12 @@
"cost": 6,
"ex": {
"mem": {
"data": "0x0000000000000000000000000000000000000000000000000000000000000001",
"data": "0xf000000000000000000000000000000000000000000000000000000000000002",
"off": 0
},
"push": [],
"store": null,
"used": 16493345
"used": 16493347
},
"pc": 8,
"sub": null
@ -373,7 +363,7 @@
"0x20"
],
"store": null,
"used": 16493342
"used": 16493344
},
"pc": 9,
"sub": null
@ -386,7 +376,7 @@
"0x0"
],
"store": null,
"used": 16493339
"used": 16493341
},
"pc": 11,
"sub": null
@ -397,7 +387,7 @@
"mem": null,
"push": [],
"store": null,
"used": 16493339
"used": 16493341
},
"pc": 13,
"sub": null
@ -413,9 +403,9 @@
"0x20"
],
"store": null,
"used": 16755135
"used": 16755137
},
"pc": 22,
"pc": 21,
"sub": null
},
{
@ -426,9 +416,9 @@
"0x0"
],
"store": null,
"used": 16755132
"used": 16755134
},
"pc": 24,
"pc": 23,
"sub": null
},
{
@ -437,9 +427,9 @@
"mem": null,
"push": [],
"store": null,
"used": 16755132
"used": 16755134
},
"pc": 26,
"pc": 25,
"sub": null
}
]

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1314fb3706759dad5",
"to": "0x1314fb37067a68c4f"
"from": "0x1314fb3706759d8f7",
"to": "0x1314fb37067a68a71"
}
},
"code": "=",
@ -32,8 +32,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffffcf4e990",
"to": "0xffffffffffffffffffffffffffffffffffca83816"
"from": "0xffffffffffffffffffffffffffffffffffcf4eb6e",
"to": "0xffffffffffffffffffffffffffffffffffca839f4"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x14d1120d7b66e8c4f",
"to": "0x14d1120d8a56e7f3d"
"from": "0x14d1120d7b66e8a71",
"to": "0x14d1120d8a56e7d5f"
}
},
"code": "=",
@ -32,8 +32,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffffca83816",
"to": "0xfffffffffffffffffffffffffffffffff0da84528"
"from": "0xffffffffffffffffffffffffffffffffffca839f4",
"to": "0xfffffffffffffffffffffffffffffffff0da84706"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x168d28e3ff4367f3d",
"to": "0x168d28e3ff4cf0b77"
"from": "0x168d28e3ff4367d5f",
"to": "0x168d28e3ff4cf0999"
}
},
"code": "=",
@ -45,8 +45,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0da84528",
"to": "0xfffffffffffffffffffffffffffffffff0d0fb8ee"
"from": "0xfffffffffffffffffffffffffffffffff0da84706",
"to": "0xfffffffffffffffffffffffffffffffff0d0fbacc"
}
},
"code": "=",
@ -248,8 +248,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x168d28e3ff4cf0b77",
"to": "0x168d28e3ff530e3c9"
"from": "0x168d28e3ff4cf0999",
"to": "0x168d28e3ff530e1eb"
}
},
"code": "=",
@ -272,8 +272,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0d0fb8ee",
"to": "0xfffffffffffffffffffffffffffffffff0cade09c"
"from": "0xfffffffffffffffffffffffffffffffff0d0fbacc",
"to": "0xfffffffffffffffffffffffffffffffff0cade27a"
}
},
"code": "=",
@ -475,8 +475,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x168d28e3ff530e3c9",
"to": "0x168d28e3ff592bc1b"
"from": "0x168d28e3ff530e1eb",
"to": "0x168d28e3ff592ba3d"
}
},
"code": "=",
@ -499,8 +499,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0cade09c",
"to": "0xfffffffffffffffffffffffffffffffff0c4c084a"
"from": "0xfffffffffffffffffffffffffffffffff0cade27a",
"to": "0xfffffffffffffffffffffffffffffffff0c4c0a28"
}
},
"code": "=",

@ -21,8 +21,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x18493fba7445abc1b",
"to": "0x18493fba744aa28d8"
"from": "0x18493fba7445aba3d",
"to": "0x18493fba744aa26fa"
}
},
"code": "=",
@ -32,8 +32,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0c4c084a",
"to": "0xfffffffffffffffffffffffffffffffff0bfc9b8d"
"from": "0xfffffffffffffffffffffffffffffffff0c4c0a28",
"to": "0xfffffffffffffffffffffffffffffffff0bfc9d6b"
}
},
"code": "=",
@ -168,8 +168,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x18493fba744aa28d8",
"to": "0x18493fba744faf67b"
"from": "0x18493fba744aa26fa",
"to": "0x18493fba744faf49d"
}
},
"code": "=",
@ -179,8 +179,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0bfc9b8d",
"to": "0xfffffffffffffffffffffffffffffffff0babcdea"
"from": "0xfffffffffffffffffffffffffffffffff0bfc9d6b",
"to": "0xfffffffffffffffffffffffffffffffff0babcfc8"
}
},
"code": "=",

@ -14,7 +14,7 @@
"jsonrpc": "2.0",
"result": [
{
"output": "0xf000000000000000000000000000000000000000000000000000000000000001",
"output": "0xf000000000000000000000000000000000000000000000000000000000000002",
"stateDiff": null,
"trace": [
{
@ -27,8 +27,8 @@
"value": "0x0"
},
"result": {
"gasUsed": "0x30a",
"output": "0xf000000000000000000000000000000000000000000000000000000000000001"
"gasUsed": "0x308",
"output": "0xf000000000000000000000000000000000000000000000000000000000000002"
},
"subtraces": 1,
"traceAddress": [],
@ -38,14 +38,14 @@
"action": {
"callType": "delegatecall",
"from": "0x0060000000000000000000000000000000000000",
"gas": "0xfbab36",
"input": "0x",
"gas": "0xfbab38",
"input": "0xf000000000000000000000000000000000000000000000000000000000000001",
"to": "0x0030000000000000000000000000000000000000",
"value": "0x0"
},
"result": {
"gasUsed": "0x1b",
"output": "0x0000000000000000000000000000000000000000000000000000000000000001"
"output": "0xf000000000000000000000000000000000000000000000000000000000000002"
},
"subtraces": 0,
"traceAddress": [

@ -14,13 +14,13 @@
"jsonrpc": "2.0",
"result": [
{
"output": "0xf000000000000000000000000000000000000000000000000000000000000001",
"output": "0xf000000000000000000000000000000000000000000000000000000000000002",
"stateDiff": {
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1158e460918415e6b",
"to": "0x1158e46091891dad5"
"to": "0x1158e46091891d8f7"
}
},
"code": "=",
@ -31,7 +31,7 @@
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffffd4565fa",
"to": "0xffffffffffffffffffffffffffffffffffcf4e990"
"to": "0xffffffffffffffffffffffffffffffffffcf4eb6e"
}
},
"code": "=",

@ -19,8 +19,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x1314fb3706759dad5",
"to": "0x1314fb37067a68c4f"
"from": "0x1314fb3706759d8f7",
"to": "0x1314fb37067a68a71"
}
},
"code": "=",
@ -30,8 +30,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffffcf4e990",
"to": "0xffffffffffffffffffffffffffffffffffca83816"
"from": "0xffffffffffffffffffffffffffffffffffcf4eb6e",
"to": "0xffffffffffffffffffffffffffffffffffca839f4"
}
},
"code": "=",

@ -19,8 +19,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x14d1120d7b66e8c4f",
"to": "0x14d1120d8a56e7f3d"
"from": "0x14d1120d7b66e8a71",
"to": "0x14d1120d8a56e7d5f"
}
},
"code": "=",
@ -30,8 +30,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xffffffffffffffffffffffffffffffffffca83816",
"to": "0xfffffffffffffffffffffffffffffffff0da84528"
"from": "0xffffffffffffffffffffffffffffffffffca839f4",
"to": "0xfffffffffffffffffffffffffffffffff0da84706"
}
},
"code": "=",

@ -19,8 +19,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x168d28e3ff4367f3d",
"to": "0x168d28e3ff4cf0b77"
"from": "0x168d28e3ff4367d5f",
"to": "0x168d28e3ff4cf0999"
}
},
"code": "=",
@ -43,8 +43,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0da84528",
"to": "0xfffffffffffffffffffffffffffffffff0d0fb8ee"
"from": "0xfffffffffffffffffffffffffffffffff0da84706",
"to": "0xfffffffffffffffffffffffffffffffff0d0fbacc"
}
},
"code": "=",
@ -67,8 +67,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x168d28e3ff4cf0b77",
"to": "0x168d28e3ff530e3c9"
"from": "0x168d28e3ff4cf0999",
"to": "0x168d28e3ff530e1eb"
}
},
"code": "=",
@ -91,8 +91,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0d0fb8ee",
"to": "0xfffffffffffffffffffffffffffffffff0cade09c"
"from": "0xfffffffffffffffffffffffffffffffff0d0fbacc",
"to": "0xfffffffffffffffffffffffffffffffff0cade27a"
}
},
"code": "=",
@ -115,8 +115,8 @@
"0x0000000000000000000000000000000000000000": {
"balance": {
"*": {
"from": "0x168d28e3ff530e3c9",
"to": "0x168d28e3ff592bc1b"
"from": "0x168d28e3ff530e1eb",
"to": "0x168d28e3ff592ba3d"
}
},
"code": "=",
@ -139,8 +139,8 @@
"0xfe3b557e8fb62b89f4916b721be55ceb828dbd73": {
"balance": {
"*": {
"from": "0xfffffffffffffffffffffffffffffffff0cade09c",
"to": "0xfffffffffffffffffffffffffffffffff0c4c084a"
"from": "0xfffffffffffffffffffffffffffffffff0cade27a",
"to": "0xfffffffffffffffffffffffffffffffff0c4c0a28"
}
},
"code": "=",

@ -14,12 +14,12 @@
"jsonrpc": "2.0",
"result": [
{
"output": "0xf000000000000000000000000000000000000000000000000000000000000001",
"output": "0xf000000000000000000000000000000000000000000000000000000000000002",
"stateDiff": null,
"trace": [],
"transactionHash": "0x6f77512ee9d43474a884c0703c86712fb98dca772fa6e12252786e3e23f196c1",
"vmTrace": {
"code": "0x60206000602036038060206000376000346000355af460206000f3",
"code": "0x602060006020360380602060003760006000355af460206000f3",
"ops": [
{
"cost": 3,
@ -153,19 +153,6 @@
"pc": 14,
"sub": null
},
{
"cost": 2,
"ex": {
"mem": null,
"push": [
"0x0"
],
"store": null,
"used": 16755873
},
"pc": 16,
"sub": null
},
{
"cost": 3,
"ex": {
@ -174,9 +161,9 @@
"0x0"
],
"store": null,
"used": 16755870
"used": 16755872
},
"pc": 17,
"pc": 16,
"sub": null
},
{
@ -187,9 +174,9 @@
"0x30000000000000000000000000000000000000"
],
"store": null,
"used": 16755867
"used": 16755869
},
"pc": 19,
"pc": 18,
"sub": null
},
{
@ -197,25 +184,28 @@
"ex": {
"mem": null,
"push": [
"0xffac99"
"0xffac9b"
],
"store": null,
"used": 16755865
"used": 16755867
},
"pc": 20,
"pc": 19,
"sub": null
},
{
"cost": 16494066,
"cost": 16494068,
"ex": {
"mem": null,
"mem": {
"data": "0xf000000000000000000000000000000000000000000000000000000000000002",
"off": 0
},
"push": [
"0x1"
],
"store": null,
"used": 16755138
"used": 16755140
},
"pc": 21,
"pc": 20,
"sub": {
"code": "0x60003560010160005260206000f3",
"ops": [
@ -227,7 +217,7 @@
"0x0"
],
"store": null,
"used": 16493363
"used": 16493365
},
"pc": 0,
"sub": null
@ -237,10 +227,10 @@
"ex": {
"mem": null,
"push": [
"0x0"
"0xf000000000000000000000000000000000000000000000000000000000000001"
],
"store": null,
"used": 16493360
"used": 16493362
},
"pc": 2,
"sub": null
@ -253,7 +243,7 @@
"0x1"
],
"store": null,
"used": 16493357
"used": 16493359
},
"pc": 3,
"sub": null
@ -263,10 +253,10 @@
"ex": {
"mem": null,
"push": [
"0x1"
"0xf000000000000000000000000000000000000000000000000000000000000002"
],
"store": null,
"used": 16493354
"used": 16493356
},
"pc": 5,
"sub": null
@ -279,7 +269,7 @@
"0x0"
],
"store": null,
"used": 16493351
"used": 16493353
},
"pc": 6,
"sub": null
@ -288,12 +278,12 @@
"cost": 6,
"ex": {
"mem": {
"data": "0x0000000000000000000000000000000000000000000000000000000000000001",
"data": "0xf000000000000000000000000000000000000000000000000000000000000002",
"off": 0
},
"push": [],
"store": null,
"used": 16493345
"used": 16493347
},
"pc": 8,
"sub": null
@ -306,7 +296,7 @@
"0x20"
],
"store": null,
"used": 16493342
"used": 16493344
},
"pc": 9,
"sub": null
@ -319,7 +309,7 @@
"0x0"
],
"store": null,
"used": 16493339
"used": 16493341
},
"pc": 11,
"sub": null
@ -330,7 +320,7 @@
"mem": null,
"push": [],
"store": null,
"used": 16493339
"used": 16493341
},
"pc": 13,
"sub": null
@ -346,9 +336,9 @@
"0x20"
],
"store": null,
"used": 16755135
"used": 16755137
},
"pc": 22,
"pc": 21,
"sub": null
},
{
@ -359,9 +349,9 @@
"0x0"
],
"store": null,
"used": 16755132
"used": 16755134
},
"pc": 24,
"pc": 23,
"sub": null
},
{
@ -370,9 +360,9 @@
"mem": null,
"push": [],
"store": null,
"used": 16755132
"used": 16755134
},
"pc": 26,
"pc": 25,
"sub": null
}
]

@ -37,9 +37,11 @@ public class TraceFrame {
private final String opcode;
private final Gas gasRemaining;
private final Optional<Gas> gasCost;
private final Gas gasRefund;
private final int depth;
private final EnumSet<ExceptionalHaltReason> exceptionalHaltReasons;
private final Address recipient;
private final Wei value;
private final Bytes inputData;
private final Bytes outputData;
private final Optional<Bytes32[]> stack;
@ -51,22 +53,23 @@ public class TraceFrame {
private final Optional<Code> maybeCode;
private final int stackItemsProduced;
private final Optional<Bytes32[]> stackPostExecution;
private final Optional<Bytes[]> memoryPostExecution;
private Optional<Integer> maybeNextDepth;
private Gas gasRemainingPostExecution;
private final Optional<Map<UInt256, UInt256>> storagePreExecution;
private final boolean virtualOperation;
private final Optional<MemoryEntry> maybeUpdatedMemory;
private final Optional<MemoryEntry> maybeUpdatedStorage;
private Optional<Gas> precompiledGasCost;
public TraceFrame(
final int pc,
final String opcode,
final Gas gasRemaining,
final Optional<Gas> gasCost,
final Gas gasRefund,
final int depth,
final EnumSet<ExceptionalHaltReason> exceptionalHaltReasons,
final Address recipient,
final Wei value,
final Bytes inputData,
final Bytes outputData,
final Optional<Bytes32[]> stack,
@ -78,17 +81,18 @@ public class TraceFrame {
final Optional<Code> maybeCode,
final int stackItemsProduced,
final Optional<Bytes32[]> stackPostExecution,
final Optional<Bytes[]> memoryPostExecution,
final Optional<Map<UInt256, UInt256>> storagePreExecution,
final boolean virtualOperation,
final Optional<MemoryEntry> maybeUpdatedMemory) {
final Optional<MemoryEntry> maybeUpdatedMemory,
final Optional<MemoryEntry> maybeUpdatedStorage) {
this.pc = pc;
this.opcode = opcode;
this.gasRemaining = gasRemaining;
this.gasCost = gasCost;
this.gasRefund = gasRefund;
this.depth = depth;
this.exceptionalHaltReasons = exceptionalHaltReasons;
this.recipient = recipient;
this.value = value;
this.inputData = inputData;
this.outputData = outputData;
this.stack = stack;
@ -100,11 +104,10 @@ public class TraceFrame {
this.maybeCode = maybeCode;
this.stackItemsProduced = stackItemsProduced;
this.stackPostExecution = stackPostExecution;
this.memoryPostExecution = memoryPostExecution;
this.maybeNextDepth = Optional.empty();
this.storagePreExecution = storagePreExecution;
this.virtualOperation = virtualOperation;
this.maybeUpdatedMemory = maybeUpdatedMemory;
this.maybeUpdatedStorage = maybeUpdatedStorage;
precompiledGasCost = Optional.empty();
}
public int getPc() {
@ -123,6 +126,10 @@ public class TraceFrame {
return gasCost;
}
public Gas getGasRefund() {
return gasRefund;
}
public int getDepth() {
return depth;
}
@ -135,6 +142,10 @@ public class TraceFrame {
return recipient;
}
public Wei getValue() {
return value;
}
public Bytes getInputData() {
return inputData;
}
@ -194,34 +205,10 @@ public class TraceFrame {
return stackPostExecution;
}
public Optional<Bytes[]> getMemoryPostExecution() {
return memoryPostExecution;
}
public boolean depthHasIncreased() {
return maybeNextDepth.map(next -> next > depth).orElse(false);
}
public boolean depthHasDecreased() {
return maybeNextDepth.map(next -> next < depth).orElse(false);
}
public Optional<Integer> getMaybeNextDepth() {
return maybeNextDepth;
}
public void setMaybeNextDepth(final Optional<Integer> maybeNextDepth) {
this.maybeNextDepth = maybeNextDepth;
}
public Gas getGasRemainingPostExecution() {
return gasRemainingPostExecution;
}
public Optional<Map<UInt256, UInt256>> getStoragePreExecution() {
return storagePreExecution;
}
public void setGasRemainingPostExecution(final Gas gasRemainingPostExecution) {
this.gasRemainingPostExecution = gasRemainingPostExecution;
}
@ -233,4 +220,16 @@ public class TraceFrame {
public Optional<MemoryEntry> getMaybeUpdatedMemory() {
return maybeUpdatedMemory;
}
public Optional<MemoryEntry> getMaybeUpdatedStorage() {
return maybeUpdatedStorage;
}
public Optional<Gas> getPrecompiledGasCost() {
return precompiledGasCost;
}
public void setPrecompiledGasCost(final Optional<Gas> precompiledGasCost) {
this.precompiledGasCost = precompiledGasCost;
}
}

@ -42,7 +42,7 @@ import java.util.stream.Collectors;
* </tr>
* <tr>
* <td>{@link MessageFrame.State#NOT_STARTED}</td>
* <td>{@link AbstractMessageProcessor#start(MessageFrame)}</td>
* <td>{@link AbstractMessageProcessor#start(MessageFrame, OperationTracer)}</td>
* </tr>
* <tr>
* <td>{@link MessageFrame.State#CODE_EXECUTING}</td>
@ -74,7 +74,7 @@ public abstract class AbstractMessageProcessor {
this.forceDeleteAccountsWhenEmpty = forceDeleteAccountsWhenEmpty;
}
protected abstract void start(MessageFrame frame);
protected abstract void start(MessageFrame frame, final OperationTracer operationTracer);
/**
* Gets called when the message frame code executes successfully.
@ -163,7 +163,7 @@ public abstract class AbstractMessageProcessor {
public void process(final MessageFrame frame, final OperationTracer operationTracer) {
if (frame.getState() == MessageFrame.State.NOT_STARTED) {
start(frame);
start(frame, operationTracer);
}
if (frame.getState() == MessageFrame.State.CODE_EXECUTING) {

@ -22,6 +22,7 @@ import org.hyperledger.besu.ethereum.core.MutableAccount;
import org.hyperledger.besu.ethereum.vm.EVM;
import org.hyperledger.besu.ethereum.vm.GasCalculator;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.ethereum.vm.OperationTracer;
import java.util.Collection;
import java.util.List;
@ -102,7 +103,7 @@ public class MainnetContractCreationProcessor extends AbstractMessageProcessor {
}
@Override
public void start(final MessageFrame frame) {
public void start(final MessageFrame frame, final OperationTracer operationTracer) {
if (LOG.isTraceEnabled()) {
LOG.trace("Executing contract-creation");
}

@ -21,6 +21,7 @@ import org.hyperledger.besu.ethereum.core.MutableAccount;
import org.hyperledger.besu.ethereum.core.Wei;
import org.hyperledger.besu.ethereum.vm.EVM;
import org.hyperledger.besu.ethereum.vm.MessageFrame;
import org.hyperledger.besu.ethereum.vm.OperationTracer;
import java.util.Collection;
@ -48,7 +49,7 @@ public class MainnetMessageCallProcessor extends AbstractMessageProcessor {
}
@Override
public void start(final MessageFrame frame) {
public void start(final MessageFrame frame, final OperationTracer operationTracer) {
LOG.trace("Executing message-call");
try {
transferValue(frame);
@ -57,7 +58,7 @@ public class MainnetMessageCallProcessor extends AbstractMessageProcessor {
final PrecompiledContract precompile =
precompiles.get(frame.getContractAddress(), frame.getContractAccountVersion());
if (precompile != null) {
executePrecompile(precompile, frame);
executePrecompile(precompile, frame, operationTracer);
} else {
frame.setState(MessageFrame.State.CODE_EXECUTING);
}
@ -114,7 +115,10 @@ public class MainnetMessageCallProcessor extends AbstractMessageProcessor {
*
* @param contract The contract this is a message call to.
*/
private void executePrecompile(final PrecompiledContract contract, final MessageFrame frame) {
private void executePrecompile(
final PrecompiledContract contract,
final MessageFrame frame,
final OperationTracer operationTracer) {
final Gas gasRequirement = contract.gasRequirement(frame.getInputData());
if (frame.getRemainingGas().compareTo(gasRequirement) < 0) {
LOG.trace(
@ -127,6 +131,7 @@ public class MainnetMessageCallProcessor extends AbstractMessageProcessor {
} else {
frame.decrementRemainingGas(gasRequirement);
final Bytes output = contract.compute(frame.getInputData(), frame);
operationTracer.tracePrecompileCall(frame, gasRequirement, output);
if (output != null) {
if (contract.getName().equals("Privacy")) {
// do not decrement the gas requirement for a privacy pre-compile contract call -> leads

@ -61,19 +61,15 @@ public class DebugOperationTracer implements OperationTracer {
EnumSet.copyOf(frame.getExceptionalHaltReasons());
final Bytes inputData = frame.getInputData();
final Optional<Bytes32[]> stack = captureStack(frame);
final Optional<Map<UInt256, UInt256>> storagePreExecution = captureStorage(frame);
final WorldUpdater worldUpdater = frame.getWorldState();
final Optional<Bytes32[]> stackPostExecution;
final Optional<Bytes[]> memoryPostExecution;
try {
executeOperation.execute();
} finally {
final Bytes outputData = frame.getOutputData();
final Optional<Bytes[]> memory = captureMemory(frame);
stackPostExecution = captureStack(frame);
memoryPostExecution = captureMemory(frame);
if (lastFrame != null) {
lastFrame.setMaybeNextDepth(Optional.of(depth));
lastFrame.setGasRemainingPostExecution(gasRemaining);
}
final Optional<Map<UInt256, UInt256>> storage = captureStorage(frame);
@ -85,9 +81,11 @@ public class DebugOperationTracer implements OperationTracer {
opcode,
gasRemaining,
currentGasCost,
frame.getGasRefund(),
depth,
exceptionalHaltReasons,
frame.getRecipientAddress(),
frame.getApparentValue(),
inputData,
outputData,
stack,
@ -96,18 +94,23 @@ public class DebugOperationTracer implements OperationTracer {
worldUpdater,
frame.getRevertReason(),
maybeRefunds,
Optional.ofNullable(frame.getCode()),
Optional.ofNullable(frame.getMessageFrameStack().peek()).map(MessageFrame::getCode),
frame.getCurrentOperation().getStackItemsProduced(),
stackPostExecution,
memoryPostExecution,
storagePreExecution,
currentOperation.isVirtualOperation(),
frame.getMaybeUpdatedMemory());
frame.getMaybeUpdatedMemory(),
frame.getMaybeUpdatedStorage());
traceFrames.add(lastFrame);
}
frame.reset();
}
@Override
public void tracePrecompileCall(
final MessageFrame frame, final Gas gasRequirement, final Bytes output) {
traceFrames.get(traceFrames.size() - 1).setPrecompiledGasCost(Optional.of(gasRequirement));
}
private Optional<Map<UInt256, UInt256>> captureStorage(final MessageFrame frame) {
if (!options.isStorageEnabled()) {
return Optional.empty();

@ -235,6 +235,7 @@ public class MessageFrame {
private Operation currentOperation;
private final Consumer<MessageFrame> completer;
private Optional<MemoryEntry> maybeUpdatedMemory = Optional.empty();
private Optional<MemoryEntry> maybeUpdatedStorage = Optional.empty();
public static Builder builder() {
return new Builder();
@ -556,16 +557,6 @@ public class MessageFrame {
return value;
}
/**
* Write byte to memory
*
* @param offset The offset in memory
* @param value The value to set in memory
*/
public void writeMemory(final UInt256 offset, final byte value) {
writeMemory(offset, value, false);
}
/**
* Write byte to memory
*
@ -668,6 +659,9 @@ public class MessageFrame {
maybeUpdatedMemory = Optional.of(new MemoryEntry(offset, value));
}
public void storageWasUpdated(final UInt256 storageAddress, final Bytes value) {
maybeUpdatedStorage = Optional.of(new MemoryEntry(storageAddress, value));
}
/**
* Accumulate a log.
*
@ -978,8 +972,13 @@ public class MessageFrame {
return maybeUpdatedMemory;
}
public Optional<MemoryEntry> getMaybeUpdatedStorage() {
return maybeUpdatedStorage;
}
public void reset() {
maybeUpdatedMemory = Optional.empty();
maybeUpdatedStorage = Optional.empty();
}
public static class Builder {

@ -19,6 +19,8 @@ import org.hyperledger.besu.ethereum.vm.ehalt.ExceptionalHaltException;
import java.util.Optional;
import org.apache.tuweni.bytes.Bytes;
public interface OperationTracer {
OperationTracer NO_TRACING =
@ -28,6 +30,9 @@ public interface OperationTracer {
MessageFrame frame, Optional<Gas> currentGasCost, ExecuteOperation executeOperation)
throws ExceptionalHaltException;
default void tracePrecompileCall(
final MessageFrame frame, final Gas gasRequirement, final Bytes output) {};
interface ExecuteOperation {
void execute() throws ExceptionalHaltException;

@ -62,6 +62,7 @@ public class SStoreOperation extends AbstractOperation {
frame.incrementGasRefund(gasCalculator().calculateStorageRefundAmount(account, key, value));
account.setStorageValue(key, value);
frame.storageWasUpdated(key, value.toBytes());
}
@Override

Loading…
Cancel
Save