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 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(&self) -> &Self::Database {
110 &self.database
111 }
112
113 fn db_mut(&mut self) -> &mut Self::Database {
114 &mut self.database
115 }
116
117 fn sload(
118 &mut self,
119 address: Address,
120 key: StorageKey,
121 ) -> Result<StateLoad<StorageValue>, <Self::Database as Database>::Error> {
122 self.inner
123 .sload_assume_account_present(&mut self.database, address, key, false)
124 .map_err(JournalLoadError::unwrap_db_error)
125 }
126
127 fn sstore(
128 &mut self,
129 address: Address,
130 key: StorageKey,
131 value: StorageValue,
132 ) -> Result<StateLoad<SStoreResult>, <Self::Database as Database>::Error> {
133 self.inner
134 .sstore_assume_account_present(&mut self.database, address, key, value, false)
135 .map_err(JournalLoadError::unwrap_db_error)
136 }
137
138 fn tload(&mut self, address: Address, key: StorageKey) -> StorageValue {
139 self.inner.tload(address, key)
140 }
141
142 fn tstore(&mut self, address: Address, key: StorageKey, value: StorageValue) {
143 self.inner.tstore(address, key, value)
144 }
145
146 fn log(&mut self, log: Log) {
147 self.inner.log(log)
148 }
149
150 #[inline]
151 fn logs(&self) -> &[Log] {
152 &self.inner.logs
153 }
154
155 #[inline]
156 fn take_logs(&mut self) -> Vec<Log> {
157 self.inner.take_logs()
158 }
159
160 fn selfdestruct(
161 &mut self,
162 address: Address,
163 target: Address,
164 skip_cold_load: bool,
165 ) -> Result<StateLoad<SelfDestructResult>, JournalLoadError<<Self::Database as Database>::Error>>
166 {
167 self.inner
168 .selfdestruct(&mut self.database, address, target, skip_cold_load)
169 }
170
171 #[inline]
172 fn warm_access_list(&mut self, access_list: AddressMap<HashSet<StorageKey>>) {
173 self.inner.warm_addresses.set_access_list(access_list);
174 }
175
176 fn warm_coinbase_account(&mut self, address: Address) {
177 self.inner.warm_addresses.set_coinbase(address);
178 }
179
180 fn warm_precompiles(&mut self, precompiles: AddressSet) {
181 self.inner
182 .warm_addresses
183 .set_precompile_addresses(precompiles);
184 }
185
186 #[inline]
187 fn precompile_addresses(&self) -> &AddressSet {
188 self.inner.warm_addresses.precompiles()
189 }
190
191 #[inline]
193 fn depth(&self) -> usize {
194 self.inner.depth
195 }
196
197 #[inline]
198 fn set_spec_id(&mut self, spec_id: SpecId) {
199 self.inner.cfg.spec = spec_id;
200 }
201
202 #[inline]
203 fn set_eip7708_config(&mut self, disabled: bool, delayed_burn_disabled: bool) {
204 self.inner
205 .set_eip7708_config(disabled, delayed_burn_disabled);
206 }
207
208 #[inline]
209 fn transfer(
210 &mut self,
211 from: Address,
212 to: Address,
213 balance: U256,
214 ) -> Result<Option<TransferError>, DB::Error> {
215 self.inner.transfer(&mut self.database, from, to, balance)
216 }
217
218 #[inline]
219 fn transfer_loaded(
220 &mut self,
221 from: Address,
222 to: Address,
223 balance: U256,
224 ) -> Option<TransferError> {
225 self.inner.transfer_loaded(from, to, balance)
226 }
227
228 #[inline]
229 fn touch_account(&mut self, address: Address) {
230 self.inner.touch(address);
231 }
232
233 #[inline]
234 #[allow(deprecated)]
235 fn caller_accounting_journal_entry(
236 &mut self,
237 address: Address,
238 old_balance: U256,
239 bump_nonce: bool,
240 ) {
241 self.inner
242 .caller_accounting_journal_entry(address, old_balance, bump_nonce);
243 }
244
245 #[inline]
247 fn balance_incr(
248 &mut self,
249 address: Address,
250 balance: U256,
251 ) -> Result<(), <Self::Database as Database>::Error> {
252 self.inner
253 .balance_incr(&mut self.database, address, balance)
254 }
255
256 #[inline]
258 #[allow(deprecated)]
259 fn nonce_bump_journal_entry(&mut self, address: Address) {
260 self.inner.nonce_bump_journal_entry(address)
261 }
262
263 #[inline]
264 fn load_account(&mut self, address: Address) -> Result<StateLoad<&Account>, DB::Error> {
265 self.inner.load_account(&mut self.database, address)
266 }
267
268 #[inline]
269 fn load_account_mut_skip_cold_load(
270 &mut self,
271 address: Address,
272 skip_cold_load: bool,
273 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, DB::Error> {
274 self.inner
275 .load_account_mut_optional(&mut self.database, address, skip_cold_load)
276 .map_err(JournalLoadError::unwrap_db_error)
277 }
278
279 #[inline]
280 fn load_account_mut_optional_code(
281 &mut self,
282 address: Address,
283 load_code: bool,
284 ) -> Result<StateLoad<Self::JournaledAccount<'_>>, DB::Error> {
285 self.inner
286 .load_account_mut_optional_code(&mut self.database, address, load_code, false)
287 .map_err(JournalLoadError::unwrap_db_error)
288 }
289
290 #[inline]
291 fn load_account_with_code(
292 &mut self,
293 address: Address,
294 ) -> Result<StateLoad<&Account>, DB::Error> {
295 self.inner.load_code(&mut self.database, address)
296 }
297
298 #[inline]
299 fn load_account_delegated(
300 &mut self,
301 address: Address,
302 ) -> Result<StateLoad<AccountLoad>, DB::Error> {
303 self.inner
304 .load_account_delegated(&mut self.database, address)
305 }
306
307 #[inline]
308 fn checkpoint(&mut self) -> JournalCheckpoint {
309 self.inner.checkpoint()
310 }
311
312 #[inline]
313 fn checkpoint_commit(&mut self) {
314 self.inner.checkpoint_commit()
315 }
316
317 #[inline]
318 fn checkpoint_revert(&mut self, checkpoint: JournalCheckpoint) {
319 self.inner.checkpoint_revert(checkpoint)
320 }
321
322 #[inline]
323 fn set_code_with_hash(&mut self, address: Address, code: Bytecode, hash: B256) {
324 self.inner.set_code_with_hash(address, code, hash);
325 }
326
327 #[inline]
328 fn create_account_checkpoint(
329 &mut self,
330 caller: Address,
331 address: Address,
332 balance: U256,
333 spec_id: SpecId,
334 ) -> Result<JournalCheckpoint, TransferError> {
335 self.inner
337 .create_account_checkpoint(caller, address, balance, spec_id)
338 }
339
340 #[inline]
341 fn commit_tx(&mut self) {
342 self.inner.commit_tx()
343 }
344
345 #[inline]
346 fn discard_tx(&mut self) {
347 self.inner.discard_tx();
348 }
349
350 #[inline]
352 fn finalize(&mut self) -> Self::State {
353 self.inner.finalize()
354 }
355
356 #[inline]
357 fn sload_skip_cold_load(
358 &mut self,
359 address: Address,
360 key: StorageKey,
361 skip_cold_load: bool,
362 ) -> Result<StateLoad<StorageValue>, JournalLoadError<<Self::Database as Database>::Error>>
363 {
364 self.inner
365 .sload_assume_account_present(&mut self.database, address, key, skip_cold_load)
366 }
367
368 #[inline]
369 fn sstore_skip_cold_load(
370 &mut self,
371 address: Address,
372 key: StorageKey,
373 value: StorageValue,
374 skip_cold_load: bool,
375 ) -> Result<StateLoad<SStoreResult>, JournalLoadError<<Self::Database as Database>::Error>>
376 {
377 self.inner.sstore_assume_account_present(
378 &mut self.database,
379 address,
380 key,
381 value,
382 skip_cold_load,
383 )
384 }
385
386 #[inline]
387 fn load_account_info_skip_cold_load(
388 &mut self,
389 address: Address,
390 load_code: bool,
391 skip_cold_load: bool,
392 ) -> Result<AccountInfoLoad<'_>, JournalLoadError<<Self::Database as Database>::Error>> {
393 let spec = self.inner.cfg.spec;
394 self.inner
395 .load_account_optional(&mut self.database, address, load_code, skip_cold_load)
396 .map(|a| {
397 AccountInfoLoad::new(&a.data.info, a.is_cold, a.state_clear_aware_is_empty(spec))
398 })
399 }
400}