Skip to content

Add EIP: Execution-Layer Reorg State Retention Window#11601

Merged
eth-bot merged 11 commits into
ethereum:masterfrom
nerolation:toni/retention
May 14, 2026
Merged

Add EIP: Execution-Layer Reorg State Retention Window#11601
eth-bot merged 11 commits into
ethereum:masterfrom
nerolation:toni/retention

Conversation

@nerolation

@nerolation nerolation commented May 5, 2026

Copy link
Copy Markdown
Contributor

Add a state-retention floor of 262_144 blocks (=2**18; 8192 epochs × 32 slots, ~36.4 days) so EL clients can locally process any reorg without triggering sync.
8192 epochs covers any leak scenario where up to ~79% of stake started offline.

@nerolation nerolation requested a review from eth-bot as a code owner May 5, 2026 11:05
@github-actions github-actions Bot added c-new Creates a brand new proposal s-draft This EIP is a Draft t-core labels May 5, 2026
@eth-bot

eth-bot commented May 5, 2026

Copy link
Copy Markdown
Collaborator

✅ All reviewers have approved.

@eth-bot eth-bot added e-consensus Waiting on editor consensus e-review Waiting on editor to review labels May 5, 2026
@github-actions github-actions Bot added the w-ci Waiting on CI to pass label May 5, 2026
Comment thread EIPS/eip-xxxx.md Outdated
Comment thread EIPS/eip-xxxx.md Outdated
nerolation and others added 3 commits May 7, 2026 08:28
Co-authored-by: Andrew B Coathup <28278242+abcoathup@users.noreply.github.com>
@github-actions github-actions Bot removed the w-ci Waiting on CI to pass label May 7, 2026
Comment thread EIPS/eip-8252.md Outdated
Comment thread EIPS/eip-8252.md Outdated
@github-actions github-actions Bot removed the t-core label May 7, 2026
@github-actions github-actions Bot added t-informational and removed s-draft This EIP is a Draft labels May 7, 2026
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

The commit 143ba14 (as a parent of c63f1ce) contains errors.
Please inspect the Run Summary for details.

@github-actions github-actions Bot added the w-ci Waiting on CI to pass label May 7, 2026
@github-actions github-actions Bot removed the w-ci Waiting on CI to pass label May 7, 2026

@jochem-brouwer jochem-brouwer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this EIP should (if we had the chance to time travel back a few years ago) have lived in execution-specs or a similar repository (as the definition and this constant). This EIP also uses several constants from "current fork" which is not future-proof. The status cannot start as Living, and although I emoji-accepted the Informational status before I believe this is not correct as it violates current EIP-1 spec.

If we need this now, categorize it as Core and as Draft (and check my other comments). Not sure, but my feeling is that this constant/definition should have lived elsewhere that EIPs repository (which we should have addressed at Paris 😓 )

Comment thread EIPS/eip-8252.md Outdated
Comment thread EIPS/eip-8252.md
Comment thread EIPS/eip-8252.md Outdated
Comment thread EIPS/eip-8252.md Outdated
Co-authored-by: Jochem Brouwer <jochembrouwer96@gmail.com>
@nerolation nerolation requested a review from jochem-brouwer May 13, 2026 07:29
@github-actions github-actions Bot added the s-draft This EIP is a Draft label May 14, 2026

@jochem-brouwer jochem-brouwer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed previous objects and problems I had in sync and this now looks fine, LGTM, lets merge!! 🚢 🚀

@eth-bot eth-bot enabled auto-merge (squash) May 14, 2026 09:23

@eth-bot eth-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All Reviewers Have Approved; Performing Automatic Merge...

@eth-bot eth-bot merged commit 5e93443 into ethereum:master May 14, 2026
10 checks passed
pull Bot pushed a commit to Dustin4444/erigon that referenced this pull request May 26, 2026
)

## Summary

Implements [EIP-8252](ethereum/EIPs#11601
`REORG_RETENTION_WINDOW = 262_144` blocks (~36.4 days) as the new
default for full and blocks prune modes.

### Mode definitions

| Mode | Blocks | History | Net effect on mainnet |
|---|---|---|---|
| `archive` | `KeepAllBlocksPruneMode` | sentinel | unchanged |
| `full` (default) | `Distance(262_144)` *(was
`DefaultBlocksPruneMode`)* | `Distance(262_144)` *(was `100_000`)* | tx
+ state pruned to last 262k blocks |
| `blocks` | `KeepAllBlocksPruneMode` | `Distance(262_144)` *(was
`100_000`)* | state pruned to last 262k blocks |
| `minimal` | `Distance(100_000)` | `Distance(100_000)` | unchanged —
pinned to new `MinimalPruneDistance` constant, deliberately sub-EIP-8252
|

The `DefaultBlocksPruneMode` sentinel is also renamed in this PR to
`KeepPostMergeBlocksPruneMode` to reflect what it actually does (drop
pre-merge data, keep post-merge) now that it's no longer the default for
any named mode.

### Fresh-sync impact

New full nodes download substantially fewer transaction segments than
3.4's full mode. `buildBlackListForPruning` activates for distance-based
`Blocks` and blacklists tx segments with `To <= frozenBlocks - 262_144`
before the download loop. On mainnet today (head ~22M, merge ~15.5M)
that's keeping ~262k blocks of tx instead of ~6.5M post-merge blocks —
roughly a 25× reduction in transaction-segment disk footprint. Headers
and bodies (excluding tx) follow their existing rules.

### Existing-datadir upgrades

`EnsureNotChanged` got a generic retention-window compat path:

- Accepts finite↔finite `Distance` changes on `History` or `Blocks` in
either direction (covers the EIP-8252 default bump and any
operator-initiated `--prune.distance` change).
- Accepts the either-direction transition between a finite `Distance`
and `KeepPostMergeBlocksPruneMode` (chain-history-expiry sentinel) on
`Blocks` — so legacy full datadirs upgrade silently, and operators can
revert with `--prune.distance.blocks=18446744073709551615` even after
the auto-upgrade has rewritten the persisted value.
- Rejects any transition involving `KeepAllBlocksPruneMode` — narrowing
from "keep all blocks" is the one truly destructive direction and stays
explicit.

When a compatible transition is accepted, the persisted value is
rewritten so subsequent restarts don't re-fire the warning. The
pre-existing archive-default-bump compat branch is preserved for the
orthogonal `{KeepPostMergeBlocksPruneMode, KeepPostMergeBlocksPruneMode}
→ ArchiveMode` legacy-archive case.

### `eth_capabilities` clamp

Previously `eth_capabilities` advertised `receipts.oldestBlock=0` and
`logs.oldestBlock=0` whenever `--persist.receipts` was set, regardless
of whether the node could actually serve them. That was correct under
the old `FullMode` shape (`Blocks=DefaultBlocksPruneMode` kept block
bodies indefinitely), but not under the new finite-Distance shape —
`eth_getBlockReceipts` walks block bodies and `getLogsV3` reads log
indexes, both of which follow `prune.Blocks`. The RPC now reports
`blocksOldest` for receipts/logs with the same `DeleteStrategy{window,
N}` as blocks, so routing layers can correctly determine which node to
ask.

### Caveat: frozen `.seg` file deletion is gated by erigontech#21306

Physical deletion of already-on-disk frozen transaction segments is not
yet implemented (erigontech#21306). Upgraded full datadirs will record the new
cutoff but keep the old `.seg` files on disk until that lands;
freshly-synced full nodes use the blacklist at download time and avoid
the data in the first place. So an upgraded full node will have *more*
on-disk data than a freshly-synced one until erigontech#21306 ships.

### Other changes wrapped up in this PR

- **`Distance.Enabled()` corrected** to return false for both sentinel
values (`KeepPostMergeBlocksPruneMode` and `KeepAllBlocksPruneMode`).
Previously only the former was excluded; the snapshotsync blacklist
needed a local workaround that's now gone.
- **`isTransactionsSegmentExpired` removed**, absorbed into
`buildBlackListForPruning`. The download path now has one filter for tx
segments instead of two parallel ones covering different mode shapes.
`buildBlackListForPruning` uses `cc.IsPreMerge(res.From)` directly for
the chain-history-expiry case rather than indirecting through
`blocksRetentionCutoff` with a `head=0` trick.
- **`blocksRetentionCutoff` extracted** and used by
`isReceiptsSegmentPruned` so the per-mode cutoff logic lives in one
place.
- **`downloadFilteringApplies` extracted** to gate the slow
`getMinimumBlocksToDownload` call with the same predicate
`buildBlackListForPruning` uses internally; previously the gate was
narrower than the function's own activation logic, which caused the
`--prune.mode=archive --prune.distance.blocks=18446744073709551615`
hybrid to silently skip pre-merge tx filtering.
- **`Mode.String()` recognises legacy shapes** rather than rendering
them as misleading "archive ..." strings:
`{KeepPostMergeBlocksPruneMode, finite}` → `"full(legacy)
--prune.distance=N"`; `{KeepAllBlocksPruneMode, finite}` → `"blocks
--prune.distance=N"`. The fallback rendering still mirrors `FromCli`
input so operator-supplied `--prune.mode=archive --prune.distance=…`
round-trips visibly.
- **`duDetectNodeType` blocks-mode gate** uses `DefaultPruneDistance`
for the maturity check: a genesis tx segment is evidence of blocks mode
only on a chain past the point where full would have pruned it. On
chains in the `[MinimalPruneDistance, DefaultPruneDistance]` band, full
and blocks are indistinguishable on disk; the fall-through defaults the
ambiguous case to full, the more common mode.
- **`duComputeEstimates` returns a 4th row** for blocks mode — mirrors
full's state-history pruning but keeps all tx segments and
receipt-related state, matching the runtime behaviour.
- **`setIfNotExist` and `overwriteStoredMode` share a `writeBlockAmount`
helper** that owns the on-disk serialisation.
- Docs updated: `docs/site/docs/fundamentals/sync-modes.md`,
`execution/commitment/qmtree/PRUNE_POLICY.md`, ChangeLog entry,
regenerated `llms-full.txt` artifacts.

Refs EIP-8252 (informational):
ethereum/EIPs#11601

Closes erigontech#20447

## Test plan

- [x] `make lint` clean across multiple runs (non-deterministic linter)
- [x] `go build ./...` clean
- [x] `go test ./db/kv/prune/...`: 11-case `isRetentionWindowChange`
table + 9 `EnsureNotChanged` integration tests (legacy minimal no-op,
blocks-mode History bump with DB rewrite, full sentinel→finite
acceptance, finite→`KeepPostMergeBlocksPruneMode` revert acceptance,
`KeepAllBlocksPruneMode` narrowing rejected, archive identity,
arbitrary-distance change, pre-existing archive-default-bump compat) +
`TestModeString_LegacyShapes`
- [x] `go test ./db/snapshotsync/...`: `TestBlackListForPruning`
(asserts against the adjusted-cutoff value the function actually uses,
so a regression in `adjustBlockPrune` would fail loudly),
`TestBlackListForPruning_BlocksModeKeepsAllTransactions` (locks down the
`Distance.Enabled()` fix), `TestBlackListForPruning_ChainHistoryExpiry`
(covers the absorbed sentinel path against mainnet preverified),
`TestDownloadFilteringApplies` (8-case table including the
`{KeepPostMerge, KeepPostMerge}` hybrid)
- [x] `go test ./cmd/utils/app/... -run TestDU`: boundary fixtures at
`To` in the gap between minimal's and full's cutoffs validate per-mode
pruning math; blocks-mode row in estimates; detector classification
including the `[MinimalPruneDistance, DefaultPruneDistance]`
ambiguity-band regression test
- [x] `go test ./rpc/jsonrpc/... -run TestCapabilities`: legacy-full
shape (chain-history-expiry sentinel) and finite-finite shape (EIP-8252)
covered, including `--persist.receipts` interactions and `MergeHeight`
clamping
- [ ] Manual smoke test against a real mainnet datadir (deferred — happy
to do on request)

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: info@weblogix.biz <admin@10gbps.weblogix.it>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c-new Creates a brand new proposal e-consensus Waiting on editor consensus e-review Waiting on editor to review s-draft This EIP is a Draft t-informational

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants