Repository navigation
core/rawdb: freeze empty receipts when the header commits to none - #2474
kamuikatsurgi wants to merge 2 commits into
Conversation
Older versions could store a zero-length receipts value for blocks without (non state-sync) receipts during sync. The chain freezer treated that as missing data and failed on that block forever, re-appending and rolling back up to a full batch every minute. Freeze the canonical empty list instead when the block header's receipt root is the empty root, matching how the eth handlers already serve such blocks. A block that commits to non-empty receipts still fails as before.
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.
Tip: disable this comment in your organization's Code Review settings.
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The focused fix safely validates the header commitment and includes coverage for both success and rejection paths.
Review effort: Balanced
Findings: None
What changed in this PR
Fixes freezer stalls caused by legacy empty receipt values when headers commit to an empty receipt root.
Changes:
- Freezes
rlp.EmptyListfor safely verifiable empty receipts. - Preserves errors for non-empty receipt roots.
- Adds regression and control tests.
| File | Description |
|---|---|
core/rawdb/chain_freezer.go |
Handles legacy empty receipt values during freezing. |
core/rawdb/freezer_test.go |
Tests empty and non-empty receipt-root behavior. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #2474 +/- ##
===========================================
+ Coverage 55.62% 55.66% +0.04%
===========================================
Files 918 918
Lines 167160 167169 +9
===========================================
+ Hits 92978 93050 +72
+ Misses 68714 68640 -74
- Partials 5468 5479 +11
... and 32 files with indirect coverage changes
🚀 New features to boost your workflow:
|
|
This PR is stale because it has been open 21 days with no activity. Remove stale label or comment or this will be closed in 14 days. |
Summary
Fixes POS-3295 (
block receipts missing, can't freeze block N).Between v2.3.2 and v2.8.0,
splitReceiptsAndDeriveFieldsreturnednilfor blocks without (non state-sync) receipts. This mostly hit pre-Madhugiri sprint-end blocks whose only receipt was the state-sync one.InsertReceiptChainthen stored a zero-length value under the block's receipts key. 839b3c6 fixed the writer, but databases that already have these entries (and snapshots taken from them) stay stuck:freezeRangetreats the empty value as missing and never gets past that block.The freezer now freezes
rlp.EmptyListwhen the receipts value is empty and the block header commits to an empty receipt root. This is the same rule the eth handlers already use when serving receipts for such blocks. If the header commits to non-empty receipts, the freezer still errors as before.Executed tests
TestChainFreezerEmptyReceipts(fails without the fix);go test -race ./core/rawdb/...golangci-lintclean oncore/rawdb; diffguard passes with 100% mutation kill ratedevelopand from this branch, withFullImmutabilityThresholdlowered to 256 for the test only so the freezer runs within minutes.develop: both nodes got stuck as reported in the ticket. Every minute they loggedblock receipts missing, can't freeze block 85/... block 80, and ancients stayed at 49 / 54 while head grew past 500.eth_getBlockReceipts(85)returns[], and block 80's tx receipt is served from the ancient store with status 1.Rollout notes
Not consensus-affecting and backwards-compatible. Affected nodes start freezing again after the upgrade, with no resync needed.