1use crate::host::{SStoreResult, SelfDestructResult};
2use core::ops::{Deref, DerefMut};
3use database_interface::Database;
4use primitives::{Address, Bytes, HashSet, Log, B256, U256};
5use specification::hardfork::SpecId;
6use state::{Account, Bytecode};
7
8pub trait Journal {
9 type Database: Database;
10 type FinalOutput;
11
12 fn new(database: Self::Database) -> Self;
16
17 fn db_ref(&self) -> &Self::Database;
19
20 fn db(&mut self) -> &mut Self::Database;
22
23 fn sload(
27 &mut self,
28 address: Address,
29 key: U256,
30 ) -> Result<StateLoad<U256>, <Self::Database as Database>::Error>;
31
32 fn sstore(
34 &mut self,
35 address: Address,
36 key: U256,
37 value: U256,
38 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error>;
39
40 fn tload(&mut self, address: Address, key: U256) -> U256;
42
43 fn tstore(&mut self, address: Address, key: U256, value: U256);
45
46 fn log(&mut self, log: Log);
48
49 fn selfdestruct(
51 &mut self,
52 address: Address,
53 target: Address,
54 ) -> Result<StateLoad<SelfDestructResult>, <Self::Database as Database>::Error>;
55
56 fn warm_account_and_storage(
57 &mut self,
58 address: Address,
59 storage_keys: impl IntoIterator<Item = U256>,
60 ) -> Result<(), <Self::Database as Database>::Error>;
61
62 fn warm_account(&mut self, address: Address);
63
64 fn warm_precompiles(&mut self, addresses: HashSet<Address>);
65
66 fn precompile_addresses(&self) -> &HashSet<Address>;
67
68 fn set_spec_id(&mut self, spec_id: SpecId);
69
70 fn touch_account(&mut self, address: Address);
71
72 fn transfer(
73 &mut self,
74 from: &Address,
75 to: &Address,
76 balance: U256,
77 ) -> Result<Option<TransferError>, <Self::Database as Database>::Error>;
78
79 fn inc_account_nonce(
80 &mut self,
81 address: Address,
82 ) -> Result<Option<u64>, <Self::Database as Database>::Error>;
83
84 fn load_account(
85 &mut self,
86 address: Address,
87 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
88
89 fn load_account_code(
90 &mut self,
91 address: Address,
92 ) -> Result<StateLoad<&mut Account>, <Self::Database as Database>::Error>;
93
94 fn load_account_delegated(
95 &mut self,
96 address: Address,
97 ) -> Result<StateLoad<AccountLoad>, <Self::Database as Database>::Error>;
98
99 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
101
102 #[inline]
106 fn set_code(&mut self, address: Address, code: Bytecode) {
107 let hash = code.hash_slow();
108 self.set_code_with_hash(address, code, hash);
109 }
110
111 fn code(
112 &mut self,
113 address: Address,
114 ) -> Result<StateLoad<Bytes>, <Self::Database as Database>::Error>;
115
116 fn code_hash(
117 &mut self,
118 address: Address,
119 ) -> Result<StateLoad<B256>, <Self::Database as Database>::Error>;
120
121 fn clear(&mut self);
123
124 fn checkpoint(&mut self) -> JournalCheckpoint;
125
126 fn checkpoint_commit(&mut self);
127
128 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint);
129
130 fn create_account_checkpoint(
131 &mut self,
132 caller: Address,
133 address: Address,
134 balance: U256,
135 spec_id: SpecId,
136 ) -> Result<JournalCheckpoint, TransferError>;
137
138 fn depth(&self) -> usize;
139
140 fn finalize(&mut self) -> Self::FinalOutput;
144}
145
146#[derive(Copy, Clone, Debug, PartialEq, Eq)]
148pub enum TransferError {
149 OutOfFunds,
151 OverflowPayment,
153 CreateCollision,
155}
156
157#[derive(Debug, Copy, Clone, PartialEq, Eq)]
159#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
160pub struct JournalCheckpoint {
161 pub log_i: usize,
162 pub journal_i: usize,
163}
164
165#[derive(Clone, Debug, Default, PartialEq, Eq)]
167#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
168pub struct StateLoad<T> {
169 pub data: T,
171 pub is_cold: bool,
173}
174
175impl<T> Deref for StateLoad<T> {
176 type Target = T;
177
178 fn deref(&self) -> &Self::Target {
179 &self.data
180 }
181}
182
183impl<T> DerefMut for StateLoad<T> {
184 fn deref_mut(&mut self) -> &mut Self::Target {
185 &mut self.data
186 }
187}
188
189impl<T> StateLoad<T> {
190 pub fn new(data: T, is_cold: bool) -> Self {
192 Self { data, is_cold }
193 }
194
195 pub fn map<B, F>(self, f: F) -> StateLoad<B>
199 where
200 F: FnOnce(T) -> B,
201 {
202 StateLoad::new(f(self.data), self.is_cold)
203 }
204}
205
206#[derive(Clone, Debug, Default, PartialEq, Eq)]
208#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
209pub struct AccountLoad {
210 pub is_delegate_account_cold: Option<bool>,
212 pub is_empty: bool,
214}