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