1pub mod account;
4pub mod entry;
5
6use crate::{
7 context::{SStoreResult, SelfDestructResult},
8 host::LoadError,
9 journaled_state::account::JournaledAccountTr,
10 ErasedError,
11};
12use core::ops::{Deref, DerefMut};
13use database_interface::Database;
14use primitives::{
15 hardfork::SpecId, Address, AddressMap, AddressSet, Bytes, HashSet, Log, StorageKey,
16 StorageValue, B256, U256,
17};
18use state::{Account, AccountInfo, Bytecode};
19use std::{borrow::Cow, vec::Vec};
20pub trait JournalTr {
22 type Database: Database;
24 type State;
26 type JournaledAccount<'a>: JournaledAccountTr
28 where
29 Self: 'a;
30
31 fn new(database: Self::Database) -> Self;
35
36 fn db_mut(&mut self) -> &mut Self::Database {
38 self.db_and_state_mut().0
39 }
40
41 fn db(&self) -> &Self::Database {
43 self.db_and_state().0
44 }
45
46 fn evm_state_mut(&mut self) -> &mut Self::State {
48 self.db_and_state_mut().1
49 }
50
51 fn evm_state(&self) -> &Self::State {
53 self.db_and_state().1
54 }
55
56 fn db_and_state(&self) -> (&Self::Database, &Self::State);
58
59 fn db_and_state_mut(&mut self) -> (&mut Self::Database, &mut Self::State);
61
62 fn sload(
66 &mut self,
67 address: Address,
68 key: StorageKey,
69 ) -> Result<StateLoad<StorageValue>, <Self::Database as Database>::Error> {
70 self.sload_skip_cold_load(address, key, false)
72 .map_err(JournalLoadError::unwrap_db_error)
73 }
74
75 fn sload_skip_cold_load(
77 &mut self,
78 _address: Address,
79 _key: StorageKey,
80 _skip_cold_load: bool,
81 ) -> Result<StateLoad<StorageValue>, JournalLoadError<<Self::Database as Database>::Error>>;
82
83 fn sstore(
85 &mut self,
86 address: Address,
87 key: StorageKey,
88 value: StorageValue,
89 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error> {
90 self.sstore_skip_cold_load(address, key, value, false)
92 .map_err(JournalLoadError::unwrap_db_error)
93 }
94
95 fn sstore_skip_cold_load(
97 &mut self,
98 _address: Address,
99 _key: StorageKey,
100 _value: StorageValue,
101 _skip_cold_load: bool,
102 ) -> Result<StateLoad<SStoreResult>, JournalLoadError<<Self::Database as Database>::Error>>;
103
104 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue;
106
107 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue);
109
110 fn log(&mut self, log: Log);
112
113 fn take_logs(&mut self) -> Vec<Log>;
115
116 fn logs(&self) -> &[Log];
118
119 fn selfdestruct(
121 &mut self,
122 address: Address,
123 target: Address,
124 skip_cold_load: bool,
125 ) -> Result<StateLoad<SelfDestructResult>, JournalLoadError<<Self::Database as Database>::Error>>;
126
127 fn warm_access_list(&mut self, access_list: AddressMap<HashSet<StorageKey>>);
129
130 fn warm_coinbase_account(&mut self, address: Address);
132
133 fn warm_precompiles(&mut self, addresses: &AddressSet);
135
136 fn precompile_addresses(&self) -> &AddressSet;
138
139 fn set_spec_id(&mut self, spec_id: SpecId);
141
142 fn set_eip7708_config(&mut self, disabled: bool, delayed_burn_disabled: bool);
152
153 fn touch_account(&mut self, address: Address);
155
156 fn transfer(
158 &mut self,
159 from: Address,
160 to: Address,
161 balance: U256,
162 ) -> Result<Option<TransferError>, <Self::Database as Database>::Error>;
163
164 fn transfer_loaded(
166 &mut self,
167 from: Address,
168 to: Address,
169 balance: U256,
170 ) -> Option<TransferError>;
171
172 #[deprecated]
174 fn caller_accounting_journal_entry(
175 &mut self,
176 address: Address,
177 old_balance: U256,
178 bump_nonce: bool,
179 );
180
181 fn balance_incr(
183 &mut self,
184 address: Address,
185 balance: U256,
186 ) -> Result<(), <Self::Database as Database>::Error>;
187
188 #[deprecated]
190 fn nonce_bump_journal_entry(&mut self, address: Address);
191
192 fn load_account(
194 &mut self,
195 address: Address,
196 ) -> Result<StateLoad<&Account>, <Self::Database as Database>::Error>;
197
198 #[inline]
200 #[deprecated(note = "Use `load_account_with_code` instead")]
201 fn load_account_code(
202 &mut self,
203 address: Address,
204 ) -> Result<StateLoad<&Account>, <Self::Database as Database>::Error> {
205 self.load_account_with_code(address)
206 }
207
208 fn load_account_with_code(
210 &mut self,
211 address: Address,
212 ) -> Result<StateLoad<&Account>, <Self::Database as Database>::Error>;
213
214 fn load_account_delegated(
216 &mut self,
217 address: Address,
218 ) -> Result<StateLoad<AccountLoad>, <Self::Database as Database>::Error>;
219
220 #[inline]
222 fn load_account_mut(
223 &mut self,
224 address: Address,
225 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, <Self::Database as Database>::Error> {
226 self.load_account_mut_skip_cold_load(address, false)
227 .map_err(JournalLoadError::unwrap_db_error)
228 }
229
230 fn load_account_mut_skip_cold_load(
232 &mut self,
233 address: Address,
234 skip_cold_load: bool,
235 ) -> Result<
236 StateLoad<Self::JournaledAccount<'_>>,
237 JournalLoadError<<Self::Database as Database>::Error>,
238 >;
239
240 #[inline]
242 fn load_account_with_code_mut(
243 &mut self,
244 address: Address,
245 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, <Self::Database as Database>::Error> {
246 self.load_account_mut_optional_code(address, true)
247 }
248
249 fn load_account_mut_optional_code(
251 &mut self,
252 address: Address,
253 load_code: bool,
254 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, <Self::Database as Database>::Error>;
255
256 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256);
258
259 #[inline]
263 fn set_code(&mut self, address: Address, code: Bytecode) {
264 let hash = code.hash_slow();
265 self.set_code_with_hash(address, code, hash);
266 }
267
268 #[inline]
270 fn code(
271 &mut self,
272 address: Address,
273 ) -> Result<StateLoad<Bytes>, <Self::Database as Database>::Error> {
274 let a = self.load_account_with_code(address)?;
275 let code = a.info.code.as_ref().unwrap().original_bytes();
277
278 Ok(StateLoad::new(code, a.is_cold))
279 }
280
281 fn code_hash(
283 &mut self,
284 address: Address,
285 ) -> Result<StateLoad<B256>, <Self::Database as Database>::Error> {
286 let acc = self.load_account_with_code(address)?;
287 if acc.is_empty() {
288 return Ok(StateLoad::new(B256::ZERO, acc.is_cold));
289 }
290 let hash = acc.info.code_hash;
291 Ok(StateLoad::new(hash, acc.is_cold))
292 }
293
294 fn clear(&mut self) {
296 let _ = self.finalize();
297 }
298
299 fn checkpoint(&mut self) -> JournalCheckpoint;
302
303 fn checkpoint_commit(&mut self);
305
306 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint);
308
309 fn create_account_checkpoint(
311 &mut self,
312 caller: Address,
313 address: Address,
314 balance: U256,
315 spec_id: SpecId,
316 ) -> Result<JournalCheckpoint, TransferError>;
317
318 fn depth(&self) -> usize;
320
321 fn commit_tx(&mut self);
323
324 fn discard_tx(&mut self);
329
330 fn finalize(&mut self) -> Self::State;
332
333 fn load_account_info_skip_cold_load(
335 &mut self,
336 _address: Address,
337 _load_code: bool,
338 _skip_cold_load: bool,
339 ) -> Result<AccountInfoLoad<'_>, JournalLoadError<<Self::Database as Database>::Error>>;
340}
341
342#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
344#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
345pub enum JournalLoadError<E> {
346 DBError(E),
348 ColdLoadSkipped,
350}
351
352pub type JournalLoadErasedError = JournalLoadError<ErasedError>;
354
355impl<E> JournalLoadError<E> {
356 #[inline]
358 pub const fn is_db_error(&self) -> bool {
359 matches!(self, JournalLoadError::DBError(_))
360 }
361
362 #[inline]
364 pub const fn is_cold_load_skipped(&self) -> bool {
365 matches!(self, JournalLoadError::ColdLoadSkipped)
366 }
367
368 #[inline]
370 pub fn take_db_error(self) -> Option<E> {
371 if let JournalLoadError::DBError(e) = self {
372 Some(e)
373 } else {
374 None
375 }
376 }
377
378 #[inline]
380 pub fn unwrap_db_error(self) -> E {
381 if let JournalLoadError::DBError(e) = self {
382 e
383 } else {
384 panic!("Expected DBError");
385 }
386 }
387
388 #[inline]
390 pub fn into_parts(self) -> (LoadError, Option<E>) {
391 match self {
392 JournalLoadError::DBError(e) => (LoadError::DBError, Some(e)),
393 JournalLoadError::ColdLoadSkipped => (LoadError::ColdLoadSkipped, None),
394 }
395 }
396
397 #[inline]
399 pub fn map<B, F>(self, f: F) -> JournalLoadError<B>
400 where
401 F: FnOnce(E) -> B,
402 {
403 match self {
404 JournalLoadError::DBError(e) => JournalLoadError::DBError(f(e)),
405 JournalLoadError::ColdLoadSkipped => JournalLoadError::ColdLoadSkipped,
406 }
407 }
408}
409
410impl<E> From<E> for JournalLoadError<E> {
411 fn from(e: E) -> Self {
412 JournalLoadError::DBError(e)
413 }
414}
415
416impl<E> From<JournalLoadError<E>> for LoadError {
417 fn from(e: JournalLoadError<E>) -> Self {
418 match e {
419 JournalLoadError::DBError(_) => LoadError::DBError,
420 JournalLoadError::ColdLoadSkipped => LoadError::ColdLoadSkipped,
421 }
422 }
423}
424
425#[derive(Copy, Clone, Debug, PartialEq, Eq)]
427pub enum TransferError {
428 OutOfFunds,
430 OverflowPayment,
432 CreateCollision,
434}
435
436#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
438#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
439pub struct JournalCheckpoint {
440 pub log_i: usize,
442 pub journal_i: usize,
444 pub selfdestructed_i: usize,
446}
447
448#[derive(Clone, Debug, Default, PartialEq, Eq)]
450#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
451pub struct StateLoad<T> {
452 pub data: T,
454 pub is_cold: bool,
456}
457
458impl<T> Deref for StateLoad<T> {
459 type Target = T;
460
461 fn deref(&self) -> &Self::Target {
462 &self.data
463 }
464}
465
466impl<T> DerefMut for StateLoad<T> {
467 fn deref_mut(&mut self) -> &mut Self::Target {
468 &mut self.data
469 }
470}
471
472impl<T> StateLoad<T> {
473 #[inline]
475 pub const fn new(data: T, is_cold: bool) -> Self {
476 Self { data, is_cold }
477 }
478
479 #[inline]
483 pub fn map<B, F>(self, f: F) -> StateLoad<B>
484 where
485 F: FnOnce(T) -> B,
486 {
487 StateLoad::new(f(self.data), self.is_cold)
488 }
489}
490
491#[derive(Clone, Debug, Default, PartialEq, Eq)]
493#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
494pub struct AccountLoad {
495 pub is_delegate_account_cold: Option<bool>,
497 pub is_empty: bool,
499}
500
501#[derive(Clone, Debug, Default, PartialEq, Eq)]
503#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
504pub struct AccountInfoLoad<'a> {
505 pub account: Cow<'a, AccountInfo>,
507 pub is_cold: bool,
509 pub is_empty: bool,
511}
512
513impl<'a> AccountInfoLoad<'a> {
514 #[inline]
516 pub const fn new(account: &'a AccountInfo, is_cold: bool, is_empty: bool) -> Self {
517 Self {
518 account: Cow::Borrowed(account),
519 is_cold,
520 is_empty,
521 }
522 }
523
524 #[inline]
528 pub fn into_state_load<F, O>(self, f: F) -> StateLoad<O>
529 where
530 F: FnOnce(Cow<'a, AccountInfo>) -> O,
531 {
532 StateLoad::new(f(self.account), self.is_cold)
533 }
534}
535
536impl<'a> Deref for AccountInfoLoad<'a> {
537 type Target = AccountInfo;
538
539 fn deref(&self) -> &Self::Target {
540 &self.account
541 }
542}