Skip to main content

revm_database/states/
transition_state.rs

1use super::TransitionAccount;
2use primitives::{hash_map::Entry, Address, AddressMap, HashMap};
3
4/// State of accounts in transition between transaction executions.
5#[derive(Clone, Default, Debug, PartialEq, Eq)]
6pub struct TransitionState {
7    /// Block state account with account state
8    pub transitions: AddressMap<TransitionAccount>,
9}
10
11impl TransitionState {
12    /// Create new transition state containing one [`TransitionAccount`].
13    pub fn single(address: Address, transition: TransitionAccount) -> Self {
14        let mut transitions = HashMap::default();
15        transitions.insert(address, transition);
16        TransitionState { transitions }
17    }
18
19    /// Take the contents of this [`TransitionState`] and replace it with an
20    /// empty one.
21    ///
22    /// See [core::mem::take].
23    pub fn take(&mut self) -> TransitionState {
24        core::mem::take(self)
25    }
26
27    /// Clear the transition state.
28    pub fn clear(&mut self) {
29        self.transitions.clear();
30    }
31
32    /// Add transitions to the transition state.
33    ///
34    /// This will insert new [`TransitionAccount`]s, or update existing ones via
35    /// [`update`][TransitionAccount::update].
36    pub fn add_transitions(
37        &mut self,
38        transitions: impl IntoIterator<Item = (Address, TransitionAccount)>,
39    ) {
40        let transitions = transitions.into_iter();
41        if let Some(upper) = transitions.size_hint().1 {
42            self.transitions.reserve(upper);
43        }
44        for (address, account) in transitions {
45            match self.transitions.entry(address) {
46                Entry::Occupied(entry) => entry.into_mut().update(account),
47                Entry::Vacant(entry) => _ = entry.insert(account),
48            }
49        }
50    }
51}