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(
71 &mut self,
72 address: Address,
73 ) -> Result<(), <Self::Database as Database>::Error> {
74 self.warm_account_and_storage(address, [])
75 }
76
77 fn warm_coinbase_account(&mut self, address: Address);
79
80 fn warm_precompiles(&mut self, addresses: HashSet<Address>);
82
83 fn precompile_addresses(&self) -> &HashSet<Address>;
85
86 fn set_spec_id(&mut self, spec_id: SpecId);
88
89 fn touch_account(&mut self, address: Address);
91
92 fn transfer(
94 &mut self,
95 from: Address,
96 to: Address,
97 balance: U256,
98 ) -> Result<Option<TransferError>, <Self::Database as Database>::Error>;
99
100 fn caller_accounting_journal_entry(
102 &mut self,
103 address: Address,
104 old_balance: U256,
105 bump_nonce: bool,
106 );
107
108 fn balance_incr(
110 &mut self,
111 address: Address,
112 balance: U256,
113 ) -> Result<(), <Self::Database as Database>::Error>;
114
115 fn nonce_bump_journal_entry(&mut self, address: Address);
117
118 fn load_account(
120 &mut self,
121 address: Address,
122 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
123
124 fn load_account_code(
126 &mut self,
127 address: Address,
128 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
129
130 fn load_account_delegated(
132 &mut self,
133 address: Address,
134 ) -> Result<StateLoad<AccountLoad>, <Self::Database as Database>::Error>;
135
136 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
138
139 #[inline]
143 fn set_code(&mut self, address: Address, code: Bytecode) {
144 let hash = code.hash_slow();
145 self.set_code_with_hash(address, code, hash);
146 }
147
148 #[inline]
150 fn code(
151 &mut self,
152 address: Address,
153 ) -> Result<StateLoad<Bytes>, <Self::Database as Database>::Error> {
154 let a = self.load_account_code(address)?;
155 let code = a.info.code.as_ref().unwrap();
157 let code = code.original_bytes();
158
159 Ok(StateLoad::new(code, a.is_cold))
160 }
161
162 fn code_hash(
164 &mut self,
165 address: Address,
166 ) -> Result<StateLoad<B256>, <Self::Database as Database>::Error> {
167 let acc = self.load_account_code(address)?;
168 if acc.is_empty() {
169 return Ok(StateLoad::new(B256::ZERO, acc.is_cold));
170 }
171 let _code = acc.info.code.as_ref().unwrap();
173
174 let hash = acc.info.code_hash;
175
176 Ok(StateLoad::new(hash, acc.is_cold))
177 }
178
179 fn clear(&mut self) {
181 let _ = self.finalize();
182 }
183
184 fn checkpoint(&mut self) -> JournalCheckpoint;
187
188 fn checkpoint_commit(&mut self);
190
191 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint);
193
194 fn create_account_checkpoint(
196 &mut self,
197 caller: Address,
198 address: Address,
199 balance: U256,
200 spec_id: SpecId,
201 ) -> Result<JournalCheckpoint, TransferError>;
202
203 fn depth(&self) -> usize;
205
206 fn take_logs(&mut self) -> Vec<Log>;
208
209 fn commit_tx(&mut self);
211
212 fn discard_tx(&mut self);
217
218 fn finalize(&mut self) -> Self::State;
220}
221
222#[derive(Copy, Clone, Debug, PartialEq, Eq)]
224pub enum TransferError {
225 OutOfFunds,
227 OverflowPayment,
229 CreateCollision,
231}
232
233#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
235#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
236pub struct JournalCheckpoint {
237 pub log_i: usize,
239 pub journal_i: usize,
241}
242
243#[derive(Clone, Debug, Default, PartialEq, Eq)]
245#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
246pub struct StateLoad<T> {
247 pub data: T,
249 pub is_cold: bool,
251}
252
253impl<T> Deref for StateLoad<T> {
254 type Target = T;
255
256 fn deref(&self) -> &Self::Target {
257 &self.data
258 }
259}
260
261impl<T> DerefMut for StateLoad<T> {
262 fn deref_mut(&mut self) -> &mut Self::Target {
263 &mut self.data
264 }
265}
266
267impl<T> StateLoad<T> {
268 pub fn new(data: T, is_cold: bool) -> Self {
270 Self { data, is_cold }
271 }
272
273 pub fn map<B, F>(self, f: F) -> StateLoad<B>
277 where
278 F: FnOnce(T) -> B,
279 {
280 StateLoad::new(f(self.data), self.is_cold)
281 }
282}
283
284#[derive(Clone, Debug, Default, PartialEq, Eq)]
286#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
287pub struct AccountLoad {
288 pub is_delegate_account_cold: Option<bool>,
290 pub is_empty: bool,
292}