Skip to content

Fix mismatch in receipts#2486

Merged
DmytroNazarenko merged 5 commits into
v5.2.0from
fix-mismatch
Jun 16, 2026
Merged

Fix mismatch in receipts#2486
DmytroNazarenko merged 5 commits into
v5.2.0from
fix-mismatch

Conversation

@badrogger

@badrogger badrogger commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

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

  • Reproduced and verified the fix with the existing test/api-tests/hardfork-compat suite, which performs a 5.1.0 → 5.2.0 upgrade scenario: runs a mixed workload on a 5.1.0 primary (legacy transfers, Type-1 access-list txs, Type-2 EIP-1559 txs, contract deploys,
    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.
  • Existing unit tests covering typed-receipt RLP round-trips and Berlin schedule behavior (test/unittests/libethereum/BerlinForkTransaction.cpp) continue to pass.

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.

@github-actions

Copy link
Copy Markdown

@badrogger badrogger marked this pull request as ready for review June 11, 2026 14:15
Copilot AI review requested due to automatic review settings June 11, 2026 14:15

Copilot AI 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.

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 BerlinForkPatch in Block::enact when computing receiptsRoot.
  • Gate typed receipt encoding on BerlinForkPatch in Block::commitToSeal when 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 BerlinForkPatch while tx wrapping remains gated by EIP1559TransactionsPatch. (PR comment left.)

Comment thread libethereum/Block.cpp Outdated
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;

Copilot AI 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.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@DmytroNazarenko DmytroNazarenko merged commit e03b41e into v5.2.0 Jun 16, 2026
24 of 29 checks passed
@DmytroNazarenko DmytroNazarenko deleted the fix-mismatch branch June 16, 2026 12:11
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 16, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants