Skip to content

Commit 3d7b60c

Browse files
authored
refactor: remove hooks (#69)
The hooks pattern seems to be outdated since we no longer doing post tx checking. The only reason to have hook is to reuse the rlp bytes, which we can do it in a trivial way -- returning it after handling the block. This pr removes the ExecutionHook and changes the way we reusing the rlp bytes.
1 parent b44a38b commit 3d7b60c

File tree

8 files changed

+71
-125
lines changed

8 files changed

+71
-125
lines changed

crates/bin/src/commands/run_file.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
use crate::utils;
22
use anyhow::{anyhow, bail};
33
use clap::Args;
4-
use sbv::primitives::types::LegacyStorageTrace;
54
use sbv::{
6-
core::{ChunkInfo, EvmExecutorBuilder, HardforkConfig},
7-
primitives::{types::BlockTrace, zk_trie::db::kv::HashMapDb, Block, B256},
5+
core::{BlockExecutionResult, ChunkInfo, EvmExecutorBuilder, HardforkConfig},
6+
primitives::{
7+
types::{BlockTrace, LegacyStorageTrace},
8+
zk_trie::db::kv::HashMapDb,
9+
Block, B256,
10+
},
811
};
912
use serde::Deserialize;
1013
use std::panic::catch_unwind;
11-
use std::{cell::RefCell, path::PathBuf};
14+
use std::path::PathBuf;
1215
use tiny_keccak::{Hasher, Keccak};
1316
use tokio::task::JoinSet;
1417

@@ -80,22 +83,21 @@ impl RunFileCommand {
8083
let (chunk_info, mut zktrie_db) = ChunkInfo::from_block_traces(&traces);
8184
let mut code_db = HashMapDb::default();
8285

83-
let tx_bytes_hasher = RefCell::new(Keccak::v256());
86+
let mut tx_bytes_hasher = Keccak::v256();
8487

8588
let mut executor = EvmExecutorBuilder::new(&mut code_db, &mut zktrie_db)
8689
.hardfork_config(fork_config)
8790
.chain_id(traces[0].chain_id())
88-
.with_hooks(traces[0].root_before(), |hooks| {
89-
hooks.add_tx_rlp_handler(|_, rlp| {
90-
tx_bytes_hasher.borrow_mut().update(rlp);
91-
});
92-
})?;
91+
.build(traces[0].root_before())?;
9392
for trace in traces.iter() {
9493
executor.insert_codes(trace)?;
9594
}
9695

9796
for trace in traces.iter() {
98-
executor.handle_block(trace)?;
97+
let BlockExecutionResult { tx_rlps, .. } = executor.handle_block(trace)?;
98+
for tx_rlp in tx_rlps {
99+
tx_bytes_hasher.update(&tx_rlp);
100+
}
99101
}
100102

101103
let post_state_root = executor.commit_changes()?;
@@ -105,7 +107,7 @@ impl RunFileCommand {
105107
drop(executor);
106108

107109
let mut tx_bytes_hash = B256::ZERO;
108-
tx_bytes_hasher.into_inner().finalize(&mut tx_bytes_hash.0);
110+
tx_bytes_hasher.finalize(&mut tx_bytes_hash.0);
109111
let _public_input_hash = chunk_info.public_input_hash(&tx_bytes_hash);
110112

111113
dev_info!("[chunk mode] public input hash: {:?}", _public_input_hash);

crates/core/src/chunk.rs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,10 +117,9 @@ impl ChunkInfo {
117117
#[cfg(test)]
118118
mod tests {
119119
use super::*;
120-
use crate::{EvmExecutorBuilder, HardforkConfig};
120+
use crate::{BlockExecutionResult, EvmExecutorBuilder, HardforkConfig};
121121
use revm::primitives::b256;
122122
use sbv_primitives::types::BlockTrace;
123-
use std::cell::RefCell;
124123

125124
const TRACES_STR: [&str; 4] = [
126125
include_str!("../../../testdata/mainnet_blocks/8370400.json"),
@@ -145,31 +144,30 @@ mod tests {
145144
let (chunk_info, mut zktrie_db) = ChunkInfo::from_block_traces(&traces);
146145
let mut code_db = HashMapDb::default();
147146

148-
let tx_bytes_hasher = RefCell::new(Keccak::v256());
147+
let mut tx_bytes_hasher = Keccak::v256();
149148

150149
let mut executor = EvmExecutorBuilder::new(&mut code_db, &mut zktrie_db)
151150
.hardfork_config(fork_config)
152151
.chain_id(traces[0].chain_id())
153-
.with_hooks(traces[0].root_before(), |hooks| {
154-
hooks.add_tx_rlp_handler(|_, rlp| {
155-
tx_bytes_hasher.borrow_mut().update(rlp);
156-
});
157-
})
152+
.build(traces[0].root_before())
158153
.unwrap();
159154
for trace in traces.iter() {
160155
executor.insert_codes(trace).unwrap();
161156
}
162157

163158
for trace in traces.iter() {
164-
executor.handle_block(trace).unwrap();
159+
let BlockExecutionResult { tx_rlps, .. } = executor.handle_block(trace).unwrap();
160+
for tx_rlp in tx_rlps {
161+
tx_bytes_hasher.update(&tx_rlp);
162+
}
165163
}
166164

167165
let post_state_root = executor.commit_changes().unwrap();
168166
assert_eq!(post_state_root, chunk_info.post_state_root);
169167
drop(executor); // drop executor to release Rc<Keccek>
170168

171169
let mut tx_bytes_hash = B256::ZERO;
172-
tx_bytes_hasher.into_inner().finalize(&mut tx_bytes_hash.0);
170+
tx_bytes_hasher.finalize(&mut tx_bytes_hash.0);
173171
let public_input_hash = chunk_info.public_input_hash(&tx_bytes_hash);
174172
assert_eq!(
175173
public_input_hash,

crates/core/src/executor/builder.rs

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
use crate::error::DatabaseError;
2-
use crate::{executor::hooks::ExecuteHooks, EvmDatabase, EvmExecutor, HardforkConfig};
1+
use crate::{error::DatabaseError, EvmDatabase, EvmExecutor, HardforkConfig};
32
use revm::db::CacheDB;
4-
use sbv_primitives::alloy_primitives::ChainId;
5-
use sbv_primitives::zk_trie::db::kv::KVDatabase;
6-
use sbv_primitives::zk_trie::db::NodeDb;
7-
use sbv_primitives::B256;
3+
use sbv_primitives::{
4+
alloy_primitives::ChainId, zk_trie::db::kv::KVDatabase, zk_trie::db::NodeDb, B256,
5+
};
86
use std::fmt::{self, Debug};
97

108
/// Builder for EVM executor.
@@ -93,14 +91,7 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static>
9391
EvmExecutorBuilder<'a, HardforkConfig, ChainId, CodeDb, ZkDb>
9492
{
9593
/// Initialize an EVM executor from a block trace as the initial state.
96-
pub fn with_hooks<'h, F: FnOnce(&mut ExecuteHooks<'h, CodeDb, ZkDb>)>(
97-
self,
98-
root: B256,
99-
with_execute_hooks: F,
100-
) -> Result<EvmExecutor<'a, 'h, CodeDb, ZkDb>, DatabaseError> {
101-
let mut execute_hooks = ExecuteHooks::new();
102-
with_execute_hooks(&mut execute_hooks);
103-
94+
pub fn build(self, root: B256) -> Result<EvmExecutor<'a, CodeDb, ZkDb>, DatabaseError> {
10495
let db = cycle_track!(
10596
CacheDB::new(EvmDatabase::new_from_root(
10697
root,
@@ -114,12 +105,6 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static>
114105
hardfork_config: self.hardfork_config,
115106
chain_id: self.chain_id,
116107
db,
117-
hooks: execute_hooks,
118108
})
119109
}
120-
121-
/// Initialize an EVM executor from a block trace as the initial state.
122-
pub fn build<'e>(self, root: B256) -> Result<EvmExecutor<'a, 'e, CodeDb, ZkDb>, DatabaseError> {
123-
self.with_hooks(root, |_| {})
124-
}
125110
}

crates/core/src/executor/hooks.rs

Lines changed: 0 additions & 70 deletions
This file was deleted.

crates/core/src/executor/mod.rs

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use revm::{
99
primitives::{AccountInfo, Env, B256, KECCAK_EMPTY, POSEIDON_EMPTY},
1010
};
1111
use sbv_primitives::{
12+
alloy_primitives::Bytes,
1213
zk_trie::{
1314
db::kv::KVDatabase,
1415
hash::{key_hasher::NoCacheHasher, poseidon::Poseidon},
@@ -22,18 +23,23 @@ use std::fmt::Debug;
2223
mod builder;
2324
pub use builder::EvmExecutorBuilder;
2425

25-
/// Execute hooks
26-
pub mod hooks;
27-
2826
/// EVM executor that handles the block.
29-
pub struct EvmExecutor<'db, 'h, CodeDb, ZkDb> {
27+
pub struct EvmExecutor<'db, CodeDb, ZkDb> {
3028
chain_id: ChainId,
3129
hardfork_config: HardforkConfig,
3230
db: CacheDB<EvmDatabase<'db, CodeDb, ZkDb>>,
33-
hooks: hooks::ExecuteHooks<'h, CodeDb, ZkDb>,
3431
}
3532

36-
impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb, ZkDb> {
33+
/// Block execution result
34+
#[derive(Debug, Clone)]
35+
pub struct BlockExecutionResult {
36+
/// Gas used in this block
37+
pub gas_used: u64,
38+
/// RLP bytes of transactions
39+
pub tx_rlps: Vec<Bytes>,
40+
}
41+
42+
impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, CodeDb, ZkDb> {
3743
/// Get reference to the DB
3844
pub fn db(&self) -> &CacheDB<EvmDatabase<CodeDb, ZkDb>> {
3945
&self.db
@@ -45,7 +51,10 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
4551
}
4652

4753
/// Handle a block.
48-
pub fn handle_block<T: Block>(&mut self, l2_trace: &T) -> Result<u64, VerificationError> {
54+
pub fn handle_block<T: Block>(
55+
&mut self,
56+
l2_trace: &T,
57+
) -> Result<BlockExecutionResult, VerificationError> {
4958
#[allow(clippy::let_and_return)]
5059
let gas_used = measure_duration_millis!(
5160
handle_block_duration_milliseconds,
@@ -59,7 +68,10 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
5968
}
6069

6170
#[inline(always)]
62-
fn handle_block_inner<T: Block>(&mut self, l2_trace: &T) -> Result<u64, VerificationError> {
71+
fn handle_block_inner<T: Block>(
72+
&mut self,
73+
l2_trace: &T,
74+
) -> Result<BlockExecutionResult, VerificationError> {
6375
let spec_id = self.hardfork_config.get_spec_id(l2_trace.number());
6476
dev_trace!("use spec id {spec_id:?}",);
6577
self.hardfork_config
@@ -81,6 +93,7 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
8193
};
8294

8395
let mut gas_used = 0;
96+
let mut tx_rlps = Vec::with_capacity(l2_trace.num_txs());
8497

8598
for (idx, tx) in l2_trace.transactions().enumerate() {
8699
cycle_tracker_start!("handle tx");
@@ -129,7 +142,7 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
129142
}
130143
env.tx.scroll.is_l1_msg = tx.is_l1_msg();
131144
let rlp_bytes = tx.rlp();
132-
self.hooks.tx_rlp(self, &rlp_bytes);
145+
tx_rlps.push(rlp_bytes.clone());
133146
env.tx.scroll.rlp_bytes = Some(rlp_bytes);
134147

135148
dev_trace!("{env:#?}");
@@ -161,12 +174,11 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
161174

162175
dev_trace!("{result:#?}");
163176
}
164-
self.hooks.post_tx_execution(self, idx);
165177

166178
dev_debug!("handle {idx}th tx done");
167179
cycle_tracker_end!("handle tx");
168180
}
169-
Ok(gas_used)
181+
Ok(BlockExecutionResult { gas_used, tx_rlps })
170182
}
171183

172184
/// Commit pending changes in cache db to zktrie
@@ -345,7 +357,7 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
345357
}
346358
}
347359

348-
impl<CodeDb, ZkDb> Debug for EvmExecutor<'_, '_, CodeDb, ZkDb> {
360+
impl<CodeDb, ZkDb> Debug for EvmExecutor<'_, CodeDb, ZkDb> {
349361
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
350362
f.debug_struct("EvmExecutor").field("db", &self.db).finish()
351363
}

crates/core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod error;
1414
pub use error::{DatabaseError, VerificationError};
1515

1616
mod executor;
17-
pub use executor::{hooks, EvmExecutor, EvmExecutorBuilder};
17+
pub use executor::{BlockExecutionResult, EvmExecutor, EvmExecutorBuilder};
1818

1919
mod genesis;
2020
pub use genesis::GenesisConfig;

crates/primitives/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ pub trait Block: Debug {
6969
/// transactions
7070
fn transactions(&self) -> impl Iterator<Item = &Self::Tx>;
7171

72+
/// Number of l1 transactions
73+
fn num_txs(&self) -> usize;
74+
7275
/// root before
7376
fn root_before(&self) -> B256;
7477
/// root after
@@ -314,6 +317,10 @@ impl<T: Block> Block for &T {
314317
(*self).transactions()
315318
}
316319

320+
fn num_txs(&self) -> usize {
321+
(*self).num_txs()
322+
}
323+
317324
fn root_before(&self) -> B256 {
318325
(*self).root_before()
319326
}

crates/primitives/src/types/mod.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,10 @@ where
380380
self.transactions.iter()
381381
}
382382

383+
fn num_txs(&self) -> usize {
384+
self.transactions.len()
385+
}
386+
383387
fn root_before(&self) -> B256 {
384388
self.storage_trace.root_before()
385389
}
@@ -459,6 +463,10 @@ where
459463
self.transactions.iter()
460464
}
461465

466+
fn num_txs(&self) -> usize {
467+
self.transactions.len()
468+
}
469+
462470
fn root_before(&self) -> B256 {
463471
self.storage_trace.root_before()
464472
}
@@ -672,6 +680,10 @@ impl Block for alloy::rpc::types::Block<AlloyTransaction, alloy::rpc::types::Hea
672680
self.transactions.txns()
673681
}
674682

683+
fn num_txs(&self) -> usize {
684+
self.transactions.len()
685+
}
686+
675687
fn root_before(&self) -> B256 {
676688
unimplemented!()
677689
}

0 commit comments

Comments
 (0)