Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 66 additions & 66 deletions crates/evm/chain/src/deferred_trie.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,72 +23,6 @@ pub struct DeferredTrieData {
state: Arc<Mutex<DeferredState>>,
}

/// Sorted trie data computed for an executed block.
/// These represent the complete set of sorted trie data required to persist
/// block state for, and generate proofs on top of, a block.
#[derive(Clone, Debug, Default)]
pub struct ComputedTrieData {
/// Sorted hashed post-state produced by execution.
pub hashed_state: Arc<HashedPostStateSorted>,
/// Sorted trie updates produced by state root computation.
pub trie_updates: Arc<TrieUpdatesSorted>,
/// Trie input bundled with its anchor hash, if available.
pub anchored_trie_input: Option<AnchoredTrieInput>,
}

/// Trie input bundled with its anchor hash.
///
/// The `trie_input` contains the **cumulative** overlay of all in-memory ancestor blocks,
/// not just this block's changes. Child blocks reuse the parent's overlay in O(1) by
/// cloning the Arc-wrapped data.
///
/// The `anchor_hash` is metadata indicating which persisted base state this overlay
/// sits on top of. It is CRITICAL for overlay reuse decisions: an overlay built on top
/// of Anchor A cannot be reused for a block anchored to Anchor B, as it would result
/// in an incorrect state.
#[derive(Clone, Debug)]
pub struct AnchoredTrieInput {
/// The persisted ancestor hash this trie input is anchored to.
pub anchor_hash: B256,
/// Cumulative trie input overlay from all in-memory ancestors.
pub trie_input: Arc<TrieInputSorted>,
}

/// Metrics for deferred trie computation.
#[derive(Metrics)]
#[metrics(scope = "sync.block_validation")]
struct DeferredTrieMetrics {
/// Number of times deferred trie data was ready (async task completed first).
deferred_trie_async_ready: Counter,
/// Number of times deferred trie data required synchronous computation (fallback path).
deferred_trie_sync_fallback: Counter,
}

static DEFERRED_TRIE_METRICS: LazyLock<DeferredTrieMetrics> =
LazyLock::new(DeferredTrieMetrics::default);

/// Internal state for deferred trie data.
enum DeferredState {
/// Data is not yet available; raw inputs stored for fallback computation.
/// Wrapped in `Option` to allow taking ownership during computation.
Pending(Option<PendingInputs>),
/// Data has been computed and is ready.
Ready(ComputedTrieData),
}

/// Inputs kept while a deferred trie computation is pending.
#[derive(Clone, Debug)]
struct PendingInputs {
/// Unsorted hashed post-state from execution.
hashed_state: Arc<HashedPostState>,
/// Unsorted trie updates from state root computation.
trie_updates: Arc<TrieUpdates>,
/// The persisted ancestor hash this trie input is anchored to.
anchor_hash: B256,
/// Deferred trie data from ancestor blocks for merging.
ancestors: Vec<DeferredTrieData>,
}

impl fmt::Debug for DeferredTrieData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let state = self.state.lock();
Expand Down Expand Up @@ -299,6 +233,19 @@ impl DeferredTrieData {
}
}

/// Sorted trie data computed for an executed block.
/// These represent the complete set of sorted trie data required to persist
/// block state for, and generate proofs on top of, a block.
#[derive(Clone, Debug, Default)]
pub struct ComputedTrieData {
/// Sorted hashed post-state produced by execution.
pub hashed_state: Arc<HashedPostStateSorted>,
/// Sorted trie updates produced by state root computation.
pub trie_updates: Arc<TrieUpdatesSorted>,
/// Trie input bundled with its anchor hash, if available.
pub anchored_trie_input: Option<AnchoredTrieInput>,
}

impl ComputedTrieData {
/// Construct a bundle that includes trie input anchored to a persisted ancestor.
pub const fn with_trie_input(
Expand Down Expand Up @@ -340,6 +287,59 @@ impl ComputedTrieData {
}
}

/// Trie input bundled with its anchor hash.
///
/// The `trie_input` contains the **cumulative** overlay of all in-memory ancestor blocks,
/// not just this block's changes. Child blocks reuse the parent's overlay in O(1) by
/// cloning the Arc-wrapped data.
///
/// The `anchor_hash` is metadata indicating which persisted base state this overlay
/// sits on top of. It is CRITICAL for overlay reuse decisions: an overlay built on top
/// of Anchor A cannot be reused for a block anchored to Anchor B, as it would result
/// in an incorrect state.
#[derive(Clone, Debug)]
pub struct AnchoredTrieInput {
/// The persisted ancestor hash this trie input is anchored to.
pub anchor_hash: B256,
/// Cumulative trie input overlay from all in-memory ancestors.
pub trie_input: Arc<TrieInputSorted>,
}

/// Metrics for deferred trie computation.
#[derive(Metrics)]
#[metrics(scope = "sync.block_validation")]
struct DeferredTrieMetrics {
/// Number of times deferred trie data was ready (async task completed first).
deferred_trie_async_ready: Counter,
/// Number of times deferred trie data required synchronous computation (fallback path).
deferred_trie_sync_fallback: Counter,
}

static DEFERRED_TRIE_METRICS: LazyLock<DeferredTrieMetrics> =
LazyLock::new(DeferredTrieMetrics::default);

/// Internal state for deferred trie data.
enum DeferredState {
/// Data is not yet available; raw inputs stored for fallback computation.
/// Wrapped in `Option` to allow taking ownership during computation.
Pending(Option<PendingInputs>),
/// Data has been computed and is ready.
Ready(ComputedTrieData),
}

/// Inputs kept while a deferred trie computation is pending.
#[derive(Clone, Debug)]
struct PendingInputs {
/// Unsorted hashed post-state from execution.
hashed_state: Arc<HashedPostState>,
/// Unsorted trie updates from state root computation.
trie_updates: Arc<TrieUpdates>,
/// The persisted ancestor hash this trie input is anchored to.
anchor_hash: B256,
/// Deferred trie data from ancestor blocks for merging.
ancestors: Vec<DeferredTrieData>,
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
Loading