Fix mismatch in receipts#2486
Merged
Merged
Conversation
|
SUGGESTIONS BEFORE MERGE:
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a consensus-critical receiptsRoot mismatch by aligning EIP-2718 typed-receipt encoding activation with BerlinForkPatch (instead of EIP1559TransactionsPatch) in both block production (commitToSeal) and block re-enactment (enact). This ensures pre-Berlin blocks retain their original receipt encoding/root even if typed transaction formats are accepted earlier.
Changes:
- Gate typed receipt encoding on
BerlinForkPatchinBlock::enactwhen computingreceiptsRoot. - Gate typed receipt encoding on
BerlinForkPatchinBlock::commitToSealwhen computing the receipts trie/root. - Add clarifying comments explaining why receipt encoding activation differs from early typed-transaction acceptance.
Review Findings (sorted by severity)
Critical: None found.
High: None found.
Medium: None found.
Low:
- A nearby comment in the transaction-encoding section still states it is “Same as receiptBytes creation”, which becomes misleading after this change because receipts are now gated by
BerlinForkPatchwhile tx wrapping remains gated byEIP1559TransactionsPatch. (PR comment left.)
Comment on lines
1426
to
1430
| // EIP-2718 typed-receipt encoding is gated on BerlinForkPatch (not | ||
| // EIP1559TransactionsPatch): the EIP-1559 transaction format is accepted | ||
| // before Berlin, but the receipt encoding must only change at the | ||
| // coordinated Berlin fork so pre-Berlin blocks keep their receiptsRoot. | ||
| bytes receiptBytes; |
PropzSaladaz
approved these changes
Jun 15, 2026
kladkogex
approved these changes
Jun 16, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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
Fixes a receiptsRoot mismatch between block producers and syncing nodes.
The EIP-2718 typed-receipt encoding in Block::enact and Block::commitToSeal was gated on EIP1559TransactionsPatch. Since skaled accepts the EIP-1559 transaction format before the Berlin fork, nodes with that patch active would start emitting typed receipt encodings
(0x01/0x02-prefixed RLP) for blocks produced before the coordinated Berlin fork timestamp. A node re-enacting those blocks (e.g. a sync/archive node catching up) would then compute a different receiptsRoot than the one sealed in the block header, causing a
state/receipts mismatch.
This change gates the typed-receipt encoding on BerlinForkPatch instead, in both code paths, so the receipt encoding only changes at the coordinated Berlin fork and pre-Berlin blocks keep their original receiptsRoot. The EIP-1559 transaction format itself remains
accepted before Berlin; only the receipt encoding activation point moves.
Tests
CREATE/CREATE2 factory), then launches a 5.2.0 sync node (syncNode=true, archiveMode=true) and asserts per-block stateRoot and block-hash equality across the whole chain. Before the fix the sync node diverged on blocks containing typed transactions produced
pre-Berlin; with the fix the comparison passes.
No new tests were added; the existing hardfork-compat suite already covers the failing scenario.
Performance Impact
None expected. The change only swaps which patch flag is consulted (BerlinForkPatch vs EIP1559TransactionsPatch) — both are constant-time timestamp checks — and the receipt encoding work performed per transaction is unchanged. No benchmarks were run as the change is
not on a hot path beyond what already executed per receipt.