Add updated storage to evmtool json trace (#5892)

Add the EIP-3155 "storage" option to the standard tracer, with the
caveat only updated storage is logged.

Signed-off-by: Danno Ferrin <danno.ferrin@swirldslabs.com>
pull/5907/head
Danno Ferrin 1 year ago committed by GitHub
parent 7c5c2bfbcb
commit 4e6b1fbd25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/processor/TransactionTracer.java
  2. 14
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/EvmToolCommand.java
  3. 3
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/StateTestSubCommand.java
  4. 3
      ethereum/evmtool/src/main/java/org/hyperledger/besu/evmtool/T8nSubCommand.java
  5. 57
      evm/src/main/java/org/hyperledger/besu/evm/tracing/StandardJsonTracer.java
  6. 68
      evm/src/test/java/org/hyperledger/besu/evm/StandardJsonTracerTest.java
  7. 9
      evm/src/test/java/org/hyperledger/besu/evm/toy/EvmToyCommand.java

@ -69,24 +69,22 @@ public class TransactionTracer {
final Hash blockHash,
final Hash transactionHash,
final DebugOperationTracer tracer) {
Optional<TransactionTrace> transactionTrace =
blockReplay.beforeTransactionInBlock(
mutableWorldState,
blockHash,
transactionHash,
(transaction, header, blockchain, transactionProcessor, blobGasPrice) -> {
final TransactionProcessingResult result =
processTransaction(
header,
blockchain,
mutableWorldState.updater(),
transaction,
transactionProcessor,
tracer,
blobGasPrice);
return new TransactionTrace(transaction, result, tracer.getTraceFrames());
});
return transactionTrace;
return blockReplay.beforeTransactionInBlock(
mutableWorldState,
blockHash,
transactionHash,
(transaction, header, blockchain, transactionProcessor, blobGasPrice) -> {
final TransactionProcessingResult result =
processTransaction(
header,
blockchain,
mutableWorldState.updater(),
transaction,
transactionProcessor,
tracer,
blobGasPrice);
return new TransactionTrace(transaction, result, tracer.getTraceFrames());
});
}
public List<String> traceTransactionToFile(
@ -139,7 +137,7 @@ public class TransactionTracer {
stackedUpdater,
transaction,
transactionProcessor,
new StandardJsonTracer(out, showMemory, true, true),
new StandardJsonTracer(out, showMemory, true, true, false),
blobGasPrice);
out.println(
summaryTrace(

@ -181,6 +181,14 @@ public class EvmToolCommand implements Runnable {
negatable = true)
final Boolean showReturnData = false;
@Option(
names = {"--trace.storage"},
description =
"Show the updated storage slots for the current account. Default is to not show updated storage.",
scope = INHERIT,
negatable = true)
final Boolean showStorage = false;
@Option(
names = {"--notime"},
description = "Don't include time data in summary output.",
@ -365,7 +373,7 @@ public class EvmToolCommand implements Runnable {
final OperationTracer tracer = // You should have picked Mercy.
lastLoop && showJsonResults
? new StandardJsonTracer(out, showMemory, !hideStack, showReturnData)
? new StandardJsonTracer(out, showMemory, !hideStack, showReturnData, showStorage)
: OperationTracer.NO_TRACING;
WorldUpdater updater = component.getWorldUpdater();
@ -466,10 +474,10 @@ public class EvmToolCommand implements Runnable {
" \""
+ accountStorageEntry
.getKey()
.map(UInt256::toHexString)
.map(UInt256::toQuantityHexString)
.orElse("-")
+ "\": \""
+ accountStorageEntry.getValue().toHexString()
+ accountStorageEntry.getValue().toQuantityHexString()
+ "\"")
.toList()));
out.println(" },");

@ -182,7 +182,8 @@ public class StateTestSubCommand implements Runnable {
parentCommand.out,
parentCommand.showMemory,
!parentCommand.hideStack,
parentCommand.showReturnData)
parentCommand.showReturnData,
parentCommand.showStorage)
: OperationTracer.NO_TRACING;
final ObjectMapper objectMapper = JsonUtils.createObjectMapper();

@ -254,7 +254,8 @@ public class T8nSubCommand implements Runnable {
new PrintStream(traceDest),
parentCommand.showMemory,
!parentCommand.hideStack,
parentCommand.showReturnData);
parentCommand.showReturnData,
parentCommand.showStorage);
outputStreams.put(jsonTracer, traceDest);
return jsonTracer;
}

@ -45,6 +45,7 @@ public class StandardJsonTracer implements OperationTracer {
private final boolean showMemory;
private final boolean showStack;
private final boolean showReturnData;
private final boolean showStorage;
private int pc;
private int section;
private List<String> stack;
@ -52,6 +53,7 @@ public class StandardJsonTracer implements OperationTracer {
private Bytes memory;
private int memorySize;
private int depth;
private String storageString;
/**
* Instantiates a new Standard json tracer.
@ -60,16 +62,19 @@ public class StandardJsonTracer implements OperationTracer {
* @param showMemory show memory in trace lines
* @param showStack show the stack in trace lines
* @param showReturnData show return data in trace lines
* @param showStorage show the updated storage
*/
public StandardJsonTracer(
final PrintWriter out,
final boolean showMemory,
final boolean showStack,
final boolean showReturnData) {
final boolean showReturnData,
final boolean showStorage) {
this.out = out;
this.showMemory = showMemory;
this.showStack = showStack;
this.showReturnData = showReturnData;
this.showStorage = showStorage;
}
/**
@ -79,13 +84,20 @@ public class StandardJsonTracer implements OperationTracer {
* @param showMemory show memory in trace lines
* @param showStack show the stack in trace lines
* @param showReturnData show return data in trace lines
* @param showStorage show updated storage
*/
public StandardJsonTracer(
final PrintStream out,
final boolean showMemory,
final boolean showStack,
final boolean showReturnData) {
this(new PrintWriter(out, true, StandardCharsets.UTF_8), showMemory, showStack, showReturnData);
final boolean showReturnData,
final boolean showStorage) {
this(
new PrintWriter(out, true, StandardCharsets.UTF_8),
showMemory,
showStack,
showReturnData,
showStorage);
}
/**
@ -130,6 +142,33 @@ public class StandardJsonTracer implements OperationTracer {
memory = null;
}
depth = messageFrame.getMessageStackSize();
StringBuilder sb = new StringBuilder();
if (showStorage) {
var updater = messageFrame.getWorldUpdater();
var account = updater.getAccount(messageFrame.getRecipientAddress());
if (account != null && !account.getUpdatedStorage().isEmpty()) {
boolean[] shownEntry = {false};
sb.append(",\"storage\":{");
account
.getUpdatedStorage()
.forEach(
(k, v) -> {
if (shownEntry[0]) {
sb.append(",");
} else {
shownEntry[0] = true;
}
sb.append("\"")
.append(k.toQuantityHexString())
.append("\":\"")
.append(v.toQuantityHexString())
.append("\"");
});
sb.append("}");
}
}
storageString = sb.toString();
}
@Override
@ -155,7 +194,7 @@ public class StandardJsonTracer implements OperationTracer {
if (showStack) {
sb.append("\"stack\":[").append(commaJoiner.join(stack)).append("],");
}
if (showReturnData && returnData.size() > 0) {
if (showReturnData && !returnData.isEmpty()) {
sb.append("\"returnData\":\"").append(returnData.toHexString()).append("\",");
}
sb.append("\"depth\":").append(depth).append(",");
@ -164,14 +203,14 @@ public class StandardJsonTracer implements OperationTracer {
if (executeResult.getHaltReason() != null) {
sb.append(",\"error\":\"")
.append(executeResult.getHaltReason().getDescription())
.append("\"}");
.append("\"");
} else if (messageFrame.getRevertReason().isPresent()) {
sb.append(",\"error\":\"")
.append(quoteEscape(messageFrame.getRevertReason().orElse(Bytes.EMPTY)))
.append("\"}");
} else {
sb.append("}");
.append("\"");
}
sb.append(storageString).append("}");
out.println(sb);
}
@ -229,7 +268,7 @@ public class StandardJsonTracer implements OperationTracer {
final long timeNs) {
final StringBuilder sb = new StringBuilder(1024);
sb.append("{");
if (output.size() > 0) {
if (!output.isEmpty()) {
sb.append("\"output\":\"").append(output.toShortHexString()).append("\",");
} else {
sb.append("\"output\":\"\",");

@ -38,7 +38,7 @@ class StandardJsonTracerTest {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baos);
var executor = EVMExecutor.istanbul(EvmConfiguration.DEFAULT);
StandardJsonTracer tracer = new StandardJsonTracer(out, true, true, true);
StandardJsonTracer tracer = new StandardJsonTracer(out, true, true, true, false);
executor.tracer(tracer);
executor.gas(10_000_000_000L);
@ -58,20 +58,56 @@ class StandardJsonTracerTest {
// (g) if error is zero length or null it is not included.
assertThat(baos)
.hasToString(
"{\"pc\":0,\"op\":96,\"gas\":\"0x2540be400\",\"gasCost\":\"0x3\",\"memSize\":0,\"stack\":[],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":2,\"op\":128,\"gas\":\"0x2540be3fd\",\"gasCost\":\"0x3\",\"memSize\":0,\"stack\":[\"0x40\"],\"depth\":1,\"refund\":0,\"opName\":\"DUP1\"}\n"
+ "{\"pc\":3,\"op\":83,\"gas\":\"0x2540be3fa\",\"gasCost\":\"0xc\",\"memSize\":0,\"stack\":[\"0x40\",\"0x40\"],\"depth\":1,\"refund\":0,\"opName\":\"MSTORE8\"}\n"
+ "{\"pc\":4,\"op\":96,\"gas\":\"0x2540be3ee\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":6,\"op\":96,\"gas\":\"0x2540be3eb\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\"],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":8,\"op\":85,\"gas\":\"0x2540be3e8\",\"gasCost\":\"0x4e20\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\",\"0x40\"],\"depth\":1,\"refund\":0,\"opName\":\"SSTORE\"}\n"
+ "{\"pc\":9,\"op\":96,\"gas\":\"0x2540b95c8\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":11,\"op\":96,\"gas\":\"0x2540b95c5\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\"],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":13,\"op\":96,\"gas\":\"0x2540b95c2\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\",\"0x0\"],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":15,\"op\":96,\"gas\":\"0x2540b95bf\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\",\"0x0\",\"0x40\"],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":17,\"op\":96,\"gas\":\"0x2540b95bc\",\"gasCost\":\"0x3\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\",\"0x0\",\"0x40\",\"0x0\"],\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":19,\"op\":90,\"gas\":\"0x2540b95b9\",\"gasCost\":\"0x2\",\"memory\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x40\",\"0x0\",\"0x40\",\"0x0\",\"0x2\"],\"depth\":1,\"refund\":0,\"opName\":\"GAS\"}\n"
+ "{\"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\"}\n"
+ "{\"pc\":21,\"op\":96,\"gas\":\"0x2540b92a7\",\"gasCost\":\"0x3\",\"memory\":\"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x1\"],\"returnData\":\"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\"depth\":1,\"refund\":0,\"opName\":\"PUSH1\"}\n"
+ "{\"pc\":23,\"op\":243,\"gas\":\"0x2540b92a4\",\"gasCost\":\"0x0\",\"memory\":\"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000\",\"memSize\":96,\"stack\":[\"0x1\",\"0x40\"],\"returnData\":\"0xf5a5fd42d16a20302798ef6ed309979b43003d2320d9f0e8ea9831a92759fb4b\",\"depth\":1,\"refund\":0,\"opName\":\"RETURN\"}\n");
"""
{"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":2,"op":128,"gas":"0x2540be3fd","gasCost":"0x3","memSize":0,"stack":["0x40"],"depth":1,"refund":0,"opName":"DUP1"}
{"pc":3,"op":83,"gas":"0x2540be3fa","gasCost":"0xc","memSize":0,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"MSTORE8"}
{"pc":4,"op":96,"gas":"0x2540be3ee","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":6,"op":96,"gas":"0x2540be3eb","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":8,"op":85,"gas":"0x2540be3e8","gasCost":"0x4e20","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x40"],"depth":1,"refund":0,"opName":"SSTORE"}
{"pc":9,"op":96,"gas":"0x2540b95c8","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":[],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":11,"op":96,"gas":"0x2540b95c5","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40"],"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":13,"op":96,"gas":"0x2540b95c2","gasCost":"0x3","memory":"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000","memSize":96,"stack":["0x40","0x0"],"depth":1,"refund":0,"opName":"PUSH1"}
{"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":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"}
""");
}
@Test
void updatedStorageTestCase() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream out = new PrintStream(baos);
var executor = EVMExecutor.istanbul(EvmConfiguration.DEFAULT);
StandardJsonTracer tracer = new StandardJsonTracer(out, false, false, false, true);
executor.tracer(tracer);
executor.gas(10_000_000_000L);
var codeBytes = Bytes.fromHexString("0x604080536040604055604060006040600060025afa6040f3");
executor.execute(codeBytes, Bytes.EMPTY, Wei.ZERO, Address.ZERO);
assertThat(baos)
.hasToString(
"""
{"pc":0,"op":96,"gas":"0x2540be400","gasCost":"0x3","memSize":0,"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":2,"op":128,"gas":"0x2540be3fd","gasCost":"0x3","memSize":0,"depth":1,"refund":0,"opName":"DUP1"}
{"pc":3,"op":83,"gas":"0x2540be3fa","gasCost":"0xc","memSize":0,"depth":1,"refund":0,"opName":"MSTORE8"}
{"pc":4,"op":96,"gas":"0x2540be3ee","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":6,"op":96,"gas":"0x2540be3eb","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1"}
{"pc":8,"op":85,"gas":"0x2540be3e8","gasCost":"0x4e20","memSize":96,"depth":1,"refund":0,"opName":"SSTORE"}
{"pc":9,"op":96,"gas":"0x2540b95c8","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1","storage":{"0x40":"0x40"}}
{"pc":11,"op":96,"gas":"0x2540b95c5","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1","storage":{"0x40":"0x40"}}
{"pc":13,"op":96,"gas":"0x2540b95c2","gasCost":"0x3","memSize":96,"depth":1,"refund":0,"opName":"PUSH1","storage":{"0x40":"0x40"}}
{"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":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"}}
""");
}
}

@ -122,6 +122,12 @@ public class EvmToyCommand implements Runnable {
scope = ScopeType.INHERIT)
final Boolean showReturnData = false;
@CommandLine.Option(
names = {"--trace.storage"},
description = "When tracing, show the updated storage contents.",
scope = ScopeType.INHERIT)
final Boolean showStorage = false;
@CommandLine.Option(
names = {"--repeat"},
description = "Number of times to repeat for benchmarking.")
@ -164,7 +170,8 @@ public class EvmToyCommand implements Runnable {
final OperationTracer tracer = // You should have picked Mercy.
lastLoop && showJsonResults
? new StandardJsonTracer(System.out, showMemory, showStack, showReturnData)
? new StandardJsonTracer(
System.out, showMemory, showStack, showReturnData, showStorage)
: OperationTracer.NO_TRACING;
MessageFrame initialMessageFrame =

Loading…
Cancel
Save