Improve flat trace generation performance (#6472)

Improve flat trace generation performance

Signed-off-by: Ameziane H <ameziane.hamlat@consensys.net>
pull/6088/merge
ahamlat 9 months ago committed by GitHub
parent 737d931fca
commit 8d25b24cd7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 3
      CHANGELOG.md
  2. 20
      ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/results/tracing/flat/FlatTraceGenerator.java
  3. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByHashTest.java
  4. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockByNumberTest.java
  5. 1
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceBlockTest.java
  6. 2
      ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/methods/DebugTraceTransactionTest.java
  7. 7
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/debug/TraceFrame.java
  8. 4
      ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java
  9. 5
      evm/src/main/java/org/hyperledger/besu/evm/operation/ReturnOperation.java
  10. 5
      evm/src/main/java/org/hyperledger/besu/evm/operation/RevertOperation.java

@ -31,8 +31,9 @@
- Log blob count when importing a block via Engine API [#6466](https://github.com/hyperledger/besu/pull/6466)
- Introduce `--Xbonsai-limit-trie-logs-enabled` experimental feature which by default will only retain the latest 512 trie logs, saving about 3GB per week in database growth [#5390](https://github.com/hyperledger/besu/issues/5390)
- Introduce `besu storage x-trie-log prune` experimental offline subcommand which will prune all redundant trie logs except the latest 512 [#6303](https://github.com/hyperledger/besu/pull/6303)
- Improve flat trace generation performance [#6472](https://github.com/hyperledger/besu/pull/6472)
- SNAP and CHECKPOINT sync - early access flag removed so now simply SNAP and CHECKPOINT [#6405](https://github.com/hyperledger/besu/pull/6405)
- X_SNAP and X_CHECKPOINT are marked for deprecation and will be removed in 24.4.0
- X_SNAP and X_CHECKPOINT are marked for deprecation and will be removed in 24.4.0
- Github Actions based build.
- Introduce caching mechanism to optimize Keccak hash calculations for account storage slots during block processing [#6452](https://github.com/hyperledger/besu/pull/6452)
- Added configuration options for `pragueTime` to genesis file for Prague fork development [#6473](https://github.com/hyperledger/besu/pull/6473)

@ -28,6 +28,8 @@ import org.hyperledger.besu.ethereum.debug.TraceFrame;
import org.hyperledger.besu.ethereum.mainnet.ProtocolSchedule;
import org.hyperledger.besu.evm.Code;
import org.hyperledger.besu.evm.frame.ExceptionalHaltReason;
import org.hyperledger.besu.evm.operation.ReturnOperation;
import org.hyperledger.besu.evm.operation.RevertOperation;
import java.util.ArrayDeque;
import java.util.ArrayList;
@ -530,11 +532,19 @@ public class FlatTraceGenerator {
private static boolean hasRevertInSubCall(
final TransactionTrace transactionTrace, final TraceFrame callFrame) {
return transactionTrace.getTraceFrames().stream()
.filter(traceFrame -> !traceFrame.equals(callFrame))
.takeWhile(traceFrame -> !traceFrame.getOpcode().equals("RETURN"))
.filter(traceFrame -> traceFrame.getOpcode().equals("REVERT"))
.anyMatch(traceFrame -> traceFrame.getDepth() == callFrame.getDepth());
for (int i = 0; i < transactionTrace.getTraceFrames().size(); i++) {
if (i + 1 < transactionTrace.getTraceFrames().size()) {
final TraceFrame next = transactionTrace.getTraceFrames().get(i + 1);
if (next.getDepth() == callFrame.getDepth()) {
if (next.getOpcodeNumber() == RevertOperation.OPCODE) {
return true;
} else if (next.getOpcodeNumber() == ReturnOperation.OPCODE) {
return false;
}
}
}
}
return false;
}
private static String calculateCallingAddress(final FlatTrace.Context lastContext) {

@ -91,6 +91,7 @@ public class DebugTraceBlockByHashTest {
new TraceFrame(
12,
Optional.of("NONE"),
Integer.MAX_VALUE,
45L,
OptionalLong.of(56L),
0L,

@ -77,6 +77,7 @@ public class DebugTraceBlockByNumberTest {
new TraceFrame(
12,
Optional.of("NONE"),
Integer.MAX_VALUE,
45L,
OptionalLong.of(56L),
0L,

@ -83,6 +83,7 @@ public class DebugTraceBlockTest {
new TraceFrame(
12,
Optional.of("NONE"),
Integer.MAX_VALUE,
45L,
OptionalLong.of(56L),
0L,

@ -116,6 +116,7 @@ public class DebugTraceTransactionTest {
new TraceFrame(
12,
Optional.of("NONE"),
Integer.MAX_VALUE,
45L,
OptionalLong.of(56L),
0L,
@ -183,6 +184,7 @@ public class DebugTraceTransactionTest {
new TraceFrame(
12,
Optional.of("NONE"),
Integer.MAX_VALUE,
45L,
OptionalLong.of(56L),
0L,

@ -34,6 +34,7 @@ public class TraceFrame {
private final int pc;
private final Optional<String> opcode;
private final int opcodeNumber;
private final long gasRemaining;
private final OptionalLong gasCost;
private final long gasRefund;
@ -63,6 +64,7 @@ public class TraceFrame {
public TraceFrame(
final int pc,
final Optional<String> opcode,
final int opcodeNumber,
final long gasRemaining,
final OptionalLong gasCost,
final long gasRefund,
@ -86,6 +88,7 @@ public class TraceFrame {
final Optional<StorageEntry> maybeUpdatedStorage) {
this.pc = pc;
this.opcode = opcode;
this.opcodeNumber = opcodeNumber;
this.gasRemaining = gasRemaining;
this.gasCost = gasCost;
this.gasRefund = gasRefund;
@ -118,6 +121,10 @@ public class TraceFrame {
return opcode.orElse("");
}
public int getOpcodeNumber() {
return opcodeNumber;
}
public long getGasRemaining() {
return gasRemaining;
}

@ -84,6 +84,7 @@ public class DebugOperationTracer implements OperationTracer {
public void tracePostExecution(final MessageFrame frame, final OperationResult operationResult) {
final Operation currentOperation = frame.getCurrentOperation();
final String opcode = currentOperation.getName();
final int opcodeNumber = (opcode != null) ? currentOperation.getOpcode() : Integer.MAX_VALUE;
final WorldUpdater worldUpdater = frame.getWorldUpdater();
final Bytes outputData = frame.getOutputData();
final Optional<Bytes[]> memory = captureMemory(frame);
@ -103,6 +104,7 @@ public class DebugOperationTracer implements OperationTracer {
new TraceFrame(
pc,
Optional.of(opcode),
opcodeNumber,
gasRemaining,
thisGasCost == 0 ? OptionalLong.empty() : OptionalLong.of(thisGasCost),
frame.getGasRefund(),
@ -136,6 +138,7 @@ public class DebugOperationTracer implements OperationTracer {
new TraceFrame(
frame.getPC(),
Optional.empty(),
Integer.MAX_VALUE,
frame.getRemainingGas(),
OptionalLong.empty(),
frame.getGasRefund(),
@ -182,6 +185,7 @@ public class DebugOperationTracer implements OperationTracer {
new TraceFrame(
frame.getPC(),
Optional.empty(),
Integer.MAX_VALUE,
frame.getRemainingGas(),
OptionalLong.empty(),
frame.getGasRefund(),

@ -24,13 +24,16 @@ import org.hyperledger.besu.evm.gascalculator.GasCalculator;
/** The Return operation. */
public class ReturnOperation extends AbstractOperation {
/** RETURN opcode number */
public static final int OPCODE = 0xF3;
/**
* Instantiates a new Return operation.
*
* @param gasCalculator the gas calculator
*/
public ReturnOperation(final GasCalculator gasCalculator) {
super(0xF3, "RETURN", 2, 0, gasCalculator);
super(OPCODE, "RETURN", 2, 0, gasCalculator);
}
@Override

@ -26,13 +26,16 @@ import org.apache.tuweni.bytes.Bytes;
/** The Revert operation. */
public class RevertOperation extends AbstractOperation {
/** REVERT opcode number */
public static final int OPCODE = 0xFD;
/**
* Instantiates a new Revert operation.
*
* @param gasCalculator the gas calculator
*/
public RevertOperation(final GasCalculator gasCalculator) {
super(0xFD, "REVERT", 2, 0, gasCalculator);
super(OPCODE, "REVERT", 2, 0, gasCalculator);
}
@Override

Loading…
Cancel
Save