revm_context/
journal.rs

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