1use crate::context::{SStoreResult, SelfDestructResult};
2use core::ops::{Deref, DerefMut};
3use database_interface::Database;
4use primitives::{hardfork::SpecId, Address, Bytes, HashSet, Log, B256, U256};
5use state::{
6 bytecode::{EOF_MAGIC_BYTES, EOF_MAGIC_HASH},
7 Account, Bytecode,
8};
9
10pub trait JournalTr {
12 type Database: Database;
13 type FinalOutput;
14
15 fn new(database: Self::Database) -> Self;
19
20 fn db_ref(&self) -> &Self::Database;
22
23 fn db(&mut self) -> &mut Self::Database;
25
26 fn sload(
30 &mut self,
31 address: Address,
32 key: U256,
33 ) -> Result<StateLoad<U256>, <Self::Database as Database>::Error>;
34
35 fn sstore(
37 &mut self,
38 address: Address,
39 key: U256,
40 value: U256,
41 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error>;
42
43 fn tload(&mut self, address: Address, key: U256) -> U256;
45
46 fn tstore(&mut self, address: Address, key: U256, value: U256);
48
49 fn log(&mut self, log: Log);
51
52 fn selfdestruct(
54 &mut self,
55 address: Address,
56 target: Address,
57 ) -> Result<StateLoad<SelfDestructResult>, <Self::Database as Database>::Error>;
58
59 fn warm_account_and_storage(
61 &mut self,
62 address: Address,
63 storage_keys: impl IntoIterator<Item = U256>,
64 ) -> Result<(), <Self::Database as Database>::Error>;
65
66 fn warm_account(&mut self, address: Address);
68
69 fn warm_precompiles(&mut self, addresses: HashSet<Address>);
71
72 fn precompile_addresses(&self) -> &HashSet<Address>;
74
75 fn set_spec_id(&mut self, spec_id: SpecId);
77
78 fn touch_account(&mut self, address: Address);
80
81 fn transfer(
83 &mut self,
84 from: Address,
85 to: Address,
86 balance: U256,
87 ) -> Result<Option<TransferError>, <Self::Database as Database>::Error>;
88
89 fn inc_account_nonce(
91 &mut self,
92 address: Address,
93 ) -> Result<Option<u64>, <Self::Database as Database>::Error>;
94
95 fn load_account(
97 &mut self,
98 address: Address,
99 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
100
101 fn load_account_code(
103 &mut self,
104 address: Address,
105 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
106
107 fn load_account_delegated(
109 &mut self,
110 address: Address,
111 ) -> Result<StateLoad<AccountLoad>, <Self::Database as Database>::Error>;
112
113 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
115
116 #[inline]
120 fn set_code(&mut self, address: Address, code: Bytecode) {
121 let hash = code.hash_slow();
122 self.set_code_with_hash(address, code, hash);
123 }
124
125 #[inline]
129 fn code(
130 &mut self,
131 address: Address,
132 ) -> Result<StateLoad<Bytes>, <Self::Database as Database>::Error> {
133 let a = self.load_account_code(address)?;
134 let code = a.info.code.as_ref().unwrap();
136
137 let code = if code.is_eof() {
138 EOF_MAGIC_BYTES.clone()
139 } else {
140 code.original_bytes()
141 };
142
143 Ok(StateLoad::new(code, a.is_cold))
144 }
145
146 fn code_hash(
151 &mut self,
152 address: Address,
153 ) -> Result<StateLoad<B256>, <Self::Database as Database>::Error> {
154 let acc = self.load_account_code(address)?;
155 if acc.is_empty() {
156 return Ok(StateLoad::new(B256::ZERO, acc.is_cold));
157 }
158 let code = acc.info.code.as_ref().unwrap();
160
161 let hash = if code.is_eof() {
162 EOF_MAGIC_HASH
163 } else {
164 acc.info.code_hash
165 };
166
167 Ok(StateLoad::new(hash, acc.is_cold))
168 }
169
170 fn clear(&mut self);
172
173 fn checkpoint(&mut self) -> JournalCheckpoint;
176
177 fn checkpoint_commit(&mut self);
179
180 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint);
182
183 fn create_account_checkpoint(
185 &mut self,
186 caller: Address,
187 address: Address,
188 balance: U256,
189 spec_id: SpecId,
190 ) -> Result<JournalCheckpoint, TransferError>;
191
192 fn depth(&self) -> usize;
194
195 fn finalize(&mut self) -> Self::FinalOutput;
199}
200
201#[derive(Copy, Clone, Debug, PartialEq, Eq)]
203pub enum TransferError {
204 OutOfFunds,
206 OverflowPayment,
208 CreateCollision,
210}
211
212#[derive(Debug, Copy, Clone, PartialEq, Eq)]
214#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
215pub struct JournalCheckpoint {
216 pub log_i: usize,
217 pub journal_i: usize,
218}
219
220#[derive(Clone, Debug, Default, PartialEq, Eq)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
223pub struct StateLoad<T> {
224 pub data: T,
226 pub is_cold: bool,
228}
229
230impl<T> Deref for StateLoad<T> {
231 type Target = T;
232
233 fn deref(&self) -> &Self::Target {
234 &self.data
235 }
236}
237
238impl<T> DerefMut for StateLoad<T> {
239 fn deref_mut(&mut self) -> &mut Self::Target {
240 &mut self.data
241 }
242}
243
244impl<T> StateLoad<T> {
245 pub fn new(data: T, is_cold: bool) -> Self {
247 Self { data, is_cold }
248 }
249
250 pub fn map<B, F>(self, f: F) -> StateLoad<B>
254 where
255 F: FnOnce(T) -> B,
256 {
257 StateLoad::new(f(self.data), self.is_cold)
258 }
259}
260
261#[derive(Clone, Debug, Default, PartialEq, Eq)]
263#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
264pub struct AccountLoad {
265 pub is_delegate_account_cold: Option<bool>,
267 pub is_empty: bool,
269}