1pub mod inner;
6pub mod warm_addresses;
7
8pub use context_interface::journaled_state::entry::{JournalEntry, JournalEntryTr};
9pub use inner::{JournalCfg, JournalInner};
10
11use bytecode::Bytecode;
12use context_interface::{
13 context::{SStoreResult, SelfDestructResult, StateLoad},
14 journaled_state::{
15 account::JournaledAccount, AccountInfoLoad, AccountLoad, JournalCheckpoint,
16 JournalLoadError, JournalTr, TransferError,
17 },
18};
19use core::ops::{Deref, DerefMut};
20use database_interface::Database;
21use primitives::{
22 hardfork::SpecId, Address, AddressMap, AddressSet, HashSet, Log, StorageKey, StorageValue,
23 B256, U256,
24};
25use state::{Account, EvmState};
26use std::vec::Vec;
27
28#[derive(Debug, Clone, PartialEq, Eq)]
34#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
35pub struct Journal<DB, ENTRY = JournalEntry>
36where
37 ENTRY: JournalEntryTr,
38{
39 pub database: DB,
41 pub inner: JournalInner<ENTRY>,
43}
44
45impl<DB, ENTRY> Deref for Journal<DB, ENTRY>
46where
47 ENTRY: JournalEntryTr,
48{
49 type Target = JournalInner<ENTRY>;
50
51 fn deref(&self) -> &Self::Target {
52 &self.inner
53 }
54}
55
56impl<DB, ENTRY> DerefMut for Journal<DB, ENTRY>
57where
58 ENTRY: JournalEntryTr,
59{
60 fn deref_mut(&mut self) -> &mut Self::Target {
61 &mut self.inner
62 }
63}
64
65impl<DB, ENTRY: JournalEntryTr> Journal<DB, ENTRY> {
66 pub const fn new_with_inner(database: DB, inner: JournalInner<ENTRY>) -> Self {
70 Self { database, inner }
71 }
72
73 pub fn into_init(self) -> JournalInner<ENTRY> {
77 self.inner
78 }
79}
80
81impl<DB, ENTRY: JournalEntryTr + Clone> Journal<DB, ENTRY> {
82 pub fn to_inner(&self) -> JournalInner<ENTRY> {
89 self.inner.clone()
90 }
91}
92
93impl<DB: Database, ENTRY: JournalEntryTr> JournalTr for Journal<DB, ENTRY> {
94 type Database = DB;
95 type State = EvmState;
96 type JournaledAccount<'a>
97 = JournaledAccount<'a, DB, ENTRY>
98 where
99 ENTRY: 'a,
100 DB: 'a;
101
102 fn new(database: DB) -> Journal<DB, ENTRY> {
103 Self {
104 inner: JournalInner::new(),
105 database,
106 }
107 }
108
109 fn db_and_state(&self) -> (&Self::Database, &Self::State) {
110 (&self.database, &self.inner.state)
111 }
112
113 #[inline]
114 fn db_and_state_mut(&mut self) -> (&mut Self::Database, &mut Self::State) {
115 (&mut self.database, &mut self.inner.state)
116 }
117
118 fn sload(
119 &mut self,
120 address: Address,
121 key: StorageKey,
122 ) -> Result<StateLoad<StorageValue>, <Self::Database as Database>::Error> {
123 self.inner
124 .sload_assume_account_present(&mut self.database, address, key, false)
125 .map_err(JournalLoadError::unwrap_db_error)
126 }
127
128 fn sstore(
129 &mut self,
130 address: Address,
131 key: StorageKey,
132 value: StorageValue,
133 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error> {
134 self.inner
135 .sstore_assume_account_present(&mut self.database, address, key, value, false)
136 .map_err(JournalLoadError::unwrap_db_error)
137 }
138
139 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue {
140 self.inner.tload(address, key)
141 }
142
143 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue) {
144 self.inner.tstore(address, key, value)
145 }
146
147 fn log(&mut self, log: Log) {
148 self.inner.log(log)
149 }
150
151 #[inline]
152 fn logs(&self) -> &[Log] {
153 &self.inner.logs
154 }
155
156 #[inline]
157 fn take_logs(&mut self) -> Vec<Log> {
158 self.inner.take_logs()
159 }
160
161 fn selfdestruct(
162 &mut self,
163 address: Address,
164 target: Address,
165 skip_cold_load: bool,
166 ) -> Result<StateLoad<SelfDestructResult>, JournalLoadError<<Self::Database as Database>::Error>>
167 {
168 self.inner
169 .selfdestruct(&mut self.database, address, target, skip_cold_load)
170 }
171
172 #[inline]
173 fn warm_access_list(&mut self, access_list: AddressMap<HashSet<StorageKey>>) {
174 self.inner.warm_addresses.set_access_list(access_list);
175 }
176
177 #[inline]
178 fn warm_coinbase_account(&mut self, address: Address) {
179 self.inner.warm_addresses.set_coinbase(address);
180 }
181
182 #[inline]
183 fn warm_precompiles(&mut self, precompiles: &AddressSet) {
184 self.inner
185 .warm_addresses
186 .set_precompile_addresses(precompiles);
187 }
188
189 #[inline]
190 fn precompile_addresses(&self) -> &AddressSet {
191 self.inner.warm_addresses.precompiles()
192 }
193
194 #[inline]
196 fn depth(&self) -> usize {
197 self.inner.depth
198 }
199
200 #[inline]
201 fn set_spec_id(&mut self, spec_id: SpecId) {
202 self.inner.cfg.spec = spec_id;
203 }
204
205 #[inline]
206 fn set_eip7708_config(&mut self, disabled: bool, delayed_burn_disabled: bool) {
207 self.inner
208 .set_eip7708_config(disabled, delayed_burn_disabled);
209 }
210
211 #[inline]
212 fn transfer(
213 &mut self,
214 from: Address,
215 to: Address,
216 balance: U256,
217 ) -> Result<Option<TransferError>, DB::Error> {
218 self.inner.transfer(&mut self.database, from, to, balance)
219 }
220
221 #[inline]
222 fn transfer_loaded(
223 &mut self,
224 from: Address,
225 to: Address,
226 balance: U256,
227 ) -> Option<TransferError> {
228 self.inner.transfer_loaded(from, to, balance)
229 }
230
231 #[inline]
232 fn touch_account(&mut self, address: Address) {
233 self.inner.touch(address);
234 }
235
236 #[inline]
237 #[expect(deprecated)]
238 fn caller_accounting_journal_entry(
239 &mut self,
240 address: Address,
241 old_balance: U256,
242 bump_nonce: bool,
243 ) {
244 self.inner
245 .caller_accounting_journal_entry(address, old_balance, bump_nonce);
246 }
247
248 #[inline]
250 fn balance_incr(
251 &mut self,
252 address: Address,
253 balance: U256,
254 ) -> Result<(), <Self::Database as Database>::Error> {
255 self.inner
256 .balance_incr(&mut self.database, address, balance)
257 }
258
259 #[inline]
261 #[expect(deprecated)]
262 fn nonce_bump_journal_entry(&mut self, address: Address) {
263 self.inner.nonce_bump_journal_entry(address)
264 }
265
266 #[inline]
267 fn load_account(&mut self, address: Address) -> Result<StateLoad<&Account>, DB::Error> {
268 self.inner.load_account(&mut self.database, address)
269 }
270
271 #[inline]
272 fn load_account_mut_skip_cold_load(
273 &mut self,
274 address: Address,
275 skip_cold_load: bool,
276 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, JournalLoadError<DB::Error>> {
277 self.inner
278 .load_account_mut_optional(&mut self.database, address, skip_cold_load)
279 }
280
281 #[inline]
282 fn load_account_mut_optional_code(
283 &mut self,
284 address: Address,
285 load_code: bool,
286 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, DB::Error> {
287 self.inner
288 .load_account_mut_optional_code(&mut self.database, address, load_code, false)
289 .map_err(JournalLoadError::unwrap_db_error)
290 }
291
292 #[inline]
293 fn load_account_with_code(
294 &mut self,
295 address: Address,
296 ) -> Result<StateLoad<&Account>, DB::Error> {
297 self.inner.load_code(&mut self.database, address)
298 }
299
300 #[inline]
301 fn load_account_delegated(
302 &mut self,
303 address: Address,
304 ) -> Result<StateLoad<AccountLoad>, DB::Error> {
305 self.inner
306 .load_account_delegated(&mut self.database, address)
307 }
308
309 #[inline]
310 fn checkpoint(&mut self) -> JournalCheckpoint {
311 self.inner.checkpoint()
312 }
313
314 #[inline]
315 fn checkpoint_commit(&mut self) {
316 self.inner.checkpoint_commit()
317 }
318
319 #[inline]
320 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint) {
321 self.inner.checkpoint_revert(checkpoint)
322 }
323
324 #[inline]
325 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256) {
326 self.inner.set_code_with_hash(address, code, hash);
327 }
328
329 #[inline]
330 fn create_account_checkpoint(
331 &mut self,
332 caller: Address,
333 address: Address,
334 balance: U256,
335 spec_id: SpecId,
336 ) -> Result<JournalCheckpoint, TransferError> {
337 self.inner
339 .create_account_checkpoint(caller, address, balance, spec_id)
340 }
341
342 #[inline]
343 fn commit_tx(&mut self) {
344 self.inner.commit_tx()
345 }
346
347 #[inline]
348 fn discard_tx(&mut self) {
349 self.inner.discard_tx();
350 }
351
352 #[inline]
354 fn finalize(&mut self) -> Self::State {
355 self.inner.finalize()
356 }
357
358 #[inline]
359 fn sload_skip_cold_load(
360 &mut self,
361 address: Address,
362 key: StorageKey,
363 skip_cold_load: bool,
364 ) -> Result<StateLoad<StorageValue>, JournalLoadError<<Self::Database as Database>::Error>>
365 {
366 self.inner
367 .sload_assume_account_present(&mut self.database, address, key, skip_cold_load)
368 }
369
370 #[inline]
371 fn sstore_skip_cold_load(
372 &mut self,
373 address: Address,
374 key: StorageKey,
375 value: StorageValue,
376 skip_cold_load: bool,
377 ) -> Result<StateLoad<SStoreResult>, JournalLoadError<<Self::Database as Database>::Error>>
378 {
379 self.inner.sstore_assume_account_present(
380 &mut self.database,
381 address,
382 key,
383 value,
384 skip_cold_load,
385 )
386 }
387
388 #[inline]
389 fn load_account_info_skip_cold_load(
390 &mut self,
391 address: Address,
392 load_code: bool,
393 skip_cold_load: bool,
394 ) -> Result<AccountInfoLoad<'_>, JournalLoadError<<Self::Database as Database>::Error>> {
395 let spec = self.inner.cfg.spec;
396 self.inner
397 .load_account_optional(&mut self.database, address, load_code, skip_cold_load)
398 .map(|a| {
399 AccountInfoLoad::new(&a.data.info, a.is_cold, a.state_clear_aware_is_empty(spec))
400 })
401 }
402}