reth_trie_common/
input.rs

1use crate::{prefix_set::TriePrefixSetsMut, updates::TrieUpdates, HashedPostState};
2
3/// Inputs for trie-related computations.
4#[derive(Default, Debug, Clone)]
5pub struct TrieInput {
6    /// The collection of cached in-memory intermediate trie nodes that
7    /// can be reused for computation.
8    pub nodes: TrieUpdates,
9    /// The in-memory overlay hashed state.
10    pub state: HashedPostState,
11    /// The collection of prefix sets for the computation. Since the prefix sets _always_
12    /// invalidate the in-memory nodes, not all keys from `self.state` might be present here,
13    /// if we have cached nodes for them.
14    pub prefix_sets: TriePrefixSetsMut,
15}
16
17impl TrieInput {
18    /// Create new trie input.
19    pub const fn new(
20        nodes: TrieUpdates,
21        state: HashedPostState,
22        prefix_sets: TriePrefixSetsMut,
23    ) -> Self {
24        Self { nodes, state, prefix_sets }
25    }
26
27    /// Create new trie input from in-memory state. The prefix sets will be constructed and
28    /// set automatically.
29    pub fn from_state(state: HashedPostState) -> Self {
30        let prefix_sets = state.construct_prefix_sets();
31        Self { nodes: TrieUpdates::default(), state, prefix_sets }
32    }
33
34    /// Create new trie input from the provided blocks, from oldest to newest. See the documentation
35    /// for [`Self::extend_with_blocks`] for details.
36    pub fn from_blocks<'a>(
37        blocks: impl IntoIterator<Item = (&'a HashedPostState, Option<&'a TrieUpdates>)>,
38    ) -> Self {
39        let mut input = Self::default();
40        input.extend_with_blocks(blocks);
41        input
42    }
43
44    /// Extend the trie input with the provided blocks, from oldest to newest.
45    ///
46    /// For blocks with missing trie updates, the trie input will be extended with prefix sets
47    /// constructed from the state of this block and the state itself, **without** trie updates.
48    pub fn extend_with_blocks<'a>(
49        &mut self,
50        blocks: impl IntoIterator<Item = (&'a HashedPostState, Option<&'a TrieUpdates>)>,
51    ) {
52        for (hashed_state, trie_updates) in blocks {
53            if let Some(nodes) = trie_updates.as_ref() {
54                self.append_cached_ref(nodes, hashed_state);
55            } else {
56                self.append_ref(hashed_state);
57            }
58        }
59    }
60
61    /// Prepend another trie input to the current one.
62    pub fn prepend_self(&mut self, mut other: Self) {
63        core::mem::swap(&mut self.nodes, &mut other.nodes);
64        self.nodes.extend(other.nodes);
65        core::mem::swap(&mut self.state, &mut other.state);
66        self.state.extend(other.state);
67        // No need to swap prefix sets, as they will be sorted and deduplicated.
68        self.prefix_sets.extend(other.prefix_sets);
69    }
70
71    /// Prepend state to the input and extend the prefix sets.
72    pub fn prepend(&mut self, mut state: HashedPostState) {
73        self.prefix_sets.extend(state.construct_prefix_sets());
74        core::mem::swap(&mut self.state, &mut state);
75        self.state.extend(state);
76    }
77
78    /// Prepend intermediate nodes and state to the input.
79    /// Prefix sets for incoming state will be ignored.
80    pub fn prepend_cached(&mut self, mut nodes: TrieUpdates, mut state: HashedPostState) {
81        core::mem::swap(&mut self.nodes, &mut nodes);
82        self.nodes.extend(nodes);
83        core::mem::swap(&mut self.state, &mut state);
84        self.state.extend(state);
85    }
86
87    /// Append state to the input and extend the prefix sets.
88    pub fn append(&mut self, state: HashedPostState) {
89        self.prefix_sets.extend(state.construct_prefix_sets());
90        self.state.extend(state);
91    }
92
93    /// Append state to the input by reference and extend the prefix sets.
94    pub fn append_ref(&mut self, state: &HashedPostState) {
95        self.prefix_sets.extend(state.construct_prefix_sets());
96        self.state.extend_ref(state);
97    }
98
99    /// Append intermediate nodes and state to the input.
100    /// Prefix sets for incoming state will be ignored.
101    pub fn append_cached(&mut self, nodes: TrieUpdates, state: HashedPostState) {
102        self.nodes.extend(nodes);
103        self.state.extend(state);
104    }
105
106    /// Append intermediate nodes and state to the input by reference.
107    /// Prefix sets for incoming state will be ignored.
108    pub fn append_cached_ref(&mut self, nodes: &TrieUpdates, state: &HashedPostState) {
109        self.nodes.extend_ref(nodes);
110        self.state.extend_ref(state);
111    }
112
113    /// This method clears the trie input nodes, state, and prefix sets.
114    pub fn clear(&mut self) {
115        self.nodes.clear();
116        self.state.clear();
117        self.prefix_sets.clear();
118    }
119
120    /// This method returns a cleared version of this trie input.
121    pub fn cleared(mut self) -> Self {
122        self.clear();
123        self
124    }
125}