revm_database/states/
state_builder.rs1use super::{cache::CacheState, state::DBBox, BundleState, State, TransitionState};
2use database_interface::{
3 bal::BalState, DBErrorMarker, Database, DatabaseRef, EmptyDB, WrapDatabaseRef,
4};
5use primitives::B256;
6use state::bal::Bal;
7use std::{collections::BTreeMap, sync::Arc};
8
9#[derive(Clone, Debug, PartialEq, Eq)]
11pub struct StateBuilder<DB> {
12 database: DB,
14 with_state_clear: bool,
18 with_bundle_prestate: Option<BundleState>,
21 with_cache_prestate: Option<CacheState>,
23 with_bundle_update: bool,
27 with_background_transition_merge: bool,
33 with_block_hashes: BTreeMap<u64, B256>,
35 bal_state: BalState,
37}
38
39impl StateBuilder<EmptyDB> {
40 pub fn new() -> Self {
45 Self::default()
46 }
47}
48
49impl<DB: Database + Default> Default for StateBuilder<DB> {
50 fn default() -> Self {
51 Self::new_with_database(DB::default())
52 }
53}
54
55impl<DB: Database> StateBuilder<DB> {
56 pub fn new_with_database(database: DB) -> Self {
58 Self {
59 database,
60 with_state_clear: true,
61 with_cache_prestate: None,
62 with_bundle_prestate: None,
63 with_bundle_update: false,
64 with_background_transition_merge: false,
65 with_block_hashes: BTreeMap::new(),
66 bal_state: BalState::default(),
67 }
68 }
69
70 pub fn with_database<ODB: Database>(self, database: ODB) -> StateBuilder<ODB> {
72 StateBuilder {
75 with_state_clear: self.with_state_clear,
76 database,
77 with_cache_prestate: self.with_cache_prestate,
78 with_bundle_prestate: self.with_bundle_prestate,
79 with_bundle_update: self.with_bundle_update,
80 with_background_transition_merge: self.with_background_transition_merge,
81 with_block_hashes: self.with_block_hashes,
82 bal_state: self.bal_state,
83 }
84 }
85
86 pub fn with_database_ref<ODB: DatabaseRef>(
88 self,
89 database: ODB,
90 ) -> StateBuilder<WrapDatabaseRef<ODB>> {
91 self.with_database(WrapDatabaseRef(database))
92 }
93
94 pub fn with_database_boxed<Error: DBErrorMarker>(
96 self,
97 database: DBBox<'_, Error>,
98 ) -> StateBuilder<DBBox<'_, Error>> {
99 self.with_database(database)
100 }
101
102 pub fn without_state_clear(self) -> Self {
105 Self {
106 with_state_clear: false,
107 ..self
108 }
109 }
110
111 pub fn with_bundle_prestate(self, bundle: BundleState) -> Self {
120 Self {
121 with_bundle_prestate: Some(bundle),
122 ..self
123 }
124 }
125
126 pub fn with_bundle_update(self) -> Self {
131 Self {
132 with_bundle_update: true,
133 ..self
134 }
135 }
136
137 pub fn with_cached_prestate(self, cache: CacheState) -> Self {
145 Self {
146 with_cache_prestate: Some(cache),
147 ..self
148 }
149 }
150
151 pub fn with_background_transition_merge(self) -> Self {
154 Self {
155 with_background_transition_merge: true,
156 ..self
157 }
158 }
159
160 pub fn with_block_hashes(self, block_hashes: BTreeMap<u64, B256>) -> Self {
162 Self {
163 with_block_hashes: block_hashes,
164 ..self
165 }
166 }
167
168 pub fn with_bal(mut self, bal: Arc<Bal>) -> Self {
170 self.bal_state.bal = Some(bal);
171 self
172 }
173
174 pub fn with_bal_builder(mut self) -> Self {
176 self.bal_state.bal_builder = Some(Bal::new());
177 self
178 }
179
180 pub fn build(mut self) -> State<DB> {
182 let use_preloaded_bundle = if self.with_cache_prestate.is_some() {
183 self.with_bundle_prestate = None;
184 false
185 } else {
186 self.with_bundle_prestate.is_some()
187 };
188 State {
189 cache: self
190 .with_cache_prestate
191 .unwrap_or_else(|| CacheState::new(self.with_state_clear)),
192 database: self.database,
193 transition_state: self.with_bundle_update.then(TransitionState::default),
194 bundle_state: self.with_bundle_prestate.unwrap_or_default(),
195 use_preloaded_bundle,
196 block_hashes: self.with_block_hashes,
197 bal_state: self.bal_state,
198 }
199 }
200}