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 {
11 type Database: Database;
12 type FinalOutput;
13
14 fn new(database: Self::Database) -> Self;
18
19 fn db_ref(&self) -> &Self::Database;
21
22 fn db(&mut self) -> &mut Self::Database;
24
25 fn sload(
29 &mut self,
30 address: Address,
31 key: U256,
32 ) -> Result<StateLoad<U256>, <Self::Database as Database>::Error>;
33
34 fn sstore(
36 &mut self,
37 address: Address,
38 key: U256,
39 value: U256,
40 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error>;
41
42 fn tload(&mut self, address: Address, key: U256) -> U256;
44
45 fn tstore(&mut self, address: Address, key: U256, value: U256);
47
48 fn log(&mut self, log: Log);
50
51 fn selfdestruct(
53 &mut self,
54 address: Address,
55 target: Address,
56 ) -> Result<StateLoad<SelfDestructResult>, <Self::Database as Database>::Error>;
57
58 fn warm_account_and_storage(
59 &mut self,
60 address: Address,
61 storage_keys: impl IntoIterator<Item = U256>,
62 ) -> Result<(), <Self::Database as Database>::Error>;
63
64 fn warm_account(&mut self, address: Address);
65
66 fn warm_precompiles(&mut self, addresses: HashSet<Address>);
67
68 fn precompile_addresses(&self) -> &HashSet<Address>;
69
70 fn set_spec_id(&mut self, spec_id: SpecId);
71
72 fn touch_account(&mut self, address: Address);
73
74 fn transfer(
75 &mut self,
76 from: &Address,
77 to: &Address,
78 balance: U256,
79 ) -> Result<Option<TransferError>, <Self::Database as Database>::Error>;
80
81 fn inc_account_nonce(
82 &mut self,
83 address: Address,
84 ) -> Result<Option<u64>, <Self::Database as Database>::Error>;
85
86 fn load_account(
87 &mut self,
88 address: Address,
89 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
90
91 fn load_account_code(
92 &mut self,
93 address: Address,
94 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
95
96 fn load_account_delegated(
97 &mut self,
98 address: Address,
99 ) -> Result<StateLoad<AccountLoad>, <Self::Database as Database>::Error>;
100
101 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
103
104 #[inline]
108 fn set_code(&mut self, address: Address, code: Bytecode) {
109 let hash = code.hash_slow();
110 self.set_code_with_hash(address, code, hash);
111 }
112
113 #[inline]
117 fn code(
118 &mut self,
119 address: Address,
120 ) -> Result<StateLoad<Bytes>, <Self::Database as Database>::Error> {
121 let a = self.load_account_code(address)?;
122 let code = a.info.code.as_ref().unwrap();
124
125 let code = if code.is_eof() {
126 EOF_MAGIC_BYTES.clone()
127 } else {
128 code.original_bytes()
129 };
130
131 Ok(StateLoad::new(code, a.is_cold))
132 }
133
134 fn code_hash(
139 &mut self,
140 address: Address,
141 ) -> Result<StateLoad<B256>, <Self::Database as Database>::Error> {
142 let acc = self.load_account_code(address)?;
143 if acc.is_empty() {
144 return Ok(StateLoad::new(B256::ZERO, acc.is_cold));
145 }
146 let code = acc.info.code.as_ref().unwrap();
148
149 let hash = if code.is_eof() {
150 EOF_MAGIC_HASH
151 } else {
152 acc.info.code_hash
153 };
154
155 Ok(StateLoad::new(hash, acc.is_cold))
156 }
157
158 fn clear(&mut self);
160
161 fn checkpoint(&mut self) -> JournalCheckpoint;
162
163 fn checkpoint_commit(&mut self);
164
165 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint);
166
167 fn create_account_checkpoint(
168 &mut self,
169 caller: Address,
170 address: Address,
171 balance: U256,
172 spec_id: SpecId,
173 ) -> Result<JournalCheckpoint, TransferError>;
174
175 fn depth(&self) -> usize;
176
177 fn finalize(&mut self) -> Self::FinalOutput;
181}
182
183#[derive(Copy, Clone, Debug, PartialEq, Eq)]
185pub enum TransferError {
186 OutOfFunds,
188 OverflowPayment,
190 CreateCollision,
192}
193
194#[derive(Debug, Copy, Clone, PartialEq, Eq)]
196#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
197pub struct JournalCheckpoint {
198 pub log_i: usize,
199 pub journal_i: usize,
200}
201
202#[derive(Clone, Debug, Default, PartialEq, Eq)]
204#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
205pub struct StateLoad<T> {
206 pub data: T,
208 pub is_cold: bool,
210}
211
212impl<T> Deref for StateLoad<T> {
213 type Target = T;
214
215 fn deref(&self) -> &Self::Target {
216 &self.data
217 }
218}
219
220impl<T> DerefMut for StateLoad<T> {
221 fn deref_mut(&mut self) -> &mut Self::Target {
222 &mut self.data
223 }
224}
225
226impl<T> StateLoad<T> {
227 pub fn new(data: T, is_cold: bool) -> Self {
229 Self { data, is_cold }
230 }
231
232 pub fn map<B, F>(self, f: F) -> StateLoad<B>
236 where
237 F: FnOnce(T) -> B,
238 {
239 StateLoad::new(f(self.data), self.is_cold)
240 }
241}
242
243#[derive(Clone, Debug, Default, PartialEq, Eq)]
245#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
246pub struct AccountLoad {
247 pub is_delegate_account_cold: Option<bool>,
249 pub is_empty: bool,
251}