stratus/eth/storage/
mod.rs

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