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