revm_database/states/
transition_state.rs1use std::borrow::Cow;
2
3use super::{StorageSlot, TransitionAccount};
4use primitives::{hash_map::Entry, Address, AddressMap, HashMap};
5use state::EvmStorage;
6
7#[derive(Clone, Default, Debug, PartialEq, Eq)]
9pub struct TransitionState {
10 pub transitions: AddressMap<TransitionAccount>,
12}
13
14impl TransitionState {
15 pub fn single(address: Address, transition: TransitionAccount) -> Self {
17 let mut transitions = HashMap::default();
18 transitions.insert(address, transition);
19 TransitionState { transitions }
20 }
21
22 pub fn take(&mut self) -> TransitionState {
27 core::mem::take(self)
28 }
29
30 pub fn clear(&mut self) {
32 self.transitions.clear();
33 }
34
35 pub fn add_transitions<'a>(
40 &mut self,
41 transitions: impl IntoIterator<Item = (Address, TransitionAccount<Option<Cow<'a, EvmStorage>>>)>,
42 ) {
43 let transitions = transitions.into_iter();
44 if let Some(upper) = transitions.size_hint().1 {
45 self.transitions.reserve(upper);
46 }
47 for (address, account) in transitions {
48 self.add_transition(address, account);
49 }
50 }
51
52 pub fn add_transition(
54 &mut self,
55 address: Address,
56 account: TransitionAccount<Option<Cow<'_, EvmStorage>>>,
57 ) {
58 match self.transitions.entry(address) {
59 Entry::Occupied(entry) => entry.into_mut().update(account),
60 Entry::Vacant(entry) => {
61 _ = entry.insert(account.map_storage(|storage| {
62 storage
63 .map(|storage| {
64 storage
65 .iter()
66 .filter_map(|(key, slot)| {
67 slot.is_changed().then_some((
68 *key,
69 StorageSlot::new_changed(
70 slot.original_value,
71 slot.present_value,
72 ),
73 ))
74 })
75 .collect()
76 })
77 .unwrap_or_default()
78 }))
79 }
80 }
81 }
82}