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