stratus/eth/storage/temporary/inmemory/
mod.rs

1//! In-memory storage implementations.
2
3use crate::eth::primitives::Account;
4use crate::eth::primitives::Address;
5use crate::eth::primitives::BlockNumber;
6#[cfg(feature = "dev")]
7use crate::eth::primitives::Bytes;
8use crate::eth::primitives::ExecutionChanges;
9use crate::eth::primitives::ExternalBlock;
10use crate::eth::primitives::Hash;
11#[cfg(feature = "dev")]
12use crate::eth::primitives::Nonce;
13use crate::eth::primitives::PendingBlock;
14use crate::eth::primitives::PendingBlockHeader;
15use crate::eth::primitives::Slot;
16use crate::eth::primitives::SlotIndex;
17use crate::eth::primitives::StorageError;
18use crate::eth::primitives::TransactionExecution;
19#[cfg(feature = "dev")]
20use crate::eth::primitives::Wei;
21use crate::eth::storage::ReadKind;
22use crate::eth::storage::TxCount;
23use crate::eth::storage::temporary::inmemory::call::InMemoryCallTemporaryStorage;
24use crate::eth::storage::temporary::inmemory::transaction::InmemoryTransactionTemporaryStorage;
25
26mod call;
27mod transaction;
28
29#[derive(Debug)]
30pub struct InMemoryTemporaryStorage {
31    pub transaction_storage: InmemoryTransactionTemporaryStorage,
32    pub call_storage: InMemoryCallTemporaryStorage,
33}
34
35impl InMemoryTemporaryStorage {
36    pub fn new(block_number: BlockNumber) -> Self {
37        Self {
38            transaction_storage: InmemoryTransactionTemporaryStorage::new(block_number),
39            call_storage: InMemoryCallTemporaryStorage::new(),
40        }
41    }
42
43    pub fn read_pending_block_header(&self) -> (PendingBlockHeader, TxCount) {
44        self.transaction_storage.read_pending_block_header()
45    }
46
47    #[cfg(feature = "dev")]
48    pub fn set_pending_block_header(&self, block_number: BlockNumber) -> anyhow::Result<(), StorageError> {
49        self.transaction_storage.set_pending_block_header(block_number)
50    }
51
52    pub fn set_pending_from_external(&self, block: &ExternalBlock) {
53        self.transaction_storage.set_pending_from_external(block);
54    }
55
56    pub fn save_pending_execution(&self, tx: TransactionExecution) -> Result<(), StorageError> {
57        self.call_storage.update_state_with_transaction(&tx);
58        self.transaction_storage.save_pending_execution(tx)
59    }
60
61    pub fn read_pending_executions(&self) -> Vec<TransactionExecution> {
62        self.transaction_storage.read_pending_executions()
63    }
64
65    pub fn finish_pending_block(&self) -> anyhow::Result<(PendingBlock, ExecutionChanges), StorageError> {
66        self.call_storage.retain_recent_blocks();
67        self.transaction_storage.finish_pending_block()
68    }
69
70    pub fn read_pending_execution(&self, hash: Hash) -> anyhow::Result<Option<TransactionExecution>, StorageError> {
71        self.transaction_storage.read_pending_execution(hash)
72    }
73
74    pub fn read_account(&self, address: Address, kind: ReadKind) -> anyhow::Result<Option<Account>, StorageError> {
75        match kind {
76            ReadKind::Call((block_number, tx_count)) => Ok(self.call_storage.read_account(block_number, tx_count, address)),
77            _ => self.transaction_storage.read_account(address),
78        }
79    }
80
81    pub fn read_slot(&self, address: Address, index: SlotIndex, kind: ReadKind) -> anyhow::Result<Option<Slot>, StorageError> {
82        match kind {
83            ReadKind::Call((block_number, tx_count)) => Ok(self.call_storage.read_slot(block_number, tx_count, address, index)),
84            _ => self.transaction_storage.read_slot(address, index),
85        }
86    }
87
88    #[cfg(feature = "dev")]
89    pub fn save_slot(&self, address: Address, slot: Slot) -> anyhow::Result<(), StorageError> {
90        self.transaction_storage.save_slot(address, slot)
91    }
92
93    #[cfg(feature = "dev")]
94    pub fn save_account_nonce(&self, address: Address, nonce: Nonce) -> anyhow::Result<(), StorageError> {
95        self.transaction_storage.save_account_nonce(address, nonce)
96    }
97
98    #[cfg(feature = "dev")]
99    pub fn save_account_balance(&self, address: Address, balance: Wei) -> anyhow::Result<(), StorageError> {
100        self.transaction_storage.save_account_balance(address, balance)
101    }
102
103    #[cfg(feature = "dev")]
104    pub fn save_account_code(&self, address: Address, code: Bytes) -> anyhow::Result<(), StorageError> {
105        self.transaction_storage.save_account_code(address, code)
106    }
107
108    pub fn reset(&self) -> anyhow::Result<(), StorageError> {
109        self.call_storage.reset();
110        self.transaction_storage.reset()
111    }
112}
113
114// -----------------------------------------------------------------------------
115// Inner State
116// -----------------------------------------------------------------------------
117
118#[derive(Debug, Clone)]
119pub struct InMemoryTemporaryStorageState {
120    /// Block that is being mined.
121    pub block: PendingBlock,
122
123    /// Last state of accounts and slots. Can be recreated from the executions inside the pending block.
124    pub block_changes: ExecutionChanges,
125}
126
127impl InMemoryTemporaryStorageState {
128    pub fn new(block_number: BlockNumber) -> Self {
129        Self {
130            block: PendingBlock::new_at_now(block_number),
131            block_changes: ExecutionChanges::default(),
132        }
133    }
134
135    pub fn reset(&mut self) {
136        self.block = PendingBlock::new_at_now(1.into());
137        self.block_changes = ExecutionChanges::default();
138    }
139}