use crate::db::sync::ConcurrentState;
use revm::{
database::{
states::{BundleState, TransitionState},
DatabaseRef, EmptyDB,
},
primitives::B256,
};
use std::collections::BTreeMap;
use super::{ConcurrentCacheState, ConcurrentStateInfo};
#[derive(Clone, Debug)]
pub struct ConcurrentStateBuilder<Db> {
database: Db,
with_state_clear: bool,
with_bundle_prestate: Option<BundleState>,
with_cache_prestate: Option<ConcurrentCacheState>,
with_bundle_update: bool,
with_background_transition_merge: bool,
with_block_hashes: BTreeMap<u64, B256>,
}
impl ConcurrentStateBuilder<EmptyDB> {
pub fn new() -> Self {
Self::default()
}
}
impl<Db: DatabaseRef + Sync + Default> Default for ConcurrentStateBuilder<Db> {
fn default() -> Self {
Self::new_with_database(Db::default())
}
}
impl<Db: DatabaseRef + Sync> ConcurrentStateBuilder<Db> {
pub const fn new_with_database(database: Db) -> Self {
Self {
database,
with_state_clear: true,
with_cache_prestate: None,
with_bundle_prestate: None,
with_bundle_update: false,
with_background_transition_merge: false,
with_block_hashes: BTreeMap::new(),
}
}
pub fn with_database<ODb: DatabaseRef + Sync>(
self,
database: ODb,
) -> ConcurrentStateBuilder<ODb> {
ConcurrentStateBuilder {
with_state_clear: self.with_state_clear,
database,
with_cache_prestate: self.with_cache_prestate,
with_bundle_prestate: self.with_bundle_prestate,
with_bundle_update: self.with_bundle_update,
with_background_transition_merge: self.with_background_transition_merge,
with_block_hashes: self.with_block_hashes,
}
}
pub fn with_database_ref<ODb: DatabaseRef + Sync>(
self,
database: ODb,
) -> ConcurrentStateBuilder<ODb> {
self.with_database(database)
}
pub fn without_state_clear(self) -> Self {
Self { with_state_clear: false, ..self }
}
pub fn with_bundle_prestate(self, bundle: BundleState) -> Self {
Self { with_bundle_prestate: Some(bundle), ..self }
}
pub fn with_bundle_update(self) -> Self {
Self { with_bundle_update: true, ..self }
}
pub fn with_cached_prestate(self, cache: impl Into<ConcurrentCacheState>) -> Self {
Self { with_cache_prestate: Some(cache.into()), ..self }
}
pub fn with_background_transition_merge(self) -> Self {
Self { with_background_transition_merge: true, ..self }
}
pub fn with_block_hashes(self, block_hashes: BTreeMap<u64, B256>) -> Self {
Self { with_block_hashes: block_hashes, ..self }
}
pub fn build(mut self) -> ConcurrentState<Db> {
let use_preloaded_bundle = if self.with_cache_prestate.is_some() {
self.with_bundle_prestate = None;
false
} else {
self.with_bundle_prestate.is_some()
};
ConcurrentState::new(
self.database,
ConcurrentStateInfo {
cache: self
.with_cache_prestate
.unwrap_or_else(|| ConcurrentCacheState::new(self.with_state_clear)),
transition_state: self.with_bundle_update.then(TransitionState::default),
bundle_state: self.with_bundle_prestate.unwrap_or_default(),
use_preloaded_bundle,
block_hashes: self.with_block_hashes.into(),
},
)
}
}