From 2a4a342eabf1381538d0300c4a9a97a201a0e804 Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Fri, 3 Apr 2026 10:05:30 +0530 Subject: [PATCH 01/10] feat(debug): add limit param to stop trace capture after N steps Signed-off-by: Sagar Khandagre --- .../parameters/TransactionTraceParams.java | 6 +++++ .../ethereum/vm/DebugOperationTracer.java | 4 +++ .../tracing/OpCodeTracerConfigBuilder.java | 26 ++++++++++++++++--- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java index 5ebad5d8c47..c3a7c2ece04 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java @@ -69,6 +69,9 @@ default boolean disableStack() { return Boolean.TRUE.equals(disableStackNullable()); } + @JsonProperty(value = "limit") + @Nullable Integer limit(); + @JsonProperty("tracer") @JsonInclude(JsonInclude.Include.NON_NULL) @Nullable String tracer(); @@ -122,6 +125,9 @@ default TraceOptions traceOptions() { if (disableStackNullable() != null) { builder.traceStack(!disableStack()); } + if (limit() != null) { + builder.limit(limit()); + } var opCodeTracerConfig = builder.traceOpcodes(opcodes()).build(); return new TraceOptions(tracerType, opCodeTracerConfig, tracerConfig(), stateOverrides()); diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java index 04f1952645b..3cbb10903f7 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java @@ -57,6 +57,10 @@ public DebugOperationTracer(final OpCodeTracerConfig options, final boolean reco @Override protected void capturePreExecutionState(final MessageFrame frame) { + if (options.limit() > 0 && traceFrames.size() >= options.limit()) { + traceOpcode = false; + return; + } if (lastFrame != null && frame.getDepth() > lastFrame.getDepth()) inputData = frame.getInputData().copy(); else inputData = frame.getInputData(); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java index 9ba3f633231..6a9dcdadd4d 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java @@ -27,6 +27,7 @@ public final class OpCodeTracerConfigBuilder { private boolean traceReturnData; private Set traceOpcodes; private boolean eip3155Strict; + private int limit; /** * Create an OpcodeTracerConfig builder from a previous built config. @@ -57,6 +58,7 @@ private OpCodeTracerConfigBuilder(final OpCodeTracerConfig opCodeTracerConfig) { this.traceReturnData = opCodeTracerConfig.traceReturnData(); this.traceOpcodes = opCodeTracerConfig.traceOpcodes(); this.eip3155Strict = opCodeTracerConfig.eip3155Strict(); + this.limit = opCodeTracerConfig.limit(); } /** @@ -113,6 +115,16 @@ public OpCodeTracerConfigBuilder traceOpcodes(final Set traceOpcodes) { this.traceOpcodes = traceOpcodes.stream().map(String::toLowerCase).collect(Collectors.toSet()); return this; } + /** + * Set the maximum number of steps to trace. Zero means unlimited. + * + * @param n maximum number of steps, or 0 for unlimited + * @return the current builder + */ + public OpCodeTracerConfigBuilder limit(final int n) { + limit = n; + return this; + } /** * Set eip3155Strict flag. @@ -132,7 +144,7 @@ public OpCodeTracerConfigBuilder eip3155Strict(final boolean enable) { */ public OpCodeTracerConfig build() { return new Config( - traceStorage, traceMemory, traceStack, traceReturnData, traceOpcodes, eip3155Strict); + traceStorage, traceMemory, traceStack, traceReturnData, traceOpcodes, eip3155Strict, limit); } /** @@ -144,7 +156,7 @@ public OpCodeTracerConfig build() { public sealed interface OpCodeTracerConfig permits Config { /** static default OpcodeTracerConfig which can be accessed externally */ OpCodeTracerConfig DEFAULT = - new Config(true, false, true, false, Collections.emptySet(), false); + new Config(true, false, true, false, Collections.emptySet(), false, 0); /** * Check if tracing of storage is enabled. @@ -188,6 +200,13 @@ public sealed interface OpCodeTracerConfig permits Config { * @return true if enabled, false otherwise */ boolean eip3155Strict(); + + /** + * Maximum number of steps to trace. Zero means unlimited. + * + * @return the step limit, or 0 for unlimited + */ + int limit(); } private record Config( @@ -196,6 +215,7 @@ private record Config( boolean traceStack, boolean traceReturnData, Set traceOpcodes, - boolean eip3155Strict) + boolean eip3155Strict, + int limit) implements OpCodeTracerConfig {} } From b384d7a9478748100a1350a785f5a6e2c83a0baf Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Fri, 3 Apr 2026 10:15:48 +0530 Subject: [PATCH 02/10] fix(debug): use dedicated stepCount for limit and fix last-frame gasRemainingPostExecution Signed-off-by: Sagar Khandagre --- .../besu/ethereum/vm/DebugOperationTracer.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java index 3cbb10903f7..5b2fcfbbe8b 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java @@ -43,6 +43,7 @@ public class DebugOperationTracer extends AbstractDebugOperationTracer { private TraceFrame lastFrame; private Bytes inputData; + private int stepCount; /** * Creates the operation tracer. @@ -57,10 +58,11 @@ public DebugOperationTracer(final OpCodeTracerConfig options, final boolean reco @Override protected void capturePreExecutionState(final MessageFrame frame) { - if (options.limit() > 0 && traceFrames.size() >= options.limit()) { + if (options.limit() > 0 && stepCount >= options.limit()) { traceOpcode = false; return; } + stepCount++; if (lastFrame != null && frame.getDepth() > lastFrame.getDepth()) inputData = frame.getInputData().copy(); else inputData = frame.getInputData(); @@ -68,9 +70,6 @@ protected void capturePreExecutionState(final MessageFrame frame) { @Override public void tracePostExecution(final MessageFrame frame, final OperationResult operationResult) { - if (!traceOpcode) { - return; - } final Operation currentOperation = frame.getCurrentOperation(); final String opcode = currentOperation.getName(); final int opcodeNumber = (opcode != null) ? currentOperation.getOpcode() : Integer.MAX_VALUE; @@ -93,6 +92,9 @@ public void tracePostExecution(final MessageFrame frame, final OperationResult o TraceFrame.from(lastTraceFrame).setGasRemainingPostExecution(gasRemaining).build(); traceFrames.add(updatedLast); } + if (!traceOpcode) { + return; + } final Optional> storage = captureStorage(frame); final Optional> maybeRefunds = @@ -279,6 +281,7 @@ public List getTraceFrames() { public void reset() { traceFrames = new ArrayList<>(); lastFrame = null; + stepCount = 0; } public List copyTraceFrames() { From cd3e31f35cc1863c2545f0bc7300b7ce99666320 Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Fri, 3 Apr 2026 10:20:03 +0530 Subject: [PATCH 03/10] test(debug): add unit tests for limit frame capture and gasRemainingPostExecution backfill Signed-off-by: Sagar Khandagre --- .../ethereum/vm/DebugOperationTracerTest.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index 5df6f63c993..4d821810b83 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -417,6 +417,44 @@ void shouldHandleCallScenarioAndDepthChange() { .isEqualTo(WORD_1); } + @Test + void shouldCaptureAtMostLimitFrames() { + final OpCodeTracerConfig config = + OpCodeTracerConfigBuilder.createFrom(OpCodeTracerConfig.DEFAULT) + .traceStorage(false) + .traceMemory(false) + .traceStack(false) + .limit(2) + .build(); + final DebugOperationTracer tracer = new DebugOperationTracer(config, false); + final MessageFrame frame = validMessageFrame(); + + for (int i = 0; i < 5; i++) { + traceFrame(frame, tracer, anOperation); + } + + assertThat(tracer.getTraceFrames()).hasSize(2); + } + + @Test + void shouldBackfillGasRemainingPostExecutionOnLastCapturedFrameAtLimit() { + final OpCodeTracerConfig config = + OpCodeTracerConfigBuilder.createFrom(OpCodeTracerConfig.DEFAULT) + .traceStorage(false) + .traceMemory(false) + .traceStack(false) + .limit(1) + .build(); + final DebugOperationTracer tracer = new DebugOperationTracer(config, false); + final MessageFrame frame = validMessageFrame(); + + traceFrame(frame, tracer, anOperation); + traceFrame(frame, tracer, anOperation); + + assertThat(tracer.getTraceFrames()).hasSize(1); + assertThat(tracer.getTraceFrames().get(0).getGasRemainingPostExecution()).isGreaterThan(0); + } + private TraceFrame traceFrame(final MessageFrame frame) { return traceFrame( frame, From 9b540f93a587a07794f5f93295dba0deba8132d4 Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Sat, 11 Apr 2026 18:59:02 +0530 Subject: [PATCH 04/10] reject negative values at builder layer and rpc boundary Signed-off-by: Sagar Khandagre --- .../api/jsonrpc/internal/parameters/TransactionTraceParams.java | 1 + .../hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java | 1 + 2 files changed, 2 insertions(+) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java index c3a7c2ece04..37379e3f7f1 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java @@ -126,6 +126,7 @@ default TraceOptions traceOptions() { builder.traceStack(!disableStack()); } if (limit() != null) { + if (limit() < 0) throw new IllegalArgumentException("limit must be >= 0, got: " + limit()); builder.limit(limit()); } var opCodeTracerConfig = builder.traceOpcodes(opcodes()).build(); diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java index 6a9dcdadd4d..4c838ed6ad8 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java @@ -122,6 +122,7 @@ public OpCodeTracerConfigBuilder traceOpcodes(final Set traceOpcodes) { * @return the current builder */ public OpCodeTracerConfigBuilder limit(final int n) { + if (n < 0) throw new IllegalArgumentException("limit must be >= 0, got: " + n); limit = n; return this; } From 30fc4ebd267a9c895119c1de33e5be829cff688c Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Sat, 11 Apr 2026 19:12:32 +0530 Subject: [PATCH 05/10] test(debug): add test for limit=0 treating zero as unlimited Verifies that limit(0) captures all EVM steps without capping, per the spec contract that 0 means unlimited. Without this test a regression flipping the guard from to would pass all other limit tests undetected. Signed-off-by: Sagar Khandagre --- .../ethereum/vm/DebugOperationTracerTest.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index 4d821810b83..686856b9bcf 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -455,6 +455,25 @@ void shouldBackfillGasRemainingPostExecutionOnLastCapturedFrameAtLimit() { assertThat(tracer.getTraceFrames().get(0).getGasRemainingPostExecution()).isGreaterThan(0); } + @Test + void shouldCaptureAllFramesWhenLimitIsZero() { + final OpCodeTracerConfig config = + OpCodeTracerConfigBuilder.createFrom(OpCodeTracerConfig.DEFAULT) + .traceStorage(false) + .traceMemory(false) + .traceStack(false) + .limit(0) + .build(); + final DebugOperationTracer tracer = new DebugOperationTracer(config, false); + final MessageFrame frame = validMessageFrame(); + + for (int i = 0; i < 5; i++) { + traceFrame(frame, tracer, anOperation); + } + + assertThat(tracer.getTraceFrames()).hasSize(5); + } + private TraceFrame traceFrame(final MessageFrame frame) { return traceFrame( frame, From a2c16b034553b1fd4ec36f59fc5e79b530cbc985 Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Tue, 21 Apr 2026 17:55:23 +0530 Subject: [PATCH 06/10] apply sptoless Signed-off-by: Sagar Khandagre --- .../hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java | 1 + 1 file changed, 1 insertion(+) diff --git a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java index 4c838ed6ad8..3623239a32a 100644 --- a/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java +++ b/evm/src/main/java/org/hyperledger/besu/evm/tracing/OpCodeTracerConfigBuilder.java @@ -115,6 +115,7 @@ public OpCodeTracerConfigBuilder traceOpcodes(final Set traceOpcodes) { this.traceOpcodes = traceOpcodes.stream().map(String::toLowerCase).collect(Collectors.toSet()); return this; } + /** * Set the maximum number of steps to trace. Zero means unlimited. * From af9eccbff9c9edf74b48cd8ffca6e307bc9c2ef5 Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Thu, 30 Apr 2026 10:31:47 +0530 Subject: [PATCH 07/10] changing validation to deserialization layer Signed-off-by: Sagar Khandagre --- .../internal/parameters/TransactionTraceParams.java | 8 +++++++- .../internal/parameters/TransactionTraceParamsTest.java | 7 +++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java index 37379e3f7f1..3f5bb4ec6ac 100644 --- a/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java +++ b/ethereum/api/src/main/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParams.java @@ -96,6 +96,13 @@ default Set opcodes() { @JsonInclude(JsonInclude.Include.NON_NULL) StateOverrideMap stateOverrides(); + @Value.Check + default void validate() { + if (limit() != null && limit() < 0) { + throw new IllegalArgumentException("limit must be >= 0, got: " + limit()); + } + } + /** * Convert JSON-RPC parameters to a {@link TraceOptions} object. * @@ -126,7 +133,6 @@ default TraceOptions traceOptions() { builder.traceStack(!disableStack()); } if (limit() != null) { - if (limit() < 0) throw new IllegalArgumentException("limit must be >= 0, got: " + limit()); builder.limit(limit()); } var opCodeTracerConfig = builder.traceOpcodes(opcodes()).build(); diff --git a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParamsTest.java b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParamsTest.java index 2775789627b..eaee3ce96c9 100644 --- a/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParamsTest.java +++ b/ethereum/api/src/test/java/org/hyperledger/besu/ethereum/api/jsonrpc/internal/parameters/TransactionTraceParamsTest.java @@ -15,6 +15,7 @@ package org.hyperledger.besu.ethereum.api.jsonrpc.internal.parameters; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import org.hyperledger.besu.ethereum.debug.TraceOptions; import org.hyperledger.besu.evm.tracing.OpCodeTracerConfigBuilder.OpCodeTracerConfig; @@ -131,4 +132,10 @@ public void nonOpcodeTracerShouldRespectExplicitEnableMemoryFalse() throws Excep .describedAs("explicit enableMemory=false should be respected for callTracer") .isFalse(); } + + @Test + public void negativeLimitShouldFailDuringDeserialization() { + assertThatThrownBy(() -> MAPPER.readValue("{\"limit\": -1}", TransactionTraceParams.class)) + .hasMessageContaining("limit must be >= 0, got: -1"); + } } From 7b73cb8610c8a91c357c861c8c4ff3701300d23f Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Thu, 30 Apr 2026 10:37:52 +0530 Subject: [PATCH 08/10] Updated assertion in DebugOperationTracerTest to avoid assuming gas is positive. Signed-off-by: Sagar Khandagre --- .../hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java index 686856b9bcf..024744abbbd 100644 --- a/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java +++ b/ethereum/core/src/test/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracerTest.java @@ -452,7 +452,8 @@ void shouldBackfillGasRemainingPostExecutionOnLastCapturedFrameAtLimit() { traceFrame(frame, tracer, anOperation); assertThat(tracer.getTraceFrames()).hasSize(1); - assertThat(tracer.getTraceFrames().get(0).getGasRemainingPostExecution()).isGreaterThan(0); + assertThat(tracer.getTraceFrames().get(0).getGasRemainingPostExecution()) + .isNotEqualTo(OptionalLong.empty()); } @Test From b82efa1dda92b0fc66da3bacd06f4dd5004d430b Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Thu, 30 Apr 2026 10:50:53 +0530 Subject: [PATCH 09/10] refactor(debug): decouple trace limit state from opcode filter flag Introduce a dedicated limitReached flag in DebugOperationTracer for step-limit handling. Stop mutating traceOpcode for limit enforcement; keep it only for opcode-filter semantics. Preserve existing behavior: no new frames after limit, while backfill path still runs correctly. Improve readability and reduce surprise/maintenance risk called out in review. Signed-off-by: Sagar Khandagre --- .../hyperledger/besu/ethereum/vm/DebugOperationTracer.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java index 5b2fcfbbe8b..c35e8fc2a17 100644 --- a/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java +++ b/ethereum/core/src/main/java/org/hyperledger/besu/ethereum/vm/DebugOperationTracer.java @@ -44,6 +44,7 @@ public class DebugOperationTracer extends AbstractDebugOperationTracer { private Bytes inputData; private int stepCount; + private boolean limitReached; /** * Creates the operation tracer. @@ -59,9 +60,10 @@ public DebugOperationTracer(final OpCodeTracerConfig options, final boolean reco @Override protected void capturePreExecutionState(final MessageFrame frame) { if (options.limit() > 0 && stepCount >= options.limit()) { - traceOpcode = false; + limitReached = true; return; } + limitReached = false; stepCount++; if (lastFrame != null && frame.getDepth() > lastFrame.getDepth()) inputData = frame.getInputData().copy(); @@ -92,7 +94,7 @@ public void tracePostExecution(final MessageFrame frame, final OperationResult o TraceFrame.from(lastTraceFrame).setGasRemainingPostExecution(gasRemaining).build(); traceFrames.add(updatedLast); } - if (!traceOpcode) { + if (limitReached || !traceOpcode) { return; } @@ -282,6 +284,7 @@ public void reset() { traceFrames = new ArrayList<>(); lastFrame = null; stepCount = 0; + limitReached = false; } public List copyTraceFrames() { From 96843cb1e65e10e875930a947c692bc7dd2a79e7 Mon Sep 17 00:00:00 2001 From: Sagar Khandagre Date: Fri, 1 May 2026 09:33:36 +0530 Subject: [PATCH 10/10] adding changlog Signed-off-by: Sagar Khandagre --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f03302503f..ef1121b0fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -47,6 +47,7 @@ - Enforce EIP-7928 Block Access List item budget per transaction in both processing and mining [#10250](https://github.com/besu-eth/besu/pull/10250) - Include `slotNumber` in `payloadIdentifier` generation [#10242](https://github.com/besu-eth/besu/pull/10242) - Change Block Access List index encoding to `uint32` [#10279](https://github.com/besu-eth/besu/pull/10279) +- Add `limit` support to debug opcode tracing to stop capture after N EVM steps (`0` keeps the previous unlimited behavior) and reject negative values at the RPC parameter boundary [#10173](https://github.com/besu-eth/besu/pull/10173) ### Plugin API - Publish Guava as an API dependency from `plugin-api` [#10248](https://github.com/besu-eth/besu/pull/10248)