Skip to content

[r3.4] exec: fix partial block receipt reconstruction (#20452)#20849

Merged
AskAlexSharov merged 1 commit into
release/3.4from
alex/partial_block_receipts_34
Apr 28, 2026
Merged

[r3.4] exec: fix partial block receipt reconstruction (#20452)#20849
AskAlexSharov merged 1 commit into
release/3.4from
alex/partial_block_receipts_34

Conversation

@AskAlexSharov

Copy link
Copy Markdown
Collaborator

Cherry-pick of #20467 to release/3.4.

When execution resumes from a snapshot boundary mid-block (initialBlockTxOffset > 0), the receipts passed to engine.Finalize() only contained receipts from the re-executed portion. This causes Pectra requests hash validation to fail because deposit request extraction needs ALL receipt logs.

Reproduces as: invalid requests root hash in header at block 24966723 on mainnet re-sync.

- When execution resumes from a snapshot boundary mid-block
(`initialBlockTxOffset > 0`), the receipts passed to `engine.Finalize()`
only contained receipts from the re-executed portion. This causes Pectra
requests hash validation to fail because deposit request extraction
needs ALL receipt logs.
- Fixes the `isPartial` detection in the parallel executor — `tasks[0]`
is the system tx (`TxIndex=-1`), so the first user tx must be found by
scanning for `TxIndex >= 0`.
- Adds `replayPriorTxsForReceipts` functions that use a
`HistoryReaderV3` to re-execute prior transactions and reconstruct their
receipts, prepending them before calling `Finalize`.
- Applied to both parallel (`exec3_parallel.go`) and serial
(`exec3_serial.go`) executors.

Closes #20452

- [x] `make erigon` and `make integration` build successfully
- [x] `make lint` passes (run twice for non-determinism)
- [x] `go test -short ./execution/stagedsync/...` passes
- [x] Run node through a Pectra-era snapshot boundary where
`initialBlockTxOffset > 0` and verify requests hash validation passes
- [x] Verify deposit request extraction from logs includes all block
transactions

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Mark Holt <erigon@dev-bm-e3-ethmainnet-n4.erigon.io>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@erigon-copilot erigon-copilot Bot 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.

Compared with #20847, this is broader and more complete rather than identical:

  • it fixes both exec3_serial and exec3_parallel
  • it factors the receipt replay logic into a shared execution/receipts helper instead of inlining a one-off path
  • it reconstructs prior receipts by replaying transactions against the correct historical state, which is a more general solution than relying only on receipt-cache availability

So the intent is the same (ensure Finalize sees the full receipt set for partial/frozen blocks), but #20849 is not just a duplicate cherry-pick of #20847 — it is the more complete implementation.

@AskAlexSharov AskAlexSharov merged commit ab501fc into release/3.4 Apr 28, 2026
21 checks passed
@AskAlexSharov AskAlexSharov deleted the alex/partial_block_receipts_34 branch April 28, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants