Repository navigation
Fix debug_traceTransaction "used gas mismatch" for txs at index > 0 - #999
Conversation
The replay loop was passing the trace target's receipt into every BlockExecutor.Run() call. BlockExecutor.Run compares res.GasConsumed to receipt.GasUsed and errors out on mismatch, so any trace of a tx at block index > 0 failed with "used gas mismatch, expected: <target gas>, got: <tx #0 gas>" for every tracer except callTracer (whose hook path happens to produce a GasConsumed value that satisfies the check). Load the block's receipts once up front, key them by tx hash, and look up the correct receipt per tx in the loop — matching what traceBlockByNumber already does. Fixes #998 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough
ChangesTransaction tracing
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix · Severity of issue fixed: Medium Suggested reviewers: Merge Risk: ⚪ Minimal · up to The change corrects receipt selection when tracing later transactions and adds targeted regression coverage. No actionable merge-blocking risk remains; normal test checks should complete before merging. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The fix preserves the existing request gate and isolates replay state while correcting receipt selection. No introduced security flaw was established. Additional receipt processing and unverified resource and consistency limits leave limited uncertainty. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Verified against FF testnet and mainnet gatewaysRan the fix (tagged Testnet (
|
| Tracer | Before (v1.5.8-rc.1) |
After (v1.5.9-rc.1) |
|---|---|---|
| default (struct logger) | ❌ used gas mismatch, expected: 21000, got: 21055 |
✅ gas: 21000, failed: false |
prestateTracer |
❌ same error | ✅ returns prestate map |
4byteTracer |
❌ same error | ✅ {} (value transfer, no dispatch) |
callTracer |
❌ same error | ✅ type=CALL, gasUsed=0x5208 |
| default on index-0 (control) | ✅ opcode trace | ✅ opcode trace (unchanged) |
Mainnet (evm-001.mainnet0.nodes.onflow.org:8000)
Repro target: the original externally-reported tx 0xcab2ef27617a8845f958792b2fc88b09cb87cc7c8dd5163a68ff9beb9b5ff5b7 (block 0x4c2d74f, index 10, gasUsed = 3,056,754, CREATE).
| Tracer | Before (v1.5.8-rc.2) |
After (v1.5.9-rc.1) |
|---|---|---|
| default (struct logger) | ❌ used gas mismatch, expected: 3056754, got: 36747 |
✅ gas: 3056754, failed: false + full structLogs |
prestateTracer |
❌ same error | ✅ sender nonce=148, balance=0x4e72fff6b14c50400; coinbase prestate also returned |
4byteTracer |
❌ same error | ✅ {} (CREATE, no 4-byte dispatch) |
callTracer |
❌ same error | ✅ type=CREATE, gasUsed=0x2ea472 (3,056,754), created contract 0x69d8cf3570def8cdf7d14ff041b2f4febf030905 |
muxTracer (nesting callTracer) |
❌ same error | ✅ nested callTracer result returned |
All reconcile against the on-chain receipt (gasUsed, nonce, created address). Fix verified end-to-end.
Side observation
On the FF public mainnet gateway (mainnet.evm.nodes.onflow.org, still on v1.5.7), callTracer on this same tx accidentally dodged the bug and returned a correct trace before the fix was deployed anywhere. On the FF internal mainnet node and on testnet, every tracer (including callTracer) failed uniformly. That difference is consistent with slight register-store state divergence between the two FF mainnet nodes shifting the GasConsumed reading past the (incorrect) comparison on one but not the other. Worth flagging that the public gateway should also be upgraded off v1.5.7 once this is merged.
Closes: #998
Description
debug_traceTransactionhas been returning-32000 "used gas mismatch, expected: <X>, got: <Y>"for any transaction whose index inside its block is greater than 0, unless the request usescallTracer. The failure reproduces against every recent gateway release (verified back to v1.5.7) with the default struct logger,prestateTracer,4byteTracer,muxTracer, and other non-callTracertracers.Root cause
traceTransactionloads the target's receipt once, then callsBlockExecutor.Run(tx, receipt, txTracer)for every preceding transaction in the block to warm up state — passing the target's receipt to each call.BlockExecutor.Run(services/evm/executor.go:98) comparesres.GasConsumedtoreceipt.GasUsedand returns an error on mismatch, so the loop always failed on the first preceding tx. The error'sgotvalue equals the gasUsed of tx #0 in the block,expectedequals the target's gasUsed.callTracer's hook path through flow-go's emulator incidentally produces aGasConsumedreading that happens to satisfy the (incorrect) check, which is why that one tracer worked.The sibling helper
traceBlockByNumberin the same file already does this correctly — it fetchesd.receipts.GetByBlockHeight(block.Height)and pairs each tx with its own receipt. This PR applies the same pattern totraceTransaction.Changes
api/debug.go: loadd.receipts.GetByBlockHeight(block.Height)once, build atxHash → receiptmap, pass the correct per-tx receipt into eachBlockExecutor.Run()call.tests/web3js/debug_traces_test.js: regression test that traces the coinbase fee-transfer tx (at index 1 of its block) with the default (nil) tracer and expects success. Fails on main, passes with this change.Files most critical to review
api/debug.go:293-343— the replay loop intraceTransaction.For contributor use:
mainbranchFiles changedin the Github PR explorer🤖 Generated with Claude Code
Summary by CodeRabbit