1pub mod inner;
6pub mod warm_addresses;
7
8pub use context_interface::journaled_state::entry::{JournalEntry, JournalEntryTr};
9pub use inner::JournalInner;
10
11use bytecode::Bytecode;
12use context_interface::{
13 context::{SStoreResult, SelfDestructResult, StateLoad},
14 journaled_state::{
15 account::JournaledAccount, AccountInfoLoad, AccountLoad, JournalCheckpoint,
16 JournalLoadError, JournalTr, TransferError,
17 },
18};
19use core::ops::{Deref, DerefMut};
20use database_interface::Database;
21use primitives::{
22 hardfork::SpecId, Address, HashMap, HashSet, Log, StorageKey, StorageValue, B256, U256,
23};
24use state::{Account, EvmState};
25use std::vec::Vec;
26
27#[derive(Debug, Clone, PartialEq, Eq)]
33#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
34pub struct Journal<DB, ENTRY = JournalEntry>
35where
36 ENTRY: JournalEntryTr,
37{
38 pub database: DB,
40 pub inner: JournalInner<ENTRY>,
42}
43
44impl<DB, ENTRY> Deref for Journal<DB, ENTRY>
45where
46 ENTRY: JournalEntryTr,
47{
48 type Target = JournalInner<ENTRY>;
49
50 fn deref(&self) -> &Self::Target {
51 &self.inner
52 }
53}
54
55impl<DB, ENTRY> DerefMut for Journal<DB, ENTRY>
56where
57 ENTRY: JournalEntryTr,
58{
59 fn deref_mut(&mut self) -> &mut Self::Target {
60 &mut self.inner
61 }
62}
63
64impl<DB, ENTRY: JournalEntryTr> Journal<DB, ENTRY> {
65 pub fn new_with_inner(database: DB, inner: JournalInner<ENTRY>) -> Self {
69 Self { database, inner }
70 }
71
72 pub fn into_init(self) -> JournalInner<ENTRY> {
76 self.inner
77 }
78}
79
80impl<DB, ENTRY: JournalEntryTr + Clone> Journal<DB, ENTRY> {
81 pub fn to_inner(&self) -> JournalInner<ENTRY> {
88 self.inner.clone()
89 }
90}
91
92impl<DB: Database, ENTRY: JournalEntryTr> JournalTr for Journal<DB, ENTRY> {
93 type Database = DB;
94 type State = EvmState;
95 type JournaledAccount<'a>
96 = JournaledAccount<'a, ENTRY>
97 where
98 Self: 'a;
99
100 fn new(database: DB) -> Journal<DB, ENTRY> {
101 Self {
102 inner: JournalInner::new(),
103 database,
104 }
105 }
106
107 fn db(&self) -> &Self::Database {
108 &self.database
109 }
110
111 fn db_mut(&mut self) -> &mut Self::Database {
112 &mut self.database
113 }
114
115 fn sload(
116 &mut self,
117 address: Address,
118 key: StorageKey,
119 ) -> Result<StateLoad<StorageValue>, <Self::Database as Database>::Error> {
120 self.inner
121 .sload(&mut self.database, address, key, false)
122 .map_err(JournalLoadError::unwrap_db_error)
123 }
124
125 fn sstore(
126 &mut self,
127 address: Address,
128 key: StorageKey,
129 value: StorageValue,
130 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error> {
131 self.inner
132 .sstore(&mut self.database, address, key, value, false)
133 .map_err(JournalLoadError::unwrap_db_error)
134 }
135
136 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue {
137 self.inner.tload(address, key)
138 }
139
140 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue) {
141 self.inner.tstore(address, key, value)
142 }
143
144 fn log(&mut self, log: Log) {
145 self.inner.log(log)
146 }
147
148 #[inline]
149 fn logs(&self) -> &[Log] {
150 &self.inner.logs
151 }
152
153 #[inline]
154 fn take_logs(&mut self) -> Vec<Log> {
155 self.inner.take_logs()
156 }
157
158 fn selfdestruct(
159 &mut self,
160 address: Address,
161 target: Address,
162 skip_cold_load: bool,
163 ) -> Result<StateLoad<SelfDestructResult>, JournalLoadError<<Self::Database as Database>::Error>>
164 {
165 self.inner
166 .selfdestruct(&mut self.database, address, target, skip_cold_load)
167 }
168
169 #[inline]
170 fn warm_access_list(&mut self, access_list: HashMap<Address, HashSet<StorageKey>>) {
171 self.inner.warm_addresses.set_access_list(access_list);
172 }
173
174 fn warm_coinbase_account(&mut self, address: Address) {
175 self.inner.warm_addresses.set_coinbase(address);
176 }
177
178 fn warm_precompiles(&mut self, precompiles: HashSet<Address>) {
179 self.inner
180 .warm_addresses
181 .set_precompile_addresses(precompiles);
182 }
183
184 #[inline]
185 fn precompile_addresses(&self) -> &HashSet<Address> {
186 self.inner.warm_addresses.precompiles()
187 }
188
189 #[inline]
191 fn depth(&self) -> usize {
192 self.inner.depth
193 }
194
195 #[inline]
196 fn set_spec_id(&mut self, spec_id: SpecId) {
197 self.inner.spec = spec_id;
198 }
199
200 #[inline]
201 fn transfer(
202 &mut self,
203 from: Address,
204 to: Address,
205 balance: U256,
206 ) -> Result<Option<TransferError>, DB::Error> {
207 self.inner.transfer(&mut self.database, from, to, balance)
208 }
209
210 #[inline]
211 fn transfer_loaded(
212 &mut self,
213 from: Address,
214 to: Address,
215 balance: U256,
216 ) -> Option<TransferError> {
217 self.inner.transfer_loaded(from, to, balance)
218 }
219
220 #[inline]
221 fn touch_account(&mut self, address: Address) {
222 self.inner.touch(address);
223 }
224
225 #[inline]
226 fn caller_accounting_journal_entry(
227 &mut self,
228 address: Address,
229 old_balance: U256,
230 bump_nonce: bool,
231 ) {
232 self.inner
233 .caller_accounting_journal_entry(address, old_balance, bump_nonce);
234 }
235
236 #[inline]
238 fn balance_incr(
239 &mut self,
240 address: Address,
241 balance: U256,
242 ) -> Result<(), <Self::Database as Database>::Error> {
243 self.inner
244 .balance_incr(&mut self.database, address, balance)
245 }
246
247 #[inline]
249 fn nonce_bump_journal_entry(&mut self, address: Address) {
250 self.inner.nonce_bump_journal_entry(address)
251 }
252
253 #[inline]
254 fn load_account(&mut self, address: Address) -> Result<StateLoad<&Account>, DB::Error> {
255 self.inner.load_account(&mut self.database, address)
256 }
257
258 #[inline]
259 fn load_account_mut_optional_code(
260 &mut self,
261 address: Address,
262 load_code: bool,
263 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, DB::Error> {
264 self.inner
265 .load_account_mut_optional_code(&mut self.database, address, load_code, false)
266 .map_err(JournalLoadError::unwrap_db_error)
267 }
268
269 #[inline]
270 fn load_account_with_code(
271 &mut self,
272 address: Address,
273 ) -> Result<StateLoad<&Account>, DB::Error> {
274 self.inner.load_code(&mut self.database, address)
275 }
276
277 #[inline]
278 fn load_account_delegated(
279 &mut self,
280 address: Address,
281 ) -> Result<StateLoad<AccountLoad>, DB::Error> {
282 self.inner
283 .load_account_delegated(&mut self.database, address)
284 }
285
286 #[inline]
287 fn checkpoint(&mut self) -> JournalCheckpoint {
288 self.inner.checkpoint()
289 }
290
291 #[inline]
292 fn checkpoint_commit(&mut self) {
293 self.inner.checkpoint_commit()
294 }
295
296 #[inline]
297 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint) {
298 self.inner.checkpoint_revert(checkpoint)
299 }
300
301 #[inline]
302 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256) {
303 self.inner.set_code_with_hash(address, code, hash);
304 }
305
306 #[inline]
307 fn create_account_checkpoint(
308 &mut self,
309 caller: Address,
310 address: Address,
311 balance: U256,
312 spec_id: SpecId,
313 ) -> Result<JournalCheckpoint, TransferError> {
314 self.inner
316 .create_account_checkpoint(caller, address, balance, spec_id)
317 }
318
319 #[inline]
320 fn commit_tx(&mut self) {
321 self.inner.commit_tx()
322 }
323
324 #[inline]
325 fn discard_tx(&mut self) {
326 self.inner.discard_tx();
327 }
328
329 #[inline]
331 fn finalize(&mut self) -> Self::State {
332 self.inner.finalize()
333 }
334
335 #[inline]
336 fn sload_skip_cold_load(
337 &mut self,
338 address: Address,
339 key: StorageKey,
340 skip_cold_load: bool,
341 ) -> Result<StateLoad<StorageValue>, JournalLoadError<<Self::Database as Database>::Error>>
342 {
343 self.inner
344 .sload(&mut self.database, address, key, skip_cold_load)
345 }
346
347 #[inline]
348 fn sstore_skip_cold_load(
349 &mut self,
350 address: Address,
351 key: StorageKey,
352 value: StorageValue,
353 skip_cold_load: bool,
354 ) -> Result<StateLoad<SStoreResult>, JournalLoadError<<Self::Database as Database>::Error>>
355 {
356 self.inner
357 .sstore(&mut self.database, address, key, value, skip_cold_load)
358 }
359
360 #[inline]
361 fn load_account_info_skip_cold_load(
362 &mut self,
363 address: Address,
364 load_code: bool,
365 skip_cold_load: bool,
366 ) -> Result<AccountInfoLoad<'_>, JournalLoadError<<Self::Database as Database>::Error>> {
367 let spec = self.inner.spec;
368 self.inner
369 .load_account_optional(&mut self.database, address, load_code, skip_cold_load)
370 .map(|a| {
371 AccountInfoLoad::new(&a.data.info, a.is_cold, a.state_clear_aware_is_empty(spec))
372 })
373 }
374}