Skip to content

execution/cache: wire RevertWithDiffset into unwind path#20516

Merged
yperbasis merged 1 commit intomainfrom
fix/state-cache-unwind-invalidation
Apr 13, 2026
Merged

execution/cache: wire RevertWithDiffset into unwind path#20516
yperbasis merged 1 commit intomainfrom
fix/state-cache-unwind-invalidation

Conversation

@yperbasis
Copy link
Copy Markdown
Member

Summary

  • Wire the existing RevertWithDiffset into unwindExec3 so the state cache is surgically invalidated during unwinds — keys touched by the unwound blocks are evicted, untouched keys remain cached
  • Previously RevertWithDiffset was implemented but never called; the cache survived unwinds only because ValidateAndPrepare cleared it on the next block (hash mismatch fallback)
  • The lastExecHash (already fetched with a comment anticipating this wiring) detects if the cache was modified by a different execution path (e.g. rolled-back ValidatePayload), falling back to a full clear

Context

Follow-up to #20265 and #20483. Those PRs fixed correctness bugs in the cache layer and domain unwind; this PR completes the picture by actually invalidating the cache during unwinds rather than relying on the next-block safety net.

Test plan

  • TestRevertWithDiffset_SurgicalEviction — touched keys evicted, untouched preserved, blockHash updated
  • TestRevertWithDiffset_HashMismatch_ClearsAll — mismatched revertFromHash triggers full clear
  • TestRevertWithDiffset_AccountChange_EvictsCode — account diffs also evict corresponding code entries
  • TestRevertWithDiffset_ThenValidateAndPrepare_Continuity — end-to-end: surgical revert then re-execution preserves surviving cache data
  • make lint clean
  • Full sync test on a testnet with unwinds

🤖 Generated with Claude Code

RevertWithDiffset was implemented but never called — the state cache
was not invalidated during unwinds, surviving only because
ValidateAndPrepare cleared it on the next block (hash mismatch).

Wire RevertWithDiffset into unwindExec3 so that keys touched by the
unwound blocks are surgically evicted from the cache immediately after
the domain state is rewound. Untouched keys remain cached. The
lastExecHash (already fetched for this purpose) detects if the cache
was modified by a different execution path, falling back to a full
clear.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@yperbasis yperbasis marked this pull request as ready for review April 13, 2026 10:50
@yperbasis yperbasis requested a review from mh0lt as a code owner April 13, 2026 10:50
yperbasis added a commit that referenced this pull request Apr 13, 2026
Each ValidateChain call opens a fresh RwTx that is rolled back after
validation completes. The shared state cache may hold values written
during a previous validation on a now-rolled-back tx. When the next
validation creates a fresh SharedDomains backed by a new tx, stale
cache entries are returned by GetLatest before the backing tx is
consulted, causing the parallel executor to see incorrect state
(e.g. nonce=1 instead of nonce=0 for a sender at genesis).

Clear the state cache at the start of each ValidateChain so execution
reads authoritative state from the backing tx.

Note: this is distinct from the unwind-path cache invalidation in
PR #20516 (RevertWithDiffset). That PR handles keys modified during
an unwound execution range within the same tx. This fix handles
cross-validation staleness where the previous tx was rolled back
entirely.

Fixes TestEngineApiExecBlockBatchWithLenLtMaxReorgDepthAtTipThenUnwindShouldSucceed
which fails when EXEC3_PARALLEL=true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@yperbasis yperbasis enabled auto-merge April 13, 2026 11:15
@yperbasis yperbasis added this pull request to the merge queue Apr 13, 2026
Merged via the queue into main with commit 2a34710 Apr 13, 2026
40 of 65 checks passed
@yperbasis yperbasis deleted the fix/state-cache-unwind-invalidation branch April 13, 2026 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants