1use crate::context::{SStoreResult, SelfDestructResult};
3use core::ops::{Deref, DerefMut};
4use database_interface::Database;
5use primitives::{
6 hardfork::SpecId, Address, Bytes, HashSet, Log, StorageKey, StorageValue, B256, U256,
7};
8use state::{Account, Bytecode};
9use std::vec::Vec;
10
11pub trait JournalTr {
13 type Database: Database;
15 type State;
17
18 fn new(database: Self::Database) -> Self;
22
23 fn db_mut(&mut self) -> &mut Self::Database;
25
26 fn db(&self) -> &Self::Database;
28
29 fn sload(
33 &mut self,
34 address: Address,
35 key: StorageKey,
36 ) -> Result<StateLoad<StorageValue>, <Self::Database as Database>::Error>;
37
38 fn sstore(
40 &mut self,
41 address: Address,
42 key: StorageKey,
43 value: StorageValue,
44 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error>;
45
46 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
48
49 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
51
52 fn log(&mut self, log: Log);
54
55 fn selfdestruct(
57 &mut self,
58 address: Address,
59 target: Address,
60 ) -> Result<StateLoad<SelfDestructResult>, <Self::Database as Database>::Error>;
61
62 fn warm_account_and_storage(
64 &mut self,
65 address: Address,
66 storage_keys: impl IntoIterator<Item = StorageKey>,
67 ) -> Result<(), <Self::Database as Database>::Error>;
68
69 fn warm_account(&mut self, address: Address);
71
72 fn warm_coinbase_account(&mut self, address: Address);
74
75 fn warm_precompiles(&mut self, addresses: HashSet<Address>);
77
78 fn precompile_addresses(&self) -> &HashSet<Address>;
80
81 fn set_spec_id(&mut self, spec_id: SpecId);
83
84 fn touch_account(&mut self, address: Address);
86
87 fn transfer(
89 &mut self,
90 from: Address,
91 to: Address,
92 balance: U256,
93 ) -> Result<Option<TransferError>, <Self::Database as Database>::Error>;
94
95 fn caller_accounting_journal_entry(
97 &mut self,
98 address: Address,
99 old_balance: U256,
100 bump_nonce: bool,
101 );
102
103 fn balance_incr(
105 &mut self,
106 address: Address,
107 balance: U256,
108 ) -> Result<(), <Self::Database as Database>::Error>;
109
110 fn nonce_bump_journal_entry(&mut self, address: Address);
112
113 fn load_account(
115 &mut self,
116 address: Address,
117 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
118
119 fn load_account_code(
121 &mut self,
122 address: Address,
123 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
124
125 fn load_account_delegated(
127 &mut self,
128 address: Address,
129 ) -> Result<StateLoad<AccountLoad>, <Self::Database as Database>::Error>;
130
131 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
133
134 #[inline]
138 fn set_code(&mut self, address: Address, code: Bytecode) {
139 let hash = code.hash_slow();
140 self.set_code_with_hash(address, code, hash);
141 }
142
143 #[inline]
145 fn code(
146 &mut self,
147 address: Address,
148 ) -> Result<StateLoad<Bytes>, <Self::Database as Database>::Error> {
149 let a = self.load_account_code(address)?;
150 let code = a.info.code.as_ref().unwrap();
152 let code = code.original_bytes();
153
154 Ok(StateLoad::new(code, a.is_cold))
155 }
156
157 fn code_hash(
159 &mut self,
160 address: Address,
161 ) -> Result<StateLoad<B256>, <Self::Database as Database>::Error> {
162 let acc = self.load_account_code(address)?;
163 if acc.is_empty() {
164 return Ok(StateLoad::new(B256::ZERO, acc.is_cold));
165 }
166 let _code = acc.info.code.as_ref().unwrap();
168
169 let hash = acc.info.code_hash;
170
171 Ok(StateLoad::new(hash, acc.is_cold))
172 }
173
174 fn clear(&mut self) {
176 let _ = self.finalize();
177 }
178
179 fn checkpoint(&mut self) -> JournalCheckpoint;
182
183 fn checkpoint_commit(&mut self);
185
186 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint);
188
189 fn create_account_checkpoint(
191 &mut self,
192 caller: Address,
193 address: Address,
194 balance: U256,
195 spec_id: SpecId,
196 ) -> Result<JournalCheckpoint, TransferError>;
197
198 fn depth(&self) -> usize;
200
201 fn take_logs(&mut self) -> Vec<Log>;
203
204 fn commit_tx(&mut self);
206
207 fn discard_tx(&mut self);
212
213 fn finalize(&mut self) -> Self::State;
215}
216
217#[derive(Copy, Clone, Debug, PartialEq, Eq)]
219pub enum TransferError {
220 OutOfFunds,
222 OverflowPayment,
224 CreateCollision,
226}
227
228#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
230#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
231pub struct JournalCheckpoint {
232 pub log_i: usize,
234 pub journal_i: usize,
236}
237
238#[derive(Clone, Debug, Default, PartialEq, Eq)]
240#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
241pub struct StateLoad<T> {
242 pub data: T,
244 pub is_cold: bool,
246}
247
248impl<T> Deref for StateLoad<T> {
249 type Target = T;
250
251 fn deref(&self) -> &Self::Target {
252 &self.data
253 }
254}
255
256impl<T> DerefMut for StateLoad<T> {
257 fn deref_mut(&mut self) -> &mut Self::Target {
258 &mut self.data
259 }
260}
261
262impl<T> StateLoad<T> {
263 pub fn new(data: T, is_cold: bool) -> Self {
265 Self { data, is_cold }
266 }
267
268 pub fn map<B, F>(self, f: F) -> StateLoad<B>
272 where
273 F: FnOnce(T) -> B,
274 {
275 StateLoad::new(f(self.data), self.is_cold)
276 }
277}
278
279#[derive(Clone, Debug, Default, PartialEq, Eq)]
281#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
282pub struct AccountLoad {
283 pub is_delegate_account_cold: Option<bool>,
285 pub is_empty: bool,
287}