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