Expand description
Freshness control plane and the optimistic verify-and-rerun execution loop.
This module is the generic core of the engine’s “honest freshness” model: it knows which cached state it can trust, for how long, and how to keep the rest correct without blocking simulations on RPC. It is built from four layers:
- Classification —
Validity(Pinned/Volatile/ValidThrough) and theFreshnessRegistrythat resolves a validity per(address, slot)with the precedence slot ▸ account ▸ default. - Observation —
SlotObservationTrackerrecords per-slot change frequency (clock-agnostic) to drive adaptive re-verification, tuned byFreshnessParams. - Policy — the
FreshnessPolicytrait decides which volatile slots to verify this cycle; built-ins areAlwaysVerify,NeverVerifyandObservationDriven. - Mechanism —
EvmCache::verify_slots/EvmCache::purge_account, and the freshness controller that runs the optimistic loop.
The clock is configurable via FreshnessClock: BlockClock (the default,
block-number based) or WallClock (unix seconds). The controller threads
clock.now() as now: u64 through the tracker, the policy, and
FreshnessRegistry::is_volatile.
§Reconciliation scope
The optimistic loop verifies only volatile storage slots in each sim’s
read set. Account-level state — native balance, nonce, and bytecode — is
not re-fetched or diffed today, so Validation::ConfirmedStorage means
“no volatile storage slot the sims read had changed”, not “no account state
changed”. A sim whose result depends on a BALANCE/SELFBALANCE (or
nonce/code) that moved on-chain without a co-changing storage slot in its read
set can still be reported ConfirmedStorage. If account-level state matters to
a sim, mark the account Validity::Pinned and keep it fresh via event-driven
writes, or reconcile it out of band.
The verdict taxonomy is deliberately split so this over-promise is visible in
the type: ConfirmedStorage (storage only,
account fields unverified) is distinct from
ConfirmedFull (storage and verified
account-level fields both unchanged). ConfirmedFull is defined but not yet
emitted — a follow-up wave wires validator-side account verification that will
populate it and the Corrected verdict’s
changed_accounts. See Validation for the per-verdict note.
§Example
Classification + policy selection, no network required:
use alloy_primitives::{Address, U256};
use evm_fork_cache::freshness::{
AlwaysVerify, FreshnessPolicy, FreshnessRegistry, NeverVerify,
};
use evm_fork_cache::cache::SlotObservationTracker;
let contract = Address::repeat_byte(0x01);
let volatile_slot = U256::from(0);
let immutable_slot = U256::from(6); // e.g. a constructor-set config value
let mut registry = FreshnessRegistry::new(); // default: Volatile
registry.pin_slot(contract, immutable_slot); // never re-verified
// `now` is in clock units (block number for the default BlockClock).
let now = 100;
assert!(registry.is_volatile(contract, volatile_slot, now));
assert!(!registry.is_volatile(contract, immutable_slot, now));
// Policies pick which volatile candidates to verify this cycle.
let obs = SlotObservationTracker::new();
let candidates = [(contract, volatile_slot)];
assert_eq!(
AlwaysVerify.select(&candidates, &obs, now),
vec![(contract, volatile_slot)]
);
assert!(NeverVerify.select(&candidates, &obs, now).is_empty());Structs§
- Always
Verify - Verifies every volatile candidate (safe / eager). Always correct, most RPC.
- Block
Clock - Block-number clock (the default). Cloning shares the underlying counter, so a
clone observed by a background task sees
set_blockupdates made on the main thread. - Freshness
Controller - Drives the optimistic verify-and-rerun loop over an
EvmCache. - Freshness
Params - Tunable thresholds for the adaptive freshness model.
- Freshness
Registry - Per-address / per-slot validity classification.
- Never
Verify - Verifies nothing (trust-all). Selects no slots from the predicted set, though the actual-read-set reconcile in the background validator can still surface changes.
- Observation
Driven - Adaptive policy: verifies candidates the observation tracker flags via
SlotObservationTracker::should_refetch, driven by the thresholds inFreshnessParams. - SimRequest
- A single non-committing simulation request for the optimistic loop.
- Slot
Change - A storage slot whose value changed:
oldis the prior cached/snapshot value (ZEROif previously uncached),newis the resulting value. - Slot
Outcome - The classified outcome of fetching a single storage slot.
- Speculative
Sim - Optimistic simulation results plus a handle to their deferred validation.
- Wall
Clock - Wall-clock clock:
nowreturns unix seconds.
Enums§
- Slot
Fetch - The classified result of an individual slot fetch.
- Validation
- The deferred verdict on a
SpeculativeSim’s optimistic results. - Validity
- How long a cached account or storage slot can be trusted.
Constants§
- DEFAULT_
ALWAYS_ REFETCH_ RATE - Default change-rate above which a slot is always refetched.
- DEFAULT_
CYCLE_ INTERVAL - Default clock units per “cycle” used by the probabilistic model.
- DEFAULT_
MAX_ REUSE - Default maximum reuse window, in clock units, before a slot is rechecked.
- DEFAULT_
MIN_ OBSERVATIONS - Default minimum observations before the change-frequency data is trusted.
- DEFAULT_
STALENESS_ THRESHOLD - Default refetch threshold on expected probability of change.
Traits§
- Freshness
Clock - Source of the current clock value used throughout the freshness model.
- Freshness
Policy - Decides which volatile candidate slots must be verified this cycle.