Skip to main content

evm_fork_cache/cold_start/
plan.rs

1//! What a cold-start round declares it wants done.
2//!
3//! A [`ColdStartPlan`] is a pure, IO-free description handed to the driver. All
4//! phases are optional and an empty plan is a valid no-op round.
5
6use alloy_primitives::{Address, Bytes, U256};
7
8/// A single round of cold-start work, declared by a
9/// [`ColdStartPlanner`](crate::cold_start::ColdStartPlanner).
10///
11/// All phases are optional; an empty plan is a valid no-op round. The driver
12/// executes the phases in a fixed order:
13/// **accounts → verify → probe → probe_roots → discover**.
14///
15/// - `verify` slots are authoritatively re-fetched, classified, and (when changed)
16///   injected into the cache via the dual-layer
17///   [`inject_storage_batch_fresh`](crate::cache::EvmCache::inject_storage_batch_fresh).
18/// - `probe` slots are classified at the pinned block **without** injecting.
19/// - `probe_roots` accounts have their storage root observed via the
20///   account-proof fetcher at the pinned block, without injecting anything.
21/// - `accounts` are pre-seeded into the cache before discovery runs.
22/// - `discover` view-calls capture the `(address, slot)` pairs and accounts they
23///   touch.
24///
25/// ```
26/// use alloy_primitives::{Address, Bytes, U256};
27/// use evm_fork_cache::{ColdStartCall, ColdStartPlan};
28///
29/// // Verify one known slot and discover more via a read-only view-call.
30/// let plan = ColdStartPlan {
31///     verify: vec![(Address::repeat_byte(0x11), U256::from(0))],
32///     discover: vec![ColdStartCall {
33///         from: Address::ZERO,
34///         to: Address::repeat_byte(0x11),
35///         calldata: Bytes::new(),
36///         restrict_to: None,
37///     }],
38///     ..Default::default()
39/// };
40/// assert_eq!(plan.verify.len(), 1);
41/// assert_eq!(plan.discover.len(), 1);
42/// ```
43#[derive(Clone, Debug, Default)]
44pub struct ColdStartPlan {
45    /// Slots to authoritatively re-fetch, classify, and inject when changed.
46    pub verify: Vec<(Address, U256)>,
47    /// Slots to classify at the pinned block without injecting.
48    pub probe: Vec<(Address, U256)>,
49    /// Accounts whose storage root is probed via the account-proof fetcher at
50    /// the pinned block, without injecting anything.
51    pub probe_roots: Vec<Address>,
52    /// Accounts to pre-seed into the cache before discovery.
53    pub accounts: Vec<Address>,
54    /// View-calls whose touched slots and accounts are captured.
55    pub discover: Vec<ColdStartCall>,
56}
57
58/// A read-only view-call whose touched storage and accounts are captured during
59/// the discover phase.
60///
61/// When `restrict_to` is `Some`, the captured `slots` and `accounts` are filtered
62/// to the named addresses; an empty restricted capture is observable as an empty
63/// access list (distinct from a non-empty discovery).
64#[derive(Clone, Debug)]
65pub struct ColdStartCall {
66    /// Transaction sender.
67    pub from: Address,
68    /// Call target.
69    pub to: Address,
70    /// Calldata.
71    pub calldata: Bytes,
72    /// When set, filters captured slots and accounts to these addresses.
73    pub restrict_to: Option<Vec<Address>>,
74}