Skip to content

execution: fence StateCache across frozen-block startup processing #22925

Description

@yperbasis

System information

Commit hash: 7566757e37 (main)

This is a code-level concurrency problem and is not specific to an OS, network, or node configuration.

Expected behaviour

After ProcessFrozenBlocks advances durable account, storage, or code state during startup, StateCache must not serve or accept values from an older temporal snapshot.

Actual behaviour

Engine endpoints are live before ExecModule.Start. Early payload validation or a reader using a published SharedDomains can populate the process-wide StateCache from the pre-catchup state.

ExecModule.Start then calls ProcessFrozenBlocks. That path advances durable domain state through SharedDomains instances that are not connected to StateCache, so existing pre-catchup entries are not updated. Later execution can therefore receive stale account, storage, or code values from the cache and compute the wrong state.

A clear by itself is not a complete fix unless it also fences every cache-populating reader. A temporal read opened before the clear can finish afterward and refill an old value. Waiting for BlockReadAheader only covers asynchronous read-ahead; regular SharedDomains read-fill can still cross the reset.

Steps to reproduce the behaviour

  1. Commit account value v1 and open a temporal read transaction at that state.
  2. Advance the durable domain to v2 through a path that does not apply updates to StateCache, matching frozen-block startup processing.
  3. Clear the cache at the startup boundary.
  4. Complete the old temporal read so it offers v1 to the empty cache.
  5. Read the account from a new temporal transaction.

Without a snapshot-generation or domain-progress fence, the new read can hit cached v1 instead of durable v2.

Regression coverage should also test the simpler main-branch case where v1 is already cached before uncached frozen-block processing advances the database to v2.

Context

Found while reviewing #22469. That PR should remain focused on cache-populating warmup lifecycle and interrupted-drain handling; startup cache coherence should be fixed and tested under this issue.

Metadata

Metadata

Labels

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions