stratus/eth/storage/
mod.rs

1//! Ethereum / EVM storage.
2
3use cache::CacheConfig;
4pub use cache::StorageCache;
5pub use permanent::PermanentStorageConfig;
6pub use permanent::RocksPermanentStorage;
7pub use stratus_storage::StratusStorage;
8pub use temporary::InMemoryTemporaryStorage;
9pub use temporary::TemporaryStorageConfig;
10
11mod cache;
12pub mod permanent;
13mod stratus_storage;
14mod temporary;
15
16use std::collections::HashMap;
17use std::sync::Arc;
18
19use clap::Parser;
20use display_json::DebugAsJson;
21pub use temporary::compute_pending_block_number;
22
23use crate::eth::primitives::Account;
24use crate::eth::primitives::Address;
25use crate::eth::primitives::BlockNumber;
26use crate::eth::primitives::Slot;
27use crate::eth::primitives::SlotIndex;
28use crate::eth::primitives::StratusError;
29#[derive(Debug, Clone)]
30pub struct AccountWithSlots {
31    pub info: Account,
32    pub slots: HashMap<SlotIndex, Slot, hash_hasher::HashBuildHasher>,
33}
34
35impl AccountWithSlots {
36    /// Creates a new temporary account.
37    fn new(address: Address) -> Self {
38        Self {
39            info: Account::new_empty(address),
40            slots: HashMap::default(),
41        }
42    }
43}
44
45// -----------------------------------------------------------------------------
46// Config
47// -----------------------------------------------------------------------------
48
49/// Configuration that can be used by any binary that interacts with Stratus storage.
50#[derive(Parser, DebugAsJson, Clone, serde::Serialize)]
51pub struct StorageConfig {
52    #[clap(flatten)]
53    pub temp_storage: TemporaryStorageConfig,
54
55    #[clap(flatten)]
56    pub perm_storage: PermanentStorageConfig,
57
58    #[clap(flatten)]
59    pub cache: CacheConfig,
60}
61
62impl StorageConfig {
63    /// Initializes Stratus storage.
64    pub fn init(&self) -> Result<Arc<StratusStorage>, StratusError> {
65        let perm_storage = self.perm_storage.init()?;
66        let temp_storage = self.temp_storage.init(&perm_storage)?;
67        let cache = self.cache.init();
68
69        let storage = StratusStorage::new(
70            temp_storage,
71            perm_storage,
72            cache,
73            #[cfg(feature = "dev")]
74            self.perm_storage.clone(),
75        )?;
76
77        Ok(Arc::new(storage))
78    }
79}
80
81#[derive(Clone, Copy, PartialEq, Debug, serde::Serialize, serde::Deserialize, fake::Dummy, Eq)]
82pub enum TxCount {
83    Full,
84    Partial(u64),
85}
86
87impl From<u64> for TxCount {
88    fn from(value: u64) -> Self {
89        TxCount::Partial(value)
90    }
91}
92
93impl Default for TxCount {
94    fn default() -> Self {
95        TxCount::Partial(0)
96    }
97}
98
99impl std::ops::AddAssign<u64> for TxCount {
100    fn add_assign(&mut self, rhs: u64) {
101        match self {
102            TxCount::Full => {}                       // If it's Full, keep it Full
103            TxCount::Partial(count) => *count += rhs, // If it's Partial, increment the counter
104        }
105    }
106}
107
108impl Ord for TxCount {
109    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
110        match (self, other) {
111            (TxCount::Full, TxCount::Full) => std::cmp::Ordering::Equal,
112            (TxCount::Full, TxCount::Partial(_)) => std::cmp::Ordering::Greater,
113            (TxCount::Partial(_), TxCount::Full) => std::cmp::Ordering::Less,
114            (TxCount::Partial(a), TxCount::Partial(b)) => a.cmp(b),
115        }
116    }
117}
118
119impl PartialOrd for TxCount {
120    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
121        Some(self.cmp(other))
122    }
123}
124
125#[derive(Clone, Copy, serde::Serialize, serde::Deserialize, PartialEq, Default, fake::Dummy)]
126pub enum ReadKind {
127    Call((BlockNumber, TxCount)),
128    #[default]
129    Transaction,
130    RPC,
131}