revm_database/states/
state_builder.rs1use super::{cache::CacheState, state::DBBox, BundleState, State, TransitionState};
2use database_interface::{DBErrorMarker, Database, DatabaseRef, EmptyDB, WrapDatabaseRef};
3use primitives::B256;
4use std::collections::BTreeMap;
5
6#[derive(Clone, Debug, PartialEq, Eq)]
8pub struct StateBuilder<DB> {
9 database: DB,
11 with_state_clear: bool,
15 with_bundle_prestate: Option<BundleState>,
18 with_cache_prestate: Option<CacheState>,
20 with_bundle_update: bool,
24 with_background_transition_merge: bool,
30 with_block_hashes: BTreeMap<u64, B256>,
32}
33
34impl StateBuilder<EmptyDB> {
35 pub fn new() -> Self {
40 Self::default()
41 }
42}
43
44impl<DB: Database + Default> Default for StateBuilder<DB> {
45 fn default() -> Self {
46 Self::new_with_database(DB::default())
47 }
48}
49
50impl<DB: Database> StateBuilder<DB> {
51 pub fn new_with_database(database: DB) -> Self {
53 Self {
54 database,
55 with_state_clear: true,
56 with_cache_prestate: None,
57 with_bundle_prestate: None,
58 with_bundle_update: false,
59 with_background_transition_merge: false,
60 with_block_hashes: BTreeMap::new(),
61 }
62 }
63
64 pub fn with_database<ODB: Database>(self, database: ODB) -> StateBuilder<ODB> {
66 StateBuilder {
69 with_state_clear: self.with_state_clear,
70 database,
71 with_cache_prestate: self.with_cache_prestate,
72 with_bundle_prestate: self.with_bundle_prestate,
73 with_bundle_update: self.with_bundle_update,
74 with_background_transition_merge: self.with_background_transition_merge,
75 with_block_hashes: self.with_block_hashes,
76 }
77 }
78
79 pub fn with_database_ref<ODB: DatabaseRef>(
81 self,
82 database: ODB,
83 ) -> StateBuilder<WrapDatabaseRef<ODB>> {
84 self.with_database(WrapDatabaseRef(database))
85 }
86
87 pub fn with_database_boxed<Error: DBErrorMarker + core::error::Error>(
89 self,
90 database: DBBox<'_, Error>,
91 ) -> StateBuilder<DBBox<'_, Error>> {
92 self.with_database(database)
93 }
94
95 pub fn without_state_clear(self) -> Self {
98 Self {
99 with_state_clear: false,
100 ..self
101 }
102 }
103
104 pub fn with_bundle_prestate(self, bundle: BundleState) -> Self {
113 Self {
114 with_bundle_prestate: Some(bundle),
115 ..self
116 }
117 }
118
119 pub fn with_bundle_update(self) -> Self {
124 Self {
125 with_bundle_update: true,
126 ..self
127 }
128 }
129
130 pub fn with_cached_prestate(self, cache: CacheState) -> Self {
138 Self {
139 with_cache_prestate: Some(cache),
140 ..self
141 }
142 }
143
144 pub fn with_background_transition_merge(self) -> Self {
147 Self {
148 with_background_transition_merge: true,
149 ..self
150 }
151 }
152
153 pub fn with_block_hashes(self, block_hashes: BTreeMap<u64, B256>) -> Self {
154 Self {
155 with_block_hashes: block_hashes,
156 ..self
157 }
158 }
159
160 pub fn build(mut self) -> State<DB> {
161 let use_preloaded_bundle = if self.with_cache_prestate.is_some() {
162 self.with_bundle_prestate = None;
163 false
164 } else {
165 self.with_bundle_prestate.is_some()
166 };
167 State {
168 cache: self
169 .with_cache_prestate
170 .unwrap_or_else(|| CacheState::new(self.with_state_clear)),
171 database: self.database,
172 transition_state: self.with_bundle_update.then(TransitionState::default),
173 bundle_state: self.with_bundle_prestate.unwrap_or_default(),
174 use_preloaded_bundle,
175 block_hashes: self.with_block_hashes,
176 }
177 }
178}