Skip to content

Commit

Permalink
Add updated storage to evmtool json trace (hyperledger#5892)
Browse files Browse the repository at this point in the history
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>
Signed-off-by: garyschulte <garyschulte@gmail.com>
  • Loading branch information
shemnon authored and garyschulte committed Sep 20, 2023
1 parent c8bb644 commit d4aeaea
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,24 +69,22 @@ public Optional<TransactionTrace> traceTransaction(
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(
Expand Down Expand Up @@ -139,7 +137,7 @@ public List<String> traceTransactionToFile(
stackedUpdater,
transaction,
transactionProcessor,
new StandardJsonTracer(out, showMemory, true, true),
new StandardJsonTracer(out, showMemory, true, true, false),
blobGasPrice);
out.println(
summaryTrace(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,14 @@ void setBytes(final String optionValue) {
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.",
Expand Down Expand Up @@ -365,7 +373,7 @@ public void run() {

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();
Expand Down Expand Up @@ -466,10 +474,10 @@ public static void dumpWorldState(final WorldState worldState, final PrintWriter
" \""
+ accountStorageEntry
.getKey()
.map(UInt256::toHexString)
.map(UInt256::toQuantityHexString)
.orElse("-")
+ "\": \""
+ accountStorageEntry.getValue().toHexString()
+ accountStorageEntry.getValue().toQuantityHexString()
+ "\"")
.toList()));
out.println(" },");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ private void traceTestSpecs(final String test, final List<GeneralStateTestCaseEi
parentCommand.out,
parentCommand.showMemory,
!parentCommand.hideStack,
parentCommand.showReturnData)
parentCommand.showReturnData,
parentCommand.showStorage)
: OperationTracer.NO_TRACING;

final ObjectMapper objectMapper = JsonUtils.createObjectMapper();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ public OperationTracer getManagedTracer(final int txIndex, final Hash txHash)
new PrintStream(traceDest),
parentCommand.showMemory,
!parentCommand.hideStack,
parentCommand.showReturnData);
parentCommand.showReturnData,
parentCommand.showStorage);
outputStreams.put(jsonTracer, traceDest);
return jsonTracer;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ 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;
private String gas;
private Bytes memory;
private int memorySize;
private int depth;
private String storageString;

/**
* Instantiates a new Standard json tracer.
Expand All @@ -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;
}

/**
Expand All @@ -79,13 +84,20 @@ public StandardJsonTracer(
* @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);
}

/**
Expand Down Expand Up @@ -130,6 +142,33 @@ public void tracePreExecution(final MessageFrame messageFrame) {
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
Expand All @@ -155,7 +194,7 @@ public void tracePostExecution(
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(",");
Expand All @@ -164,14 +203,14 @@ public void tracePostExecution(
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);
}

Expand Down Expand Up @@ -229,7 +268,7 @@ public void traceEndTransaction(
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\":\"\",");
Expand Down
Loading

0 comments on commit d4aeaea

Please sign in to comment.