Skip to content

Commit

Permalink
feat: portable sbv-primitives (#89)
Browse files Browse the repository at this point in the history
* feat: add EIP-7702 tx support (#85)

* upgrade

* upgrade

* Update Cargo.toml

* change branches

* remove poseidon field

* fix scroll types

* trailing lf

* feat: dump utils (#83)

* provide utils lib

* clippy

* unify imports

* fix

* style fix

* add EIP-7702 tx support

* upgrade reth

---------

Co-authored-by: Zhang Zhuo <[email protected]>

* feat: msg queue hash (#84)

* upgrade

* upgrade

* Update Cargo.toml

* change branches

* remove poseidon field

* fix scroll types

* trailing lf

* feat: dump utils (#83)

* provide utils lib

* clippy

* unify imports

* fix

* style fix

* impl msg queue hash

* remove legacy test

* move chunk into primitives and impl EuclidV2

* set prev_msg_queue_hash

* use is_l1_message

* feat: num l1 msgs in scroll block

* fix: usize instead of u64 for num txs

* chore: clippy fix remove unused import

* apply suggestion

---------

Co-authored-by: Zhang Zhuo <[email protected]>
Co-authored-by: Rohit Narurkar <[email protected]>

* fix Eip7702 signature

* chore: update reth dep

* fix bytecode construct

* upgrade to fix

* add euclid v2 test cases

* fix cli

* remove unused

* impl is_euclid_v2 in chunk

* clippy

* fix ChunkInfo

* fix chunk mode

* refactor

* refactor

* refactor primitives crate

* fix others

* export sbv-utils

* fix merge

* fmt

* clippy

---------

Co-authored-by: Zhang Zhuo <[email protected]>
Co-authored-by: Rohit Narurkar <[email protected]>
  • Loading branch information
3 people authored Mar 4, 2025
1 parent fc4ece0 commit e59614d
Show file tree
Hide file tree
Showing 33 changed files with 1,674 additions and 1,383 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions crates/bin/src/commands/run_file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ impl RunFileCommand {
core::{EvmDatabase, EvmExecutor},
kv::{nohash::NoHashMap, null::NullProvider},
primitives::{
BlockWitness as _,
chainspec::{Chain, get_chain_spec_or_build},
ext::{BlockWitnessChunkExt, BlockWitnessExt},
types::{BlockWitness, ChunkInfoBuilder},
types::{BlockWitness, reth::BlockWitnessRethExt, scroll::ChunkInfoBuilder},
},
trie::BlockWitnessTrieExt,
};
Expand Down
6 changes: 3 additions & 3 deletions crates/bin/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ use sbv::{
core::{EvmDatabase, EvmExecutor, VerificationError},
kv::nohash::NoHashMap,
primitives::{
BlockWitness,
chainspec::{Chain, get_chain_spec_or_build},
ext::BlockWitnessExt,
types::reth::BlockWitnessRethExt,
},
trie::BlockWitnessTrieExt,
};

pub fn verify<T: BlockWitness + BlockWitnessTrieExt + BlockWitnessExt>(
pub fn verify<T: BlockWitnessRethExt + BlockWitnessTrieExt + BlockWitnessExt>(
witness: T,
) -> Result<(), VerificationError> {
measure_duration_millis!(
Expand All @@ -18,7 +18,7 @@ pub fn verify<T: BlockWitness + BlockWitnessTrieExt + BlockWitnessExt>(
)
}

fn verify_inner<T: BlockWitness + BlockWitnessTrieExt + BlockWitnessExt>(
fn verify_inner<T: BlockWitnessRethExt + BlockWitnessTrieExt + BlockWitnessExt>(
witness: T,
) -> Result<(), VerificationError> {
dev_trace!("{witness:#?}");
Expand Down
4 changes: 2 additions & 2 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ reth-storage-errors.workspace = true

thiserror.workspace = true

sbv-primitives.workspace = true
sbv-primitives = { workspace = true, features = ["ethereum-all", "rkyv", "serde"] }
sbv-helpers.workspace = true
sbv-kv.workspace = true
sbv-trie.workspace = true
Expand All @@ -38,7 +38,7 @@ scroll = [
"reth-evm-ethereum/scroll",
"reth-execution-types/scroll",
"reth-scroll-evm/scroll",
"sbv-primitives/scroll",
"sbv-primitives/scroll-all",
]
debug-account = ["sbv-helpers/debug-account"]
debug-storage = ["sbv-helpers/debug-storage"]
Expand Down
9 changes: 6 additions & 3 deletions crates/core/src/database.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use sbv_kv::{HashMap, KeyValueStoreGet};
use sbv_primitives::{
AccountInfo, Address, B256, Bytecode, Bytes, U256,
revm::{db::BundleAccount, interpreter::analysis::to_analysed},
Address, B256, Bytes, U256,
types::{
AccountInfo, Bytecode,
revm::{db::BundleAccount, interpreter::analysis::to_analysed},
},
};
use sbv_trie::{PartialStateTrie, TrieNode};
use std::{cell::RefCell, fmt};

pub use sbv_primitives::revm::db::DatabaseRef;
pub use sbv_primitives::types::revm::db::DatabaseRef;

/// A database that consists of account and storage information.
pub struct EvmDatabase<CodeDb, NodesProvider, BlockHashProvider> {
Expand Down
8 changes: 5 additions & 3 deletions crates/core/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ use reth_evm::execute::{BlockExecutorProvider, Executor};
use reth_execution_types::BlockExecutionOutput;
use sbv_kv::KeyValueStoreGet;
use sbv_primitives::{
B256, Bytes, RecoveredBlock,
B256, Bytes,
chainspec::ChainSpec,
revm::db::CacheDB,
types::reth::{Block, Receipt},
types::{
reth::{Block, Receipt, RecoveredBlock},
revm::db::CacheDB,
},
};
use sbv_trie::TrieNode;
use std::{fmt::Debug, sync::Arc};
Expand Down
114 changes: 90 additions & 24 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,24 @@ workspace = true
[dependencies]
auto_impl.workspace = true
itertools.workspace = true
rkyv.workspace = true
serde = { workspace = true, features = ["derive"] }
tiny-keccak.workspace = true

alloy-consensus.workspace = true
alloy-eips.workspace = true
alloy-network.workspace = true
alloy-rpc-types-eth.workspace = true
alloy-serde.workspace = true
rkyv = { workspace = true, optional = true }
serde = { workspace = true, optional = true }

alloy-consensus = { workspace = true, optional = true }
alloy-eips = { workspace = true, optional = true }
alloy-network = { workspace = true, optional = true }
alloy-rpc-types-eth = { workspace = true, optional = true }
alloy-serde = { workspace = true, optional = true }

alloy-primitives.workspace = true

revm.workspace = true
reth-chainspec.workspace = true
reth-ethereum-forks.workspace = true
reth-primitives.workspace = true
reth-primitives-traits.workspace = true
revm = { workspace = true, optional = true }
reth-chainspec = { workspace = true, optional = true }
reth-ethereum-forks = { workspace = true, optional = true }
reth-primitives = { workspace = true, optional = true }
reth-primitives-traits = { workspace = true, optional = true }
reth-scroll-chainspec = { workspace = true, optional = true }
reth-scroll-forks = { workspace = true, optional = true }
reth-scroll-primitives = { workspace = true, optional = true }
Expand All @@ -46,19 +47,84 @@ sbv-kv.workspace = true
[dev-dependencies]

[features]
scroll = [
"dep:reth-scroll-chainspec",
"dep:reth-scroll-forks",
"dep:reth-scroll-primitives",
"dep:scroll-alloy-consensus",
"dep:scroll-alloy-rpc-types",
"dep:scroll-alloy-network",
"reth-scroll-forks/serde",
"reth-scroll-primitives/serde",
"reth-scroll-primitives/scroll",
"revm/scroll-default-handler",
"revm/optional_no_base_fee",
# serialization
rkyv = ["dep:rkyv"]
serde = [
"dep:alloy-serde",
"dep:serde",
"reth-scroll-primitives?/serde",
]

# core features switch
chainspec = ["dep:reth-chainspec"]
consensus-types = ["dep:alloy-consensus"]
eips = ["dep:alloy-eips"]
network-types = ["dep:alloy-network"]
hardforks = ["dep:reth-ethereum-forks"]
reth-types = [
"serde",
"consensus-types",
"eips",
"dep:reth-primitives",
"dep:reth-primitives-traits",
]
revm-types = ["dep:revm"]
rpc-types = ["dep:alloy-rpc-types-eth", "eips"]
ethereum-all = [
"chainspec",
"consensus-types",
"eips",
"network-types",
"hardforks",
"reth-types",
"revm-types",
"rpc-types",
]

scroll = []
scroll-chainspec = ["scroll", "chainspec", "dep:reth-scroll-chainspec"]
scroll-consensus-types = [
"scroll",
"consensus-types",
"dep:scroll-alloy-consensus",
"scroll-alloy-consensus/serde", # This is a bug
"scroll-alloy-consensus/reth-codec", # This is a bug
]
scroll-hardforks = [
"scroll",
"hardforks",
"dep:reth-scroll-forks",
"reth-scroll-forks/serde",
]
scroll-network-types = ["scroll", "network-types", "dep:scroll-alloy-network"]
scroll-pre-deployed = ["scroll"]
scroll-reth-types = [
"scroll",
"reth-types",
"scroll-revm", # This is a bug
"scroll-consensus-types",
"dep:reth-scroll-primitives",
"reth-scroll-primitives/scroll",
]
scroll-revm = [
"scroll",
"revm-types",
"revm/scroll-default-handler",
"revm/optional_no_base_fee",
]
scroll-rpc-types = ["scroll", "rpc-types", "dep:scroll-alloy-rpc-types"]
scroll-all = [
"scroll",
"scroll-chainspec",
"scroll-consensus-types",
"scroll-network-types",
"scroll-hardforks",
"scroll-pre-deployed",
"scroll-reth-types",
"scroll-revm",
"scroll-rpc-types",
]

dev = ["sbv-helpers/dev"]

sp1 = []
Expand Down
3 changes: 1 addition & 2 deletions crates/primitives/src/chainspec.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::sync::Arc;

pub use reth_chainspec;
pub use reth_chainspec::*;
pub use reth_chainspec::{self, *};

#[cfg(feature = "scroll")]
pub use reth_scroll_chainspec as scroll;
Expand Down
97 changes: 90 additions & 7 deletions crates/primitives/src/ext.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{B256, BlockWitness, Bytes, keccak256, types::consensus::BlockHeader};
use crate::{B256, BlockWitness, Bytes, keccak256};
#[cfg(feature = "scroll")]
use itertools::Itertools;
use sbv_helpers::cycle_track;
Expand Down Expand Up @@ -38,7 +38,7 @@ impl<T: BlockWitness> BlockWitnessChunkExt for [T] {
fn has_seq_block_number(&self) -> bool {
self.iter()
.tuple_windows()
.all(|(a, b)| a.header().number() + 1 == b.header().number())
.all(|(a, b)| a.number() + 1 == b.number())
}
}

Expand Down Expand Up @@ -68,7 +68,7 @@ impl<T: BlockWitness> BlockWitnessExt for T {
&self,
mut block_hashes: BlockHashProvider,
) {
let block_number = self.header().number();
let block_number = self.number();
for (i, hash) in self.block_hashes_iter().enumerate() {
let block_number = block_number
.checked_sub(i as u64 + 1)
Expand All @@ -93,7 +93,7 @@ impl<T: BlockWitness> BlockWitnessExt for [T] {
mut block_hashes: BlockHashProvider,
) {
for witness in self.iter() {
let block_number = witness.header().number();
let block_number = witness.number();
for (i, hash) in witness.block_hashes_iter().enumerate() {
let block_number = block_number
.checked_sub(i as u64 + 1)
Expand All @@ -114,9 +114,9 @@ pub trait TxBytesHashExt {
fn tx_bytes_hash_in(self, rlp_buffer: &mut Vec<u8>) -> (usize, B256);
}

#[cfg(feature = "scroll")]
impl<'a, I: IntoIterator<Item = &'a Tx>, Tx: alloy_eips::eip2718::Encodable2718 + 'a> TxBytesHashExt
for I
#[cfg(all(feature = "scroll", feature = "eips"))]
impl<'a, I: IntoIterator<Item = &'a Tx>, Tx: crate::types::eips::eip2718::Encodable2718 + 'a>
TxBytesHashExt for I
{
fn tx_bytes_hash(self) -> (usize, B256) {
let mut rlp_buffer = Vec::new();
Expand All @@ -138,3 +138,86 @@ impl<'a, I: IntoIterator<Item = &'a Tx>, Tx: alloy_eips::eip2718::Encodable2718
(len, tx_bytes_hash)
}
}

/// Chunk related extension methods for Block
#[cfg(feature = "scroll-reth-types")]
pub trait BlockChunkExt {
/// Hash the header of the block
fn legacy_hash_da_header(&self, hasher: &mut impl tiny_keccak::Hasher);
/// Hash the l1 messages of the block
fn legacy_hash_l1_msg(&self, hasher: &mut impl tiny_keccak::Hasher);
/// Hash the l1 messages of the block
fn hash_msg_queue(&self, initial_queue_hash: &B256) -> B256;
/// Number of L1 msg txs in the block
fn num_l1_msgs(&self) -> usize;
}

#[cfg(feature = "scroll-reth-types")]
impl BlockChunkExt for crate::types::reth::RecoveredBlock<crate::types::reth::Block> {
#[inline]
fn legacy_hash_da_header(&self, hasher: &mut impl tiny_keccak::Hasher) {
use crate::U256;

hasher.update(&self.number.to_be_bytes());
hasher.update(&self.timestamp.to_be_bytes());
hasher.update(
&U256::from_limbs([self.base_fee_per_gas.unwrap_or_default(), 0, 0, 0])
.to_be_bytes::<{ U256::BYTES }>(),
);
hasher.update(&self.gas_limit.to_be_bytes());
// FIXME: l1 tx could be skipped, the actual tx count needs to be calculated
hasher.update(&(self.body().transactions.len() as u16).to_be_bytes());
}

#[inline]
fn legacy_hash_l1_msg(&self, hasher: &mut impl tiny_keccak::Hasher) {
use reth_primitives_traits::SignedTransaction;
for tx in self
.body()
.transactions
.iter()
.filter(|tx| tx.is_l1_message())
{
hasher.update(tx.tx_hash().as_slice())
}
}

#[inline]
fn hash_msg_queue(&self, initial_queue_hash: &B256) -> B256 {
use reth_primitives_traits::SignedTransaction;
use tiny_keccak::Hasher;

let mut rolling_hash = *initial_queue_hash;
for tx in self
.body()
.transactions
.iter()
.filter(|tx| tx.is_l1_message())
{
let mut hasher = tiny_keccak::Keccak::v256();
hasher.update(rolling_hash.as_slice());
hasher.update(tx.tx_hash().as_slice());

hasher.finalize(rolling_hash.as_mut_slice());

// clear last 32 bits, i.e. 4 bytes.
// https://github.com/scroll-tech/da-codec/blob/26dc8d575244560611548fada6a3a2745c60fe83/encoding/da.go#L817-L825
// see also https://github.com/scroll-tech/da-codec/pull/42
rolling_hash.0[28] = 0;
rolling_hash.0[29] = 0;
rolling_hash.0[30] = 0;
rolling_hash.0[31] = 0;
}

rolling_hash
}

#[inline]
fn num_l1_msgs(&self) -> usize {
self.body()
.transactions
.iter()
.filter(|tx| tx.is_l1_message())
.count()
}
}
2 changes: 1 addition & 1 deletion crates/primitives/src/hardforks.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pub use reth_ethereum_forks::*;

#[cfg(feature = "scroll")]
#[cfg(feature = "scroll-hardforks")]
pub use reth_scroll_forks::{
DEV_HARDFORKS as SCROLL_DEV_HARDFORKS, ScrollHardfork, ScrollHardforks,
};
Loading

0 comments on commit e59614d

Please sign in to comment.