|
1 | | -use crate::{ |
2 | | - database::ReadOnlyDB, |
3 | | - utils::{collect_account_proofs, collect_storage_proofs}, |
4 | | - HardforkConfig, |
5 | | -}; |
6 | | -use eth_types::{ |
7 | | - geth_types::TxType, |
8 | | - l2_types::{BlockTrace, ExecutionResult}, |
9 | | - H160, H256, U256, |
10 | | -}; |
11 | | -use log::Level; |
12 | | -use mpt_zktrie::{AccountData, ZktrieState}; |
| 1 | +use crate::database::ReadOnlyDB; |
| 2 | +use eth_types::{geth_types::TxType, l2_types::BlockTraceV2, H160, H256, U256}; |
| 3 | +use mpt_zktrie::AccountData; |
13 | 4 | use revm::{ |
14 | 5 | db::CacheDB, |
15 | 6 | primitives::{AccountInfo, BlockEnv, Env, SpecId, TxEnv}, |
16 | | - DatabaseRef, |
17 | 7 | }; |
18 | 8 | use std::fmt::Debug; |
19 | 9 | use zktrie::ZkTrie; |
20 | 10 |
|
| 11 | +mod builder; |
| 12 | +/// Execute hooks |
| 13 | +pub mod hooks; |
| 14 | +pub use builder::EvmExecutorBuilder; |
| 15 | + |
21 | 16 | /// EVM executor that handles the block. |
22 | 17 | pub struct EvmExecutor { |
23 | 18 | db: CacheDB<ReadOnlyDB>, |
24 | 19 | zktrie: ZkTrie, |
25 | 20 | spec_id: SpecId, |
26 | | - disable_checks: bool, |
| 21 | + hooks: hooks::ExecuteHooks, |
27 | 22 | } |
28 | 23 | impl EvmExecutor { |
29 | | - /// Initialize an EVM executor from a block trace as the initial state. |
30 | | - pub fn new(l2_trace: &BlockTrace, fork_config: &HardforkConfig, disable_checks: bool) -> Self { |
31 | | - let block_number = l2_trace.header.number.unwrap().as_u64(); |
32 | | - let spec_id = fork_config.get_spec_id(block_number); |
33 | | - trace!("use spec id {:?}", spec_id); |
34 | | - |
35 | | - let mut db = CacheDB::new(ReadOnlyDB::new(l2_trace)); |
36 | | - fork_config.migrate(block_number, &mut db).unwrap(); |
37 | | - |
38 | | - let old_root = l2_trace.storage_trace.root_before; |
39 | | - let zktrie_state = ZktrieState::from_trace_with_additional( |
40 | | - old_root, |
41 | | - collect_account_proofs(&l2_trace.storage_trace), |
42 | | - collect_storage_proofs(&l2_trace.storage_trace), |
43 | | - l2_trace |
44 | | - .storage_trace |
45 | | - .deletion_proofs |
46 | | - .iter() |
47 | | - .map(|s| s.as_ref()), |
48 | | - ) |
49 | | - .unwrap(); |
50 | | - let root = *zktrie_state.root(); |
51 | | - debug!("building partial statedb done, root {}", hex::encode(root)); |
52 | | - |
53 | | - let mem_db = zktrie_state.into_inner(); |
54 | | - let zktrie = mem_db.new_trie(&root).unwrap(); |
55 | | - |
56 | | - Self { |
57 | | - db, |
58 | | - zktrie, |
59 | | - spec_id, |
60 | | - disable_checks, |
61 | | - } |
| 24 | + /// Get reference to the DB |
| 25 | + pub fn db(&self) -> &CacheDB<ReadOnlyDB> { |
| 26 | + &self.db |
62 | 27 | } |
63 | 28 |
|
64 | 29 | /// Handle a block. |
65 | | - pub fn handle_block(&mut self, l2_trace: &BlockTrace) -> H256 { |
| 30 | + pub fn handle_block(&mut self, l2_trace: &BlockTraceV2) -> H256 { |
66 | 31 | debug!("handle block {:?}", l2_trace.header.number.unwrap()); |
67 | 32 | let mut env = Box::<Env>::default(); |
68 | 33 | env.cfg.chain_id = l2_trace.chain_id; |
@@ -100,14 +65,8 @@ impl EvmExecutor { |
100 | 65 | let result = revm.transact_commit().unwrap(); // TODO: handle error |
101 | 66 | trace!("{result:#?}"); |
102 | 67 | } |
| 68 | + self.hooks.post_tx_execution(self, idx); |
103 | 69 | debug!("handle {idx}th tx done"); |
104 | | - |
105 | | - if !self.disable_checks { |
106 | | - if let Some(exec) = l2_trace.execution_results.get(idx) { |
107 | | - debug!("post check {idx}th tx"); |
108 | | - self.post_check(exec); |
109 | | - } |
110 | | - } |
111 | 70 | } |
112 | 71 | self.commit_changes(); |
113 | 72 | H256::from(self.zktrie.root()) |
@@ -256,56 +215,6 @@ impl EvmExecutor { |
256 | 215 | } |
257 | 216 | } |
258 | 217 | } |
259 | | - |
260 | | - fn post_check(&mut self, exec: &ExecutionResult) { |
261 | | - for account_post_state in exec.account_after.iter() { |
262 | | - let local_acc = self |
263 | | - .db |
264 | | - .basic_ref(account_post_state.address.0.into()) |
265 | | - .unwrap() |
266 | | - .unwrap(); |
267 | | - if log_enabled!(Level::Trace) { |
268 | | - let mut local_acc = local_acc.clone(); |
269 | | - local_acc.code = None; |
270 | | - trace!("local acc {local_acc:?}, trace acc {account_post_state:?}"); |
271 | | - } |
272 | | - let local_balance = U256(*local_acc.balance.as_limbs()); |
273 | | - if local_balance != account_post_state.balance { |
274 | | - let post = account_post_state.balance; |
275 | | - error!( |
276 | | - "incorrect balance, local {:#x} {} post {:#x} (diff {}{:#x})", |
277 | | - local_balance, |
278 | | - if local_balance < post { "<" } else { ">" }, |
279 | | - post, |
280 | | - if local_balance < post { "-" } else { "+" }, |
281 | | - if local_balance < post { |
282 | | - post - local_balance |
283 | | - } else { |
284 | | - local_balance - post |
285 | | - } |
286 | | - ) |
287 | | - } |
288 | | - if local_acc.nonce != account_post_state.nonce { |
289 | | - error!("incorrect nonce") |
290 | | - } |
291 | | - let p_hash = account_post_state.poseidon_code_hash; |
292 | | - if p_hash.is_zero() { |
293 | | - if !local_acc.is_empty() { |
294 | | - error!("incorrect poseidon_code_hash") |
295 | | - } |
296 | | - } else if local_acc.code_hash.0 != p_hash.0 { |
297 | | - error!("incorrect poseidon_code_hash") |
298 | | - } |
299 | | - let k_hash = account_post_state.keccak_code_hash; |
300 | | - if k_hash.is_zero() { |
301 | | - if !local_acc.is_empty() { |
302 | | - error!("incorrect keccak_code_hash") |
303 | | - } |
304 | | - } else if local_acc.keccak_code_hash.0 != k_hash.0 { |
305 | | - error!("incorrect keccak_code_hash") |
306 | | - } |
307 | | - } |
308 | | - } |
309 | 218 | } |
310 | 219 |
|
311 | 220 | impl Debug for EvmExecutor { |
|
0 commit comments