Skip to content

evmrpc: use BlockID.Hash in GetTransaction (CON-257)#3350

Merged
wen-coding merged 1 commit into
mainfrom
wen/fix_get_transaction_block_hash_for_autobahn
May 1, 2026
Merged

evmrpc: use BlockID.Hash in GetTransaction (CON-257)#3350
wen-coding merged 1 commit into
mainfrom
wen/fix_get_transaction_block_hash_for_autobahn

Conversation

@wen-coding

@wen-coding wen-coding commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Summary

Backend.GetTransaction returned the eth blockHash by recomputing block.Block.Header.Hash(). That's value-equivalent to BlockID.Hash under CometBFT (full Header populated by the BlockStore), but wrong under AutobahnGigaRouter.translateGlobalBlock returns a ResultBlock with only ChainID/Height/Time on the Header, so Header.Hash() recomputes a Merkle root that doesn't match any stored value.

Downstream symptom

go-ethereum's tracers.API.TraceTransaction calls backend.GetTransaction(hash), then runs blockByNumberAndHash(num, blockHash). When that helper sees block.Hash() != blockHash, it falls back to BlockByHash(blockHash) — which under Autobahn returns ErrBlockNotFoundByHash because the recomputed sparse-header hash isn't indexed anywhere. debug_traceTransaction surfaces "block not found by hash" instead of a real trace.

Fix

Read blockHash from block.BlockID.Hash. That's the actual block hash the EVM receipt store recorded during FinalizeBlock:

  • CometBFT: equal to Header.Hash() — value-equivalent substitution
  • Autobahn: the real Autobahn block hash that downstream consumers (BlockByHash, EVM receipts) already use

Verification

  • go test ./evmrpc/... — 4 packages green (incl. new test, fails without fix)
  • Live debug_traceTransaction on a 4-node Autobahn cluster now returns proper traces with callTracer / prestateTracer / prestateTracer-diffMode (previously: block not found by hash)

🤖 Generated with Claude Code

GetTransaction returned the eth blockHash by recomputing
block.Block.Header.Hash() from the tendermint Block returned by
/block. That works under CometBFT because Header is fully populated
and Header.Hash() == BlockID.Hash, but breaks under Autobahn where
the Block returned by GigaRouter.BlockByNumber has only ChainID /
Height / Time set on the Header — Header.Hash() then computes a
Merkle root that doesn't match anything stored anywhere.

The downstream effect: go-ethereum's tracers.API.TraceTransaction
calls backend.GetTransaction, then blockByNumberAndHash(num, hash).
That helper falls back to BlockByHash when the freshly-fetched
block's hash doesn't equal `hash` — and BlockByHash returns
ErrBlockNotFoundByHash because the recomputed sparse-header hash
isn't indexed. debug_traceTransaction surfaces "block not found
by hash" instead of a real trace.

Fix: read blockHash from block.BlockID.Hash, which is the actual
block hash the EVM receipt store recorded during FinalizeBlock —
identical to Header.Hash() under CometBFT, correct under Autobahn.

Test: TestGetTransactionUsesBlockIDHash with two subtests, each
asserting both the fixture invariant (Header.Hash() == BlockID.Hash
under CometBFT, != under Autobahn) and the contract (GetTransaction
returns BlockID.Hash). The Autobahn subtest fails on the original
code; the CometBFT subtest pins the fixture so a future Autobahn
shape that accidentally matches Header.Hash() can't pass without
being noticed.

Verified live: debug_traceTransaction now returns proper traces with
callTracer / prestateTracer / prestateTracer-diffMode against a
4-node Autobahn cluster (and continues to work under CometBFT —
evmrpc tests all green).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@wen-coding wen-coding changed the title evmrpc: use BlockID.Hash in GetTransaction (autobahn-safe) evmrpc: use BlockID.Hash in GetTransaction (CON-257) Apr 30, 2026
@github-actions

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedApr 30, 2026, 10:08 PM

@github-actions

Copy link
Copy Markdown

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedApr 30, 2026, 10:08 PM

@codecov

codecov Bot commented Apr 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 59.17%. Comparing base (c659ff4) to head (2dc87d7).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #3350   +/-   ##
=======================================
  Coverage   59.17%   59.17%           
=======================================
  Files        2097     2097           
  Lines      172509   172509           
=======================================
  Hits       102079   102079           
  Misses      61570    61570           
  Partials     8860     8860           
Flag Coverage Δ
sei-chain-pr 64.61% <100.00%> (?)
sei-db 70.41% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
evmrpc/simulate.go 74.06% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread evmrpc/simulate.go
txIndex := hexutil.Uint(receipt.TransactionIndex)
tmTx := block.Block.Txs[txIndex]
tx = getEthTxForTxBz(tmTx, b.txConfigProvider(block.Block.Height).TxDecoder())
blockHash = common.BytesToHash(block.Block.Header.Hash().Bytes())

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this translation only required in this code path or potentially other places too?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is the only place that matters for now.
We also have:

  • evmrpc/subscribe.go using header.Header.Hash().String() on EventDataNewBlockHeader
  • evmrpc/filter.go using block.Block.Hash() on EventDataNewBlock
    These two are both triggered on events, and Autobahn currently don't invoke events. I don't know whether Autobahn will ever need these events. If we do then we can fix them there.

@bdchatham bdchatham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread evmrpc/simulate.go
// BlockID.Hash carries the actual block hash that the EVM receipt
// store recorded during FinalizeBlock: same on both engines,
// correct under both.
blockHash = common.BytesToHash(block.BlockID.Hash)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the block metadata guaranteed to be correct here? We find holes in Tendermint verification every now and then.

@wen-coding wen-coding May 1, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you asking about the timing issue? It's correct on our end:
GetTransaction(txHash) does Receipt(txHash) first, so it will only return the hash here if a receipt exists, so the block must have finished execution and the hash should be good here.

@wen-coding wen-coding added this pull request to the merge queue May 1, 2026
Merged via the queue into main with commit e68b82f May 1, 2026
43 checks passed
@wen-coding wen-coding deleted the wen/fix_get_transaction_block_hash_for_autobahn branch May 1, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants