revm_database/states/
state_builder.rs1use crate::states::block_hash_cache::BlockHashCache;
2
3use super::{cache::CacheState, state::DBBox, BundleState, State, TransitionState};
4use database_interface::{
5 bal::BalState, DBErrorMarker, Database, DatabaseRef, EmptyDB, WrapDatabaseRef,
6};
7use state::bal::Bal;
8use std::sync::Arc;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct StateBuilder<DB> {
13 database: DB,
15 with_state_clear: bool,
19 with_bundle_prestate: Option<BundleState>,
22 with_cache_prestate: Option<CacheState>,
24 with_bundle_update: bool,
28 with_background_transition_merge: bool,
34 with_block_hashes: BlockHashCache,
36 bal_state: BalState,
38}
39
40impl StateBuilder<EmptyDB> {
41 pub fn new() -> Self {
46 Self::default()
47 }
48}
49
50impl<DB: Database + Default> Default for StateBuilder<DB> {
51 fn default() -> Self {
52 Self::new_with_database(DB::default())
53 }
54}
55
56impl<DB: Database> StateBuilder<DB> {
57 pub fn new_with_database(database: DB) -> Self {
59 Self {
60 database,
61 with_state_clear: true,
62 with_cache_prestate: None,
63 with_bundle_prestate: None,
64 with_bundle_update: false,
65 with_background_transition_merge: false,
66 with_block_hashes: BlockHashCache::new(),
67 bal_state: BalState::default(),
68 }
69 }
70
71 pub fn with_database<ODB: Database>(self, database: ODB) -> StateBuilder<ODB> {
73 StateBuilder {
76 with_state_clear: self.with_state_clear,
77 database,
78 with_cache_prestate: self.with_cache_prestate,
79 with_bundle_prestate: self.with_bundle_prestate,
80 with_bundle_update: self.with_bundle_update,
81 with_background_transition_merge: self.with_background_transition_merge,
82 with_block_hashes: self.with_block_hashes,
83 bal_state: self.bal_state,
84 }
85 }
86
87 pub fn with_database_ref<ODB: DatabaseRef>(
89 self,
90 database: ODB,
91 ) -> StateBuilder<WrapDatabaseRef<ODB>> {
92 self.with_database(WrapDatabaseRef(database))
93 }
94
95 pub fn with_database_boxed<Error: DBErrorMarker>(
97 self,
98 database: DBBox<'_, Error>,
99 ) -> StateBuilder<DBBox<'_, Error>> {
100 self.with_database(database)
101 }
102
103 pub fn without_state_clear(self) -> Self {
106 Self {
107 with_state_clear: false,
108 ..self
109 }
110 }
111
112 pub fn with_bundle_prestate(self, bundle: BundleState) -> Self {
121 Self {
122 with_bundle_prestate: Some(bundle),
123 ..self
124 }
125 }
126
127 pub fn with_bundle_update(self) -> Self {
132 Self {
133 with_bundle_update: true,
134 ..self
135 }
136 }
137
138 pub fn with_cached_prestate(self, cache: CacheState) -> Self {
146 Self {
147 with_cache_prestate: Some(cache),
148 ..self
149 }
150 }
151
152 pub fn with_background_transition_merge(self) -> Self {
155 Self {
156 with_background_transition_merge: true,
157 ..self
158 }
159 }
160
161 pub fn with_block_hashes(self, block_hashes: BlockHashCache) -> Self {
163 Self {
164 with_block_hashes: block_hashes,
165 ..self
166 }
167 }
168
169 pub fn with_bal(mut self, bal: Arc<Bal>) -> Self {
171 self.bal_state.bal = Some(bal);
172 self
173 }
174
175 pub fn with_bal_builder(mut self) -> Self {
177 self.bal_state.bal_builder = Some(Bal::new());
178 self
179 }
180
181 pub fn build(mut self) -> State<DB> {
183 let use_preloaded_bundle = if self.with_cache_prestate.is_some() {
184 self.with_bundle_prestate = None;
185 false
186 } else {
187 self.with_bundle_prestate.is_some()
188 };
189 State {
190 cache: self
191 .with_cache_prestate
192 .unwrap_or_else(|| CacheState::new(self.with_state_clear)),
193 database: self.database,
194 transition_state: self.with_bundle_update.then(TransitionState::default),
195 bundle_state: self.with_bundle_prestate.unwrap_or_default(),
196 use_preloaded_bundle,
197 block_hashes: self.with_block_hashes,
198 bal_state: self.bal_state,
199 }
200 }
201}