feat(l1): implement noopTracer for debug trace endpoints#6694
feat(l1): implement noopTracer for debug trace endpoints#6694azteca1998 wants to merge 5 commits into
Conversation
Add noopTracer variant that returns an empty JSON object {} per
transaction. Useful for benchmarking execution overhead without
tracing cost. Supported in both debug_traceTransaction and
debug_traceBlockByNumber.
Part of #6572
|
🤖 Kimi Code ReviewThe PR adds a crates/networking/rpc/tracing.rs
Security & Correctness
Verdict Automated review by Kimi (Moonshot AI) · kimi-k2.5 · custom prompt |
🤖 Codex Code Review
I didn’t find other issues in the small diff, but this one is significant enough that I would not merge as-is. There’s also no coverage for the new tracer path, so once the replay semantics are fixed, add RPC tests for success and failure cases. Automated review by OpenAI Codex · gpt-5.4 · custom prompt |
🤖 Claude Code ReviewHere is the review: PR Review:
|
Lines of code reportTotal lines added: Detailed view |
Greptile SummaryThis PR adds a
Confidence Score: 3/5The debug_traceTransaction arm of noopTracer returns {} for any hash — real, fake, or zeroed — because no transaction lookup is performed before responding. The NoopTracer path in TraceTransactionRequest skips the transaction existence check that every other tracer performs, so a caller can pass a fabricated hash and receive a successful {} response. crates/networking/rpc/tracing.rs — specifically the NoopTracer arm inside TraceTransactionRequest::handle
|
| Filename | Overview |
|---|---|
| crates/networking/rpc/tracing.rs | Adds NoopTracer variant that returns empty JSON objects without re-executing transactions; the traceTransaction arm lacks any tx-existence check, and the overall behaviour diverges from geth's noopTracer which still runs the EVM. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[RPC Request] --> B{Endpoint}
B --> C[debug_traceTransaction]
B --> D[debug_traceBlockByNumber]
C --> E{TracerType}
E -->|callTracer / prestateTracer / opcodeTracer| F[Validate tx hash, re-execute via EVM, return trace]
E -->|noopTracer| G[Return empty object - NO tx validation, NO execution]
D --> H[Resolve and fetch block - existence validated]
H --> I{TracerType}
I -->|callTracer / prestateTracer / opcodeTracer| J[Re-execute all txs via EVM, return per-tx trace]
I -->|noopTracer| K[Map tx hashes to empty objects - NO execution]
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
crates/networking/rpc/tracing.rs:216
**Missing transaction existence validation**
For every other tracer, the handler calls a blockchain method that validates the transaction hash is real and returns an error if it is not found. The `NoopTracer` arm skips execution entirely, so calling `debug_traceTransaction` with a non-existent or fabricated hash returns `{}` with status 200 instead of an appropriate error. Clients that probe for transaction existence via this endpoint will silently receive a success response and may incorrectly assume the transaction was traced.
### Issue 2 of 2
crates/networking/rpc/tracing.rs:363-377
**Behavioral divergence from geth's noopTracer**
The PR description states this matches geth's `noopTracer`, but geth still re-executes transactions through the EVM with all hook methods implemented as no-ops — the empty result is a consequence of no tracing being recorded, not of skipping execution. This implementation skips execution entirely, so it cannot be used for its stated purpose of "benchmarking raw execution overhead without tracing cost".
Reviews (1): Last reviewed commit: "feat(l1): implement noopTracer for debug..." | Re-trigger Greptile
| emit, | ||
| })?) | ||
| } | ||
| TracerType::NoopTracer => Ok(serde_json::json!({})), |
There was a problem hiding this comment.
Missing transaction existence validation
For every other tracer, the handler calls a blockchain method that validates the transaction hash is real and returns an error if it is not found. The NoopTracer arm skips execution entirely, so calling debug_traceTransaction with a non-existent or fabricated hash returns {} with status 200 instead of an appropriate error. Clients that probe for transaction existence via this endpoint will silently receive a success response and may incorrectly assume the transaction was traced.
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/networking/rpc/tracing.rs
Line: 216
Comment:
**Missing transaction existence validation**
For every other tracer, the handler calls a blockchain method that validates the transaction hash is real and returns an error if it is not found. The `NoopTracer` arm skips execution entirely, so calling `debug_traceTransaction` with a non-existent or fabricated hash returns `{}` with status 200 instead of an appropriate error. Clients that probe for transaction existence via this endpoint will silently receive a success response and may incorrectly assume the transaction was traced.
How can I resolve this? If you propose a fix, please make it concise.| TracerType::NoopTracer => { | ||
| // Return one empty object per transaction in the block, matching | ||
| // geth's behaviour where noopTracer produces {} for each tx. | ||
| let tx_hashes: Vec<H256> = block | ||
| .body | ||
| .transactions | ||
| .iter() | ||
| .map(|tx| tx.hash()) | ||
| .collect(); | ||
| let block_trace: BlockTrace<Value> = tx_hashes | ||
| .into_iter() | ||
| .map(|hash| (hash, serde_json::json!({})).into()) | ||
| .collect(); | ||
| Ok(serde_json::to_value(block_trace)?) | ||
| } |
There was a problem hiding this comment.
Behavioral divergence from geth's noopTracer
The PR description states this matches geth's noopTracer, but geth still re-executes transactions through the EVM with all hook methods implemented as no-ops — the empty result is a consequence of no tracing being recorded, not of skipping execution. This implementation skips execution entirely, so it cannot be used for its stated purpose of "benchmarking raw execution overhead without tracing cost".
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/networking/rpc/tracing.rs
Line: 363-377
Comment:
**Behavioral divergence from geth's noopTracer**
The PR description states this matches geth's `noopTracer`, but geth still re-executes transactions through the EVM with all hook methods implemented as no-ops — the empty result is a consequence of no tracing being recorded, not of skipping execution. This implementation skips execution entirely, so it cannot be used for its stated purpose of "benchmarking raw execution overhead without tracing cost".
How can I resolve this? If you propose a fix, please make it concise.Trace a real executed transaction with noopTracer and assert the response is an empty JSON object.
noopTracer was returning {} without validating that the transaction
exists or re-executing it. This diverged from geth, which still runs
the EVM with no-op hooks. Now we call trace_transaction_calls /
trace_block_calls and discard the results, matching geth semantics
and properly erroring on invalid tx hashes.
Summary
noopTracervariant to the tracer type enum{}fordebug_traceTransaction, and{txHash, result: {}}per tx fordebug_traceBlockByNumberCloses part of #6572
Test plan
debug_traceTransactionwith{"tracer": "noopTracer"}returns{}debug_traceBlockByNumberwith{"tracer": "noopTracer"}returns array of{txHash, result: {}}