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