revm_context/
journal.rs

1//! This module contains [`Journal`] struct and implements [`JournalTr`] trait for it.
2//!
3//! Entry submodule contains [`JournalEntry`] and [`JournalEntryTr`] traits.
4//! and inner submodule contains [`JournalInner`] struct that contains state.
5pub mod entry;
6pub mod inner;
7pub mod warm_addresses;
8
9pub use entry::{JournalEntry, JournalEntryTr};
10pub use inner::JournalInner;
11
12use bytecode::Bytecode;
13use context_interface::{
14    context::{SStoreResult, SelfDestructResult, StateLoad},
15    journaled_state::{AccountLoad, JournalCheckpoint, JournalTr, TransferError},
16};
17use core::ops::{Deref, DerefMut};
18use database_interface::Database;
19use primitives::{hardfork::SpecId, Address, HashSet, Log, StorageKey, StorageValue, B256, U256};
20use state::{Account, EvmState};
21use std::vec::Vec;
22
23/// A journal of state changes internal to the EVM
24///
25/// On each additional call, the depth of the journaled state is increased (`depth`) and a new journal is added.
26///
27/// The journal contains every state change that happens within that call, making it possible to revert changes made in a specific call.
28#[derive(Debug, Clone, PartialEq, Eq)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30pub struct Journal<DB, ENTRY = JournalEntry>
31where
32    ENTRY: JournalEntryTr,
33{
34    /// Database
35    pub database: DB,
36    /// Inner journal state.
37    pub inner: JournalInner<ENTRY>,
38}
39
40impl<DB, ENTRY> Deref for Journal<DB, ENTRY>
41where
42    ENTRY: JournalEntryTr,
43{
44    type Target = JournalInner<ENTRY>;
45
46    fn deref(&self) -> &Self::Target {
47        &self.inner
48    }
49}
50
51impl<DB, ENTRY> DerefMut for Journal<DB, ENTRY>
52where
53    ENTRY: JournalEntryTr,
54{
55    fn deref_mut(&mut self) -> &mut Self::Target {
56        &mut self.inner
57    }
58}
59
60impl<DB, ENTRY: JournalEntryTr> Journal<DB, ENTRY> {
61    /// Creates a new JournaledState by copying state data from a JournalInit and provided database.
62    /// This allows reusing the state, logs, and other data from a previous execution context while
63    /// connecting it to a different database backend.
64    pub fn new_with_inner(database: DB, inner: JournalInner<ENTRY>) -> Self {
65        Self { database, inner }
66    }
67
68    /// Consumes the [`Journal`] and returns [`JournalInner`].
69    ///
70    /// If you need to preserve the original journal, use [`Self::to_inner`] instead which clones the state.
71    pub fn into_init(self) -> JournalInner<ENTRY> {
72        self.inner
73    }
74}
75
76impl<DB, ENTRY: JournalEntryTr + Clone> Journal<DB, ENTRY> {
77    /// Creates a new [`JournalInner`] by cloning all internal state data (state, storage, logs, etc)
78    /// This allows creating a new journaled state with the same state data but without
79    /// carrying over the original database.
80    ///
81    /// This is useful when you want to reuse the current state for a new transaction or
82    /// execution context, but want to start with a fresh database.
83    pub fn to_inner(&self) -> JournalInner<ENTRY> {
84        self.inner.clone()
85    }
86}
87
88impl<DB: Database, ENTRY: JournalEntryTr> JournalTr for Journal<DB, ENTRY> {
89    type Database = DB;
90    type State = EvmState;
91
92    fn new(database: DB) -> Journal<DB, ENTRY> {
93        Self {
94            inner: JournalInner::new(),
95            database,
96        }
97    }
98
99    fn db(&self) -> &Self::Database {
100        &self.database
101    }
102
103    fn db_mut(&mut self) -> &mut Self::Database {
104        &mut self.database
105    }
106
107    fn sload(
108        &mut self,
109        address: Address,
110        key: StorageKey,
111    ) -> Result<StateLoad<StorageValue>, <Self::Database as Database>::Error> {
112        self.inner.sload(&mut self.database, address, key)
113    }
114
115    fn sstore(
116        &mut self,
117        address: Address,
118        key: StorageKey,
119        value: StorageValue,
120    ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error> {
121        self.inner.sstore(&mut self.database, address, key, value)
122    }
123
124    fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue {
125        self.inner.tload(address, key)
126    }
127
128    fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue) {
129        self.inner.tstore(address, key, value)
130    }
131
132    fn log(&mut self, log: Log) {
133        self.inner.log(log)
134    }
135
136    fn selfdestruct(
137        &mut self,
138        address: Address,
139        target: Address,
140    ) -> Result<StateLoad<SelfDestructResult>, DB::Error> {
141        self.inner.selfdestruct(&mut self.database, address, target)
142    }
143
144    fn warm_coinbase_account(&mut self, address: Address) {
145        self.inner.warm_addresses.set_coinbase(address);
146    }
147
148    fn warm_precompiles(&mut self, precompiles: HashSet<Address>) {
149        self.inner
150            .warm_addresses
151            .set_precompile_addresses(precompiles);
152    }
153
154    #[inline]
155    fn precompile_addresses(&self) -> &HashSet<Address> {
156        self.inner.warm_addresses.precompiles()
157    }
158
159    /// Returns call depth.
160    #[inline]
161    fn depth(&self) -> usize {
162        self.inner.depth
163    }
164
165    #[inline]
166    fn warm_account_and_storage(
167        &mut self,
168        address: Address,
169        storage_keys: impl IntoIterator<Item = StorageKey>,
170    ) -> Result<(), <Self::Database as Database>::Error> {
171        self.inner
172            .load_account_optional(&mut self.database, address, false, storage_keys)?;
173        Ok(())
174    }
175
176    #[inline]
177    fn set_spec_id(&mut self, spec_id: SpecId) {
178        self.inner.spec = spec_id;
179    }
180
181    #[inline]
182    fn transfer(
183        &mut self,
184        from: Address,
185        to: Address,
186        balance: U256,
187    ) -> Result<Option<TransferError>, DB::Error> {
188        self.inner.transfer(&mut self.database, from, to, balance)
189    }
190
191    #[inline]
192    fn touch_account(&mut self, address: Address) {
193        self.inner.touch(address);
194    }
195
196    #[inline]
197    fn caller_accounting_journal_entry(
198        &mut self,
199        address: Address,
200        old_balance: U256,
201        bump_nonce: bool,
202    ) {
203        self.inner
204            .caller_accounting_journal_entry(address, old_balance, bump_nonce);
205    }
206
207    /// Increments the balance of the account.
208    #[inline]
209    fn balance_incr(
210        &mut self,
211        address: Address,
212        balance: U256,
213    ) -> Result<(), <Self::Database as Database>::Error> {
214        self.inner
215            .balance_incr(&mut self.database, address, balance)
216    }
217
218    /// Increments the nonce of the account.
219    #[inline]
220    fn nonce_bump_journal_entry(&mut self, address: Address) {
221        self.inner.nonce_bump_journal_entry(address)
222    }
223
224    #[inline]
225    fn load_account(&mut self, address: Address) -> Result<StateLoad<&mut Account>, DB::Error> {
226        self.inner.load_account(&mut self.database, address)
227    }
228
229    #[inline]
230    fn load_account_code(
231        &mut self,
232        address: Address,
233    ) -> Result<StateLoad<&mut Account>, DB::Error> {
234        self.inner.load_code(&mut self.database, address)
235    }
236
237    #[inline]
238    fn load_account_delegated(
239        &mut self,
240        address: Address,
241    ) -> Result<StateLoad<AccountLoad>, DB::Error> {
242        self.inner
243            .load_account_delegated(&mut self.database, address)
244    }
245
246    #[inline]
247    fn checkpoint(&mut self) -> JournalCheckpoint {
248        self.inner.checkpoint()
249    }
250
251    #[inline]
252    fn checkpoint_commit(&mut self) {
253        self.inner.checkpoint_commit()
254    }
255
256    #[inline]
257    fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint) {
258        self.inner.checkpoint_revert(checkpoint)
259    }
260
261    #[inline]
262    fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256) {
263        self.inner.set_code_with_hash(address, code, hash);
264    }
265
266    #[inline]
267    fn create_account_checkpoint(
268        &mut self,
269        caller: Address,
270        address: Address,
271        balance: U256,
272        spec_id: SpecId,
273    ) -> Result<JournalCheckpoint, TransferError> {
274        // Ignore error.
275        self.inner
276            .create_account_checkpoint(caller, address, balance, spec_id)
277    }
278
279    #[inline]
280    fn take_logs(&mut self) -> Vec<Log> {
281        self.inner.take_logs()
282    }
283
284    #[inline]
285    fn commit_tx(&mut self) {
286        self.inner.commit_tx()
287    }
288
289    #[inline]
290    fn discard_tx(&mut self) {
291        self.inner.discard_tx();
292    }
293
294    /// Clear current journal resetting it to initial state and return changes state.
295    #[inline]
296    fn finalize(&mut self) -> Self::State {
297        self.inner.finalize()
298    }
299}