Skip to content

Commit

Permalink
save work
Browse files Browse the repository at this point in the history
  • Loading branch information
lightsing committed Oct 21, 2024
1 parent a94e7d3 commit 65930c6
Show file tree
Hide file tree
Showing 9 changed files with 556 additions and 495 deletions.
665 changes: 306 additions & 359 deletions Cargo.lock

Large diffs are not rendered by default.

50 changes: 19 additions & 31 deletions crates/core/src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ use revm::{
db::DatabaseRef,
primitives::{AccountInfo, Address, Bytecode, B256, U256},
};
use sbv_primitives::zk_trie::db::NodeDb;
use sbv_primitives::zk_trie::hash::ZkHash;
use sbv_primitives::{
zk_trie::{
db::kv::{KVDatabase, KVDatabaseItem},
hash::{key_hasher::NoCacheHasher, poseidon::Poseidon},
db::{
kv::{KVDatabase, KVDatabaseItem},
NodeDb,
},
hash::{key_hasher::NoCacheHasher, poseidon::Poseidon, ZkHash},
scroll_types::Account,
trie::ZkTrie,
},
Expand All @@ -21,7 +22,7 @@ type Result<T, E = DatabaseError> = std::result::Result<T, E>;
/// A database that consists of account and storage information.
pub struct EvmDatabase<'a, CodeDb, ZkDb> {
/// Map of code hash to bytecode.
code_db: CodeDb,
pub(crate) code_db: &'a mut CodeDb,
/// Storage root cache, avoid re-query account when storage root is needed
storage_root_caches: RefCell<HashMap<Address, ZkHash>>,
/// Storage trie cache, avoid re-creating trie for the same account.
Expand All @@ -44,23 +45,12 @@ impl<CodeDb, Db> fmt::Debug for EvmDatabase<'_, CodeDb, Db> {
}

impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmDatabase<'a, CodeDb, ZkDb> {
/// Initialize an EVM database from a block trace.
pub fn new<T: Block>(
l2_trace: T,
mut code_db: CodeDb,
/// Initialize an EVM database from a zkTrie root.
pub fn new_from_root(
committed_zktrie_root: B256,
code_db: &'a mut CodeDb,
zktrie_db: &'a mut NodeDb<ZkDb>,
) -> Result<Self> {
cycle_tracker_start!("insert CodeDB");
for code in l2_trace.codes() {
let hash = revm::primitives::keccak256(code);
code_db
.or_put(hash.as_slice(), code)
.map_err(DatabaseError::code_db)?;
}
cycle_tracker_end!("insert CodeDB");

let committed_zktrie_root = l2_trace.root_before();

let zktrie = ZkTrie::new_with_root(zktrie_db, NoCacheHasher, committed_zktrie_root)
.map_err(DatabaseError::zk_trie)?;

Expand Down Expand Up @@ -113,11 +103,14 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmDatabase<'a, CodeDb,
}

/// Update the database with a new block trace.
pub fn update<T: Block>(&mut self, l2_trace: T) -> Result<()> {
measure_duration_millis!(update_db_duration_milliseconds, self.update_inner(l2_trace))
pub fn insert_codes<T: Block>(&mut self, l2_trace: T) -> Result<()> {
measure_duration_millis!(
update_db_duration_milliseconds,
self.insert_codes_inner(l2_trace)
)
}

fn update_inner<T: Block>(&mut self, l2_trace: T) -> Result<()> {
fn insert_codes_inner<T: Block>(&mut self, l2_trace: T) -> Result<()> {
cycle_tracker_start!("insert CodeDB");
for code in l2_trace.codes() {
let hash = revm::primitives::keccak256(code);
Expand All @@ -126,13 +119,6 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmDatabase<'a, CodeDb,
.map_err(DatabaseError::code_db)?;
}
cycle_tracker_end!("insert CodeDB");

self.zktrie = cycle_track!(
ZkTrie::new_with_root(self.zktrie_db, NoCacheHasher, l2_trace.root_before(),),
"ZkTrie::new_with_root"
)
.map_err(DatabaseError::zk_trie)?;

Ok(())
}
}
Expand Down Expand Up @@ -208,7 +194,9 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> DatabaseRef for EvmDatabase

ZkTrie::new_with_root(self.zktrie_db, NoCacheHasher, *storage_root)
.inspect_err(|e| {
dev_warn!("storage trie associated with account({address}) not found: {e}")
let backtrace = std::backtrace::Backtrace::force_capture();
dev_warn!("storage trie associated with account({address}) not found: {e}\n{backtrace}");

})
.ok()
});
Expand Down
47 changes: 28 additions & 19 deletions crates/core/src/executor/builder.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
use crate::error::DatabaseError;
use crate::{executor::hooks::ExecuteHooks, EvmDatabase, EvmExecutor, HardforkConfig};
use revm::db::CacheDB;
use sbv_primitives::alloy_primitives::ChainId;
use sbv_primitives::zk_trie::db::kv::KVDatabase;
use sbv_primitives::zk_trie::db::NodeDb;
use sbv_primitives::Block;
use sbv_primitives::B256;
use std::fmt::{self, Debug};
use sbv_primitives::alloy_primitives::ChainId;

/// Builder for EVM executor.
pub struct EvmExecutorBuilder<'a, H, C, CodeDb, ZkDb> {
hardfork_config: H,
chain_id: C,
code_db: CodeDb,
code_db: &'a mut CodeDb,
zktrie_db: &'a mut NodeDb<ZkDb>,
}

Expand All @@ -28,7 +28,7 @@ impl<H: Debug, C: Debug, CodeDb, ZkDb> Debug for EvmExecutorBuilder<'_, H, C, Co

impl<'a, CodeDb, ZkDb> EvmExecutorBuilder<'a, (), (), CodeDb, ZkDb> {
/// Create a new builder.
pub fn new(code_db: CodeDb, zktrie_db: &'a mut NodeDb<ZkDb>) -> Self {
pub fn new(code_db: &'a mut CodeDb, zktrie_db: &'a mut NodeDb<ZkDb>) -> Self {
Self {
hardfork_config: (),
chain_id: (),
Expand All @@ -52,8 +52,21 @@ impl<'a, H, C, CodeDb, ZkDb> EvmExecutorBuilder<'a, H, C, CodeDb, ZkDb> {
}
}

/// Set chain id.
pub fn chain_id<C1>(self, chain_id: C1) -> EvmExecutorBuilder<'a, H, C1, CodeDb, ZkDb> {
EvmExecutorBuilder {
hardfork_config: self.hardfork_config,
chain_id,
code_db: self.code_db,
zktrie_db: self.zktrie_db,
}
}

/// Set code db.
pub fn code_db<CodeDb1>(self, code_db: CodeDb1) -> EvmExecutorBuilder<'a, H, C, CodeDb1, ZkDb> {
pub fn code_db<CodeDb1>(
self,
code_db: &'a mut CodeDb1,
) -> EvmExecutorBuilder<'a, H, C, CodeDb1, ZkDb> {
EvmExecutorBuilder {
hardfork_config: self.hardfork_config,
chain_id: self.chain_id,
Expand All @@ -65,7 +78,7 @@ impl<'a, H, C, CodeDb, ZkDb> EvmExecutorBuilder<'a, H, C, CodeDb, ZkDb> {
/// Set zktrie db.
pub fn zktrie_db<ZkDb1>(
self,
zktrie_db: &mut NodeDb<ZkDb1>,
zktrie_db: &'a mut NodeDb<ZkDb1>,
) -> EvmExecutorBuilder<H, C, CodeDb, ZkDb1> {
EvmExecutorBuilder {
hardfork_config: self.hardfork_config,
Expand All @@ -80,21 +93,20 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static>
EvmExecutorBuilder<'a, HardforkConfig, ChainId, CodeDb, ZkDb>
{
/// Initialize an EVM executor from a block trace as the initial state.
pub fn with_hooks<'h, T: Block, F: FnOnce(&mut ExecuteHooks<'h, CodeDb, ZkDb>)>(
pub fn with_hooks<'h, F: FnOnce(&mut ExecuteHooks<'h, CodeDb, ZkDb>)>(
self,
l2_trace: &T,
root: B256,
with_execute_hooks: F,
) -> Result<EvmExecutor<'a, 'h, CodeDb, ZkDb>, DatabaseError> {
let mut execute_hooks = ExecuteHooks::new();
with_execute_hooks(&mut execute_hooks);

let block_number = l2_trace.number();
let spec_id = self.hardfork_config.get_spec_id(block_number);

dev_trace!("use spec id {:?}", spec_id);

let db = cycle_track!(
CacheDB::new(EvmDatabase::new(l2_trace, self.code_db, self.zktrie_db)?),
CacheDB::new(EvmDatabase::new_from_root(
root,
self.code_db,
self.zktrie_db
)?),
"build ReadOnlyDB"
);

Expand All @@ -107,10 +119,7 @@ impl<'a, CodeDb: KVDatabase, ZkDb: KVDatabase + 'static>
}

/// Initialize an EVM executor from a block trace as the initial state.
pub fn build<'e, T: Block>(
self,
l2_trace: &T,
) -> Result<EvmExecutor<'a, 'e, CodeDb, ZkDb>, DatabaseError> {
self.with_hooks(l2_trace, |_| {})
pub fn build<'e>(self, root: B256) -> Result<EvmExecutor<'a, 'e, CodeDb, ZkDb>, DatabaseError> {
self.with_hooks(root, |_| {})
}
}
63 changes: 38 additions & 25 deletions crates/core/src/executor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,9 @@ use revm::{
use sbv_primitives::{
zk_trie::{
db::kv::KVDatabase,
hash::{
key_hasher::NoCacheHasher,
poseidon::{Poseidon, PoseidonError},
},
hash::{key_hasher::NoCacheHasher, poseidon::Poseidon},
scroll_types::Account,
trie::{ZkTrie, ZkTrieError},
trie::ZkTrie,
},
Block, Transaction, TxTrace,
};
Expand All @@ -42,9 +39,9 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
&self.db
}

/// Update the DB
pub fn update_db<T: Block>(&mut self, l2_trace: &T) -> Result<(), DatabaseError> {
self.db.db.update(l2_trace)
/// Insert codes from trace into CodeDB
pub fn insert_codes<T: Block>(&mut self, l2_trace: &T) -> Result<(), DatabaseError> {
self.db.db.insert_codes(l2_trace)
}

/// Handle a block.
Expand Down Expand Up @@ -90,8 +87,6 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,

dev_trace!("handle {idx}th tx");

let caller = unsafe { tx.get_from_unchecked() };

let tx = tx
.try_build_typed_tx()
.map_err(|e| VerificationError::InvalidSignature {
Expand All @@ -102,7 +97,12 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
dev_trace!("{tx:#?}");
let mut env = env.clone();
env.tx = TxEnv {
caller,
caller: tx.get_or_recover_signer().map_err(|e| {
VerificationError::InvalidSignature {
tx_hash: *tx.tx_hash(),
source: e,
}
})?,
gas_limit: tx.gas_limit() as u64,
gas_price: tx
.effective_gas_price(l2_trace.base_fee_per_gas().unwrap_or_default().to())
Expand Down Expand Up @@ -173,14 +173,11 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
pub fn commit_changes(&mut self) -> Result<B256, DatabaseError> {
measure_duration_millis!(
commit_changes_duration_milliseconds,
cycle_track!(
self.commit_changes_inner().map_err(DatabaseError::zk_trie),
"commit_changes"
)
cycle_track!(self.commit_changes_inner(), "commit_changes")
)
}

fn commit_changes_inner(&mut self) -> Result<B256, ZkTrieError<PoseidonError, ZkDb::Error>> {
fn commit_changes_inner(&mut self) -> Result<B256, DatabaseError> {
let mut zktrie = ZkTrie::<Poseidon>::new_with_root(
self.db.db.zktrie_db,
NoCacheHasher,
Expand All @@ -203,7 +200,9 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
continue;
}
if let Some(ref code) = info.code {
code_db
self.db
.db
.code_db
.or_put(info.code_hash.as_slice(), code.bytecode().as_ref())
.unwrap();
}
Expand Down Expand Up @@ -232,11 +231,9 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
measure_duration_micros!(
zktrie_update_duration_microseconds,
cycle_track!(
storage_trie.update(
self.db.db.zktrie_db,
key.to_be_bytes::<32>(),
value
)?,
storage_trie
.update(self.db.db.zktrie_db, key.to_be_bytes::<32>(), value)
.map_err(DatabaseError::zk_trie)?,
"Zktrie::update_store"
)
);
Expand All @@ -245,7 +242,8 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,
zktrie_delete_duration_microseconds,
cycle_track!(
storage_trie
.delete(self.db.db.zktrie_db, key.to_be_bytes::<32>())?,
.delete(self.db.db.zktrie_db, key.to_be_bytes::<32>())
.map_err(DatabaseError::zk_trie)?,
"Zktrie::delete"
)
);
Expand All @@ -257,7 +255,12 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,

measure_duration_micros!(
zktrie_commit_duration_microseconds,
cycle_track!(storage_trie.commit(self.db.db.zktrie_db)?, "Zktrie::commit")
cycle_track!(
storage_trie
.commit(self.db.db.zktrie_db)
.map_err(DatabaseError::zk_trie)?,
"Zktrie::commit"
)
);

cycle_tracker_end!("update storage_tire");
Expand Down Expand Up @@ -306,13 +309,23 @@ impl<CodeDb: KVDatabase, ZkDb: KVDatabase + 'static> EvmExecutor<'_, '_, CodeDb,

measure_duration_micros!(
zktrie_commit_duration_microseconds,
cycle_track!(zktrie.commit(self.db.db.zktrie_db)?, "Zktrie::commit")
cycle_track!(
zktrie
.commit(self.db.db.zktrie_db)
.map_err(DatabaseError::zk_trie)?,
"Zktrie::commit"
)
);

let root_after = *zktrie.root().unwrap_ref();

self.db.db.updated_committed_zktrie_root(root_after);

self.db.accounts.clear();
self.db.contracts.clear();
self.db.block_hashes.clear();
self.db.logs.clear();

Ok(B256::from(root_after))
}
}
Expand Down
Loading

0 comments on commit 65930c6

Please sign in to comment.