db, execution, rpcdaemon: coherent version-keyed state cache - #22532
Draft
yperbasis wants to merge 2 commits into
Draft
db, execution, rpcdaemon: coherent version-keyed state cache#22532yperbasis wants to merge 2 commits into
yperbasis wants to merge 2 commits into
Conversation
Split out of #21293. Announce the post-commit PlainStateVersion from the pre-commit dispatch, rework the Coherent kvcache around fresh version-keyed roots with reader-shaped keys, and wire the standalone rpcdaemon to the coherent cache at every budget. The execmoduletester waits for the FCU background commit after InsertChain so bg-commit tests read committed state.
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a coherent, version-keyed state cache model (keyed by PlainStateVersion) and updates notification dispatch so state-change batches can announce the version readers will observe post-commit (via a new preCommit flag). It also aligns standalone rpcdaemon cache wiring across remote and --datadir modes, and adds/extends tests to pin the new announce-vs-committed version contract and cache behaviors (including zero-budget coherence).
Changes:
- Extend notification dispatch API (
preCommitflag) so pre-commit overlay dispatch announces the post-commitPlainStateVersion. - Rework
kvcache.Coherentto be version-keyed and reader-shaped (address+location for storage, address for code), with explicit behavior for evicted roots and zero-budget operation. - Update standalone
rpcdaemonto consistently use the coherent cache (even at0MB), plus add tests for version parity and zero-budget snapshot-consistent reads.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| rpc/rpchelper/helper.go | Simplifies history cached reader wiring by relying on CacheView.GetAsOf in the interface. |
| execution/stagedsync/stageloop/stageloop.go | Extends notification sender contract with preCommit flag; clarifies committed-tx requirement for Hook.SendNotifications. |
| execution/execmodule/notification_dispatcher.go | Implements preCommit behavior: announces post-commit PlainStateVersion for overlay dispatch. |
| execution/execmodule/forkchoice.go | Marks overlay-driven dispatch as preCommit=true. |
| execution/execmodule/execmoduletester/exec_module_tester.go | Ensures tests wait for commit completion via ExecModule.WaitIdle after InsertChain. |
| execution/execmodule/exec_module_test.go | Adds version parity test and removes background-commit skip based on updated serialization guarantees. |
| db/kv/kvcache/cache.go | Core coherent cache changes: version-keyed roots, reader key shapes, eviction/root-lifetime handling, and zero-budget fast-paths. |
| db/kv/kvcache/cache_test.go | Adds targeted tests for fresh roots, shared budgets, key shapes, eviction fallback, non-latest no-cache, and zero-budget behavior. |
| db/kv/kvcache/simple.go | Makes SimpleView satisfy updated CacheView interface (adds GetAsOf stub). |
| cmd/rpcdaemon/cli/config.go | Ensures standalone rpcdaemon consistently uses coherent cache across modes; disables new-block waiting for zero budgets. |
| cmd/rpcdaemon/cli/config_test.go | Adds regression test ensuring zero-budget remote cache remains snapshot-consistent (no retention). |
| llms-full.txt | Updates CLI help text for --state.cache semantics. |
| docs/site/static/llms-full.txt | Mirrors updated CLI help text for documentation site static copy. |
| docs/site/docs/fundamentals/modules/rpc-daemon.md | Mirrors updated --state.cache help in rpcdaemon docs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
222
to
225
| // if nothing has progressed just return the existing root | ||
| if c.latestStateVersionID == stateVersionID && rootExists { | ||
| return r | ||
| } |
This was referenced Jul 17, 2026
Draft
Closed
Open
pull Bot
pushed a commit
to Dustin4444/erigon
that referenced
this pull request
Jul 18, 2026
Renames `SimpleCache` → `LatestBatchCache` (with `NewSimple` → `NewLatestBatchCache`, `SimpleView` → `LatestBatchView`, `simple.go` → `latest_batch.go`). "Simple" described the implementation rather than the contract, and suggested Simple and Coherent sit on a complexity spectrum. They actually sit on opposite sides of a semantic fork: - **`Coherent`** — snapshot-consistency first: entries are keyed by `PlainStateVersion`, so a reader stays consistent with its own committed view and never sees fresher data. - **`LatestBatchCache`** — freshness first: version-blind, it serves the most recent announced state-change batch on top of the caller's tx, deliberately showing announced-but-not-yet-committed account data; staleness is bounded to one batch by FCU serialization. That fork is what decides which cache is safe where (in-process txpool vs RPC reads — see erigontech#22532 / erigontech#22269), and the new name carries it: content (the latest batch), lifetime (replaced wholesale per batch), and the trade-off (by contrast with `Coherent`). Also updates the type doc comment to lead with the contract. One cleanup rider in the same spirit: the dead `Evict() int { return 0 }` stub is removed (no callers, not part of the `Cache` interface — a `DummyCache`-era leftover). Mechanical rename + dead-code removal, no behavior change (TDD not applicable). --------- Co-authored-by: Alex Sharov <AskAlexSharov@gmail.com>
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Split out of #21293 (
FcuBackgroundCommitgroundwork). Defaults are unchanged — the0MB→128MBretention default flip stays in #22269.Announce the version committed readers will observe
State-change notifications are dispatched pre-commit (from the SD overlay).
Dispatcher.Dispatchgains apreCommitflag and announces the post-commitPlainStateVersion— the flush that follows bumps the version exactly once (TemporalMemBatch.flushLocked) — so version-keyed cache roots match exactly the readers that should see them: post-commit transactions hit the new canonical root, pre-commit transactions keep the previous one. The committed-tx dispatch path (Hook.SendNotifications) passesfalse.Coherent version-keyed cache (
db/kv/kvcache)Roots are keyed by
PlainStateVersion. Batch-fed storage and code entries use the key shapes readers look up (address+location; code by address — seestate.CachedReader3). A view that outlivesKeepViewsversion advances falls back to its own tx snapshot instead of erroringtoo old ViewID; reads through non-latest views are not cached (they bypass eviction accounting and would grow without bound). Retained roots share the configured memory budgets: entries in older roots are cleared on version advance. Canonical roots start from their own batch, with no carry-over: the state-change producers don't announce every mutation, so a carried entry could stay stale — at a deliberate hit-rate cost (hot-but-unchanged keys miss once per key per block). Completing the producers and restoring carry-over is tracked in #22276. Code-cache hits now refresh the code eviction list (they previously moved entries in the state list, corrupting LRU order). A zero budget skips the cache machinery entirely — no global-lock churn on the read path.Standalone rpcdaemon wiring
The standalone daemon uses the coherent cache at every configured budget, in remote and
--datadirmodes alike (previously0MBand--datadirfell back toSimpleCache, which serves the newest batch's accounts to any reader regardless of its tx snapshot). Positive budgets retain entries;0MBretains none and disables new-block waiting, so reads fall back to the caller's tx snapshot while remaining coherent.Tests
TestStateChangeVersionMatchesCommittedpins announce-vs-committed version parity across {fg, bg} × {1-by-1, batched} (the batched case crosses the initial-cycle threshold, covering mid-FCU version bumps). kvcache tests pin fresh roots, retained-root aggregate budgets, reader-shaped feed keys, the evicted-view fallback, non-latest no-cache, and zero-budget no-retention.TestZeroBudgetRemoteCachePinsCommittedStatepins snapshot-consistent reads with entry retention disabled.The execmoduletester now calls
ExecModule.WaitIdleafterInsertChain: state-change events are dispatched pre-commit, so returning on the notification stream alone let bg-commit tests read pre-commit state (blockgen.GenerateChainonm.DBwould build on a stale genesis). That fix is what letsTestNotificationDispatchBackgroundCommitdrop its skip — successive FCUs are serialized via the ExecModule semaphore, so the skip's stated blocker no longer exists.Known follow-ups
#22527 (same-version re-announce keeps stale entries at >0MB after a failed/crashed commit — should land before #22269), #22276 (producer completeness / carry-over warmth), #22277 (
erigon_cacheCheckfalse positives, pre-existing).