fix: resolve in-memory parent header for multi-block eth_simulateV1#365
Open
TheFrozenFire wants to merge 1 commit into
Open
fix: resolve in-memory parent header for multi-block eth_simulateV1#365TheFrozenFire wants to merge 1 commit into
TheFrozenFire wants to merge 1 commit into
Conversation
eth_simulateV1 aborted with "Failed to get parent header from global header reader" whenever a request contained more than one blockStateCalls entry. The simulate loop chains blocks, so block N+1's parent is the in-memory block N produced one iteration earlier. BSC pre-execution (check_new_block) and the parlia snapshot rebuild resolve the parent by hash through the global header reader, which only holds real canonical headers, so the synthetic parent was unresolvable. BscBlockBuilder now seeds its parent header into the reader by hash only, leaving the canonical block-number index untouched, before pre-execution runs. For real block building the parent is already canonical, so this is a no-op re-seed; for simulation it makes each produced block resolvable as the next block's parent. The snapshot lookup is fixed implicitly via the provider's get_header_by_hash + try_rebuild fallback. Fixes bnb-chain/reth#194
Pull Request ReviewThis PR fixes a BSC/reth Sensitive ContentNo sensitive content detected. Security IssuesNo serious security issues detected. Generated by Hashdit Bot. This tool can absolutely NOT replace manual audits. |
TheFrozenFire
marked this pull request as ready for review
June 10, 2026 15:15
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
eth_simulateV1returned-32603 "Failed to get parent header from global header reader"whenever a request contained more than oneblockStateCallsentry (one block works, two or more fail). This makes each block produced during a multi-block simulation visible to the global header reader by hash, so the next block's parlia pre-execution can resolve its parent. Fixes bnb-chain/reth#194.Rationale
The simulate loop chains blocks: block N+1's parent is the in-memory block N produced one iteration earlier. BSC pre-execution (
check_new_block) and the parlia snapshot rebuild resolve the parent by hash viaHEADER_CACHE_READER, which only contains real canonical headers. Block 1's parent is the canonical chain tip and resolves; block 2's parent is the synthetic block 1, which is never persisted, so the lookup returnsNoneand execution aborts. geth serves multi-block simulate fine, so this is a reth-bsc-specific gap.Example
Reproduced against a BSC archive node. (The reported node version
1.10.2-devis thebnb-chain/rethbaseline — reth-node-core1.10.2with the-devsuffix for an untagged build — not a distinct reth-bsc release.)With this change the two-block request is expected to return two simulated blocks instead of erroring.
Changes
Notable changes:
BscBlockBuilder::apply_pre_execution_changesseeds its parent header intoHEADER_CACHE_READERby hash before pre-execution runs.HeaderCacheReader::insert_header_hash_only/insert_header_to_cache_hash_only— a hash-keyed insert that deliberately leaves the canonical block-number index untouched.test_simulated_block_parent_resolvable_by_hash_only.Potential Impacts
snapshot_by_hash) is fixed implicitly: the provider falls back toget_header_by_hash+try_rebuild, which now walks the seeded header back to the tip's snapshot.