diff --git a/Cargo.lock b/Cargo.lock index 7fb230d98..5fd6a45bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2030,9 +2030,14 @@ dependencies = [ name = "evm_arithmetization" version = "0.4.0" dependencies = [ + "alloy", + "alloy-compat", "anyhow", + "bitvec", "bytes", + "copyvec", "criterion", + "either", "env_logger 0.11.5", "ethereum-types", "hashbrown", @@ -2068,6 +2073,7 @@ dependencies = [ "tokio", "tower-lsp", "tracing", + "u4", "url", "zk_evm_common", "zk_evm_proc_macro", diff --git a/Cargo.toml b/Cargo.toml index c56be95a0..f8c6be0f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,7 +45,8 @@ bytes = "1.6.0" ciborium = "0.2.2" ciborium-io = "0.2.2" clap = { version = "4.5.7", features = ["derive", "env"] } -compat = { path = "compat" } +alloy-compat = "0.1.0" +copyvec = "0.2.0" criterion = "0.5.1" dotenvy = "0.15.7" either = "1.12.0" @@ -104,6 +105,7 @@ url = "2.5.2" winnow = "0.6.13" # local dependencies +compat = { path = "compat" } evm_arithmetization = { path = "evm_arithmetization", version = "0.4.0", default-features = false } mpt_trie = { path = "mpt_trie", version = "0.4.1" } smt_trie = { path = "smt_trie", version = "0.1.1" } diff --git a/evm_arithmetization/Cargo.toml b/evm_arithmetization/Cargo.toml index f5dfec2f2..22a40013f 100644 --- a/evm_arithmetization/Cargo.toml +++ b/evm_arithmetization/Cargo.toml @@ -15,8 +15,13 @@ homepage.workspace = true keywords.workspace = true [dependencies] +alloy.workspace = true +alloy-compat.workspace = true anyhow.workspace = true +bitvec.workspace = true bytes.workspace = true +copyvec.workspace = true +either.workspace = true env_logger.workspace = true ethereum-types.workspace = true hashbrown.workspace = true @@ -43,7 +48,7 @@ serde = { workspace = true, features = ["derive"] } serde-big-array.workspace = true serde_json.workspace = true sha2.workspace = true -smt_trie = { workspace = true, optional = true } +smt_trie = { workspace = true } starky = { workspace = true, features = ["parallel"] } static_assertions.workspace = true thiserror.workspace = true @@ -51,6 +56,7 @@ tiny-keccak.workspace = true tokio.workspace = true tower-lsp = "0.20.0" tracing.workspace = true +u4.workspace = true url.workspace = true zk_evm_common.workspace = true zk_evm_proc_macro.workspace = true @@ -64,7 +70,7 @@ ripemd.workspace = true default = ["eth_mainnet"] asmtools = ["hex"] polygon_pos = [] -cdk_erigon = ["smt_trie"] +cdk_erigon = [] eth_mainnet = [] [[bin]] diff --git a/evm_arithmetization/src/lib.rs b/evm_arithmetization/src/lib.rs index 41b7f093a..9bc6021e2 100644 --- a/evm_arithmetization/src/lib.rs +++ b/evm_arithmetization/src/lib.rs @@ -284,7 +284,9 @@ pub mod witness; pub mod curve_pairings; pub mod extension_tower; pub mod testing_utils; +pub mod tries; pub mod util; +pub mod world; // Public definitions and re-exports mod public_types; diff --git a/trace_decoder/src/tries.rs b/evm_arithmetization/src/tries.rs similarity index 99% rename from trace_decoder/src/tries.rs rename to evm_arithmetization/src/tries.rs index 7da8d2cfa..61531a1ef 100644 --- a/trace_decoder/src/tries.rs +++ b/evm_arithmetization/src/tries.rs @@ -7,10 +7,11 @@ use anyhow::ensure; use bitvec::{array::BitArray, slice::BitSlice}; use copyvec::CopyVec; use ethereum_types::{Address, H256, U256}; -use evm_arithmetization::generation::mpt::AccountRlp; use mpt_trie::partial_trie::{HashedPartialTrie, Node, OnOrphanedHashNode, PartialTrie as _}; use u4::{AsNibbles, U4}; +use crate::generation::mpt::AccountRlp; + /// Bounded sequence of [`U4`], /// used as a key for [MPT](HashedPartialTrie) types in this module. /// diff --git a/trace_decoder/src/world.rs b/evm_arithmetization/src/world.rs similarity index 95% rename from trace_decoder/src/world.rs rename to evm_arithmetization/src/world.rs index 463914c53..d01e7ef26 100644 --- a/trace_decoder/src/world.rs +++ b/evm_arithmetization/src/world.rs @@ -5,18 +5,36 @@ use anyhow::{ensure, Context as _}; use either::Either; use ethereum_types::{Address, BigEndianHash as _, U256}; use keccak_hash::H256; +use smt_trie::code::hash_bytecode_h256; -use crate::{ - tries::{MptKey, SmtKey, StateMpt, StorageTrie}, - Hasher, KeccakHash, PoseidonHash, -}; +/// Utility trait to leverage a specific hash function across Type1 and Type2 +/// zkEVM variants. +pub trait Hasher { + fn hash(bytes: &[u8]) -> H256; +} + +pub struct PoseidonHash; +pub struct KeccakHash; + +impl Hasher for PoseidonHash { + fn hash(bytes: &[u8]) -> H256 { + hash_bytecode_h256(bytes) + } +} + +impl Hasher for KeccakHash { + fn hash(bytes: &[u8]) -> H256 { + keccak_hash::keccak(bytes) + } +} + +use crate::tries::{MptKey, SmtKey, StateMpt, StorageTrie}; -/// The [core](crate::core) of this crate is agnostic over state and storage -/// representations. +/// The `core` module of the `trace_decoder` crate is agnostic over state and +/// storage representations. /// /// This is the common interface to those data structures. -/// See also [crate::_DEVELOPER_DOCS]. -pub(crate) trait World { +pub trait World { /// (State) subtries may be _hashed out. /// This type is a key which may identify a subtrie. type SubtriePath; @@ -50,8 +68,8 @@ pub(crate) trait World { /// Creates a new account at `address` if it does not exist. fn set_code(&mut self, address: Address, code: Either<&[u8], H256>) -> anyhow::Result<()>; - /// The [core](crate::core) of this crate tracks required subtries for - /// proving. + /// The `core` module of the `trace_decoder` crate tracks required subtries + /// for proving. /// /// In case of a state delete, it may be that certain parts of the subtrie /// must be retained. If so, it will be returned as [`Some`]. diff --git a/trace_decoder/Cargo.toml b/trace_decoder/Cargo.toml index 4b8d8e7bc..da9394823 100644 --- a/trace_decoder/Cargo.toml +++ b/trace_decoder/Cargo.toml @@ -11,14 +11,14 @@ keywords.workspace = true [dependencies] alloy.workspace = true -alloy-compat = "0.1.0" +alloy-compat.workspace = true anyhow.workspace = true bitflags.workspace = true bitvec.workspace = true bytes.workspace = true ciborium.workspace = true ciborium-io.workspace = true -copyvec = "0.2.0" +copyvec.workspace = true either.workspace = true enum-as-inner.workspace = true ethereum-types.workspace = true @@ -43,7 +43,7 @@ zk_evm_common.workspace = true [dev-dependencies] alloy.workspace = true -alloy-compat = "0.1.0" +alloy-compat.workspace = true assert2 = "0.3.15" camino = "1.1.9" clap.workspace = true diff --git a/trace_decoder/src/core.rs b/trace_decoder/src/core.rs index b34117911..3f63f7004 100644 --- a/trace_decoder/src/core.rs +++ b/trace_decoder/src/core.rs @@ -11,6 +11,8 @@ use ethereum_types::{Address, BigEndianHash as _, U256}; use evm_arithmetization::{ generation::TrieInputs, proof::{BlockMetadata, TrieRoots}, + tries::{MptKey, ReceiptTrie, StateMpt, StorageTrie, TransactionTrie}, + world::{Hasher, KeccakHash, PoseidonHash, Type1World, Type2World, World}, GenerationInputs, }; use itertools::Itertools as _; @@ -19,14 +21,8 @@ use mpt_trie::partial_trie::PartialTrie as _; use nunny::NonEmpty; use zk_evm_common::gwei_to_wei; +use crate::observer::{DummyObserver, Observer}; use crate::{ - observer::{DummyObserver, Observer}, - world::Type2World, - Hasher, KeccakHash, PoseidonHash, -}; -use crate::{ - tries::{MptKey, ReceiptTrie, StateMpt, StorageTrie, TransactionTrie}, - world::{Type1World, World}, BlockLevelData, BlockTrace, BlockTraceTriePreImages, CombinedPreImages, ContractCodeUsage, OtherBlockData, SeparateStorageTriesPreImage, SeparateTriePreImage, SeparateTriePreImages, TxnInfo, TxnMeta, TxnTrace, @@ -180,7 +176,8 @@ pub fn entrypoint( /// [`HashedPartialTrie`](mpt_trie::partial_trie::HashedPartialTrie), /// or a [`wire`](crate::wire)-encoded representation of one. /// -/// Turn either of those into our [internal representations](crate::tries). +/// Turn either of those into our [internal +/// representations](evm_arithmetization::tries). #[allow(clippy::type_complexity)] fn start( pre_images: BlockTraceTriePreImages, diff --git a/trace_decoder/src/lib.rs b/trace_decoder/src/lib.rs index b89332e5f..4bd68bc11 100644 --- a/trace_decoder/src/lib.rs +++ b/trace_decoder/src/lib.rs @@ -56,20 +56,17 @@ /// we can continue to do the main work of "executing" the transactions. /// /// The core of this library is agnostic over the (combined) -/// state and storage representation - see [`world::World`] for more. +/// state and storage representation - see [`evm_arithmetization::world::World`] +/// for more. const _DEVELOPER_DOCS: () = (); mod interface; pub use interface::*; -use keccak_hash::H256; -use smt_trie::code::hash_bytecode_h256; -mod tries; mod type1; mod type2; mod wire; -mod world; pub use core::{entrypoint, WireDisposition}; @@ -103,27 +100,6 @@ mod hex { } } -/// Utility trait to leverage a specific hash function across Type1 and Type2 -/// zkEVM variants. -pub(crate) trait Hasher { - fn hash(bytes: &[u8]) -> H256; -} - -pub(crate) struct PoseidonHash; -pub(crate) struct KeccakHash; - -impl Hasher for PoseidonHash { - fn hash(bytes: &[u8]) -> H256 { - hash_bytecode_h256(bytes) - } -} - -impl Hasher for KeccakHash { - fn hash(bytes: &[u8]) -> H256 { - keccak_hash::keccak(bytes) - } -} - #[cfg(test)] #[derive(serde::Deserialize)] struct Case { diff --git a/trace_decoder/src/observer.rs b/trace_decoder/src/observer.rs index 428cac086..3d19c700d 100644 --- a/trace_decoder/src/observer.rs +++ b/trace_decoder/src/observer.rs @@ -1,9 +1,9 @@ use std::marker::PhantomData; use ethereum_types::U256; +use evm_arithmetization::tries::{ReceiptTrie, TransactionTrie}; use crate::core::IntraBlockTries; -use crate::tries::{ReceiptTrie, TransactionTrie}; /// Observer API for the trace decoder. /// Observer is used to collect various debugging and metadata info diff --git a/trace_decoder/src/type1.rs b/trace_decoder/src/type1.rs index 072bdbe3c..2d9e293d5 100644 --- a/trace_decoder/src/type1.rs +++ b/trace_decoder/src/type1.rs @@ -7,15 +7,14 @@ use std::collections::{BTreeMap, BTreeSet}; use anyhow::{bail, ensure, Context as _}; use either::Either; use evm_arithmetization::generation::mpt::AccountRlp; +use evm_arithmetization::tries::{MptKey, StateMpt, StorageTrie}; +use evm_arithmetization::world::{Hasher as _, Type1World, World}; use keccak_hash::H256; use mpt_trie::partial_trie::OnOrphanedHashNode; use nunny::NonEmpty; use u4::U4; -use crate::tries::{MptKey, StateMpt, StorageTrie}; use crate::wire::{Instruction, SmtLeaf}; -use crate::world::{Type1World, World}; -use crate::Hasher as _; #[derive(Debug, Clone, Default)] pub struct Frontend { diff --git a/trace_decoder/src/type2.rs b/trace_decoder/src/type2.rs index 4a380bc70..87af8a464 100644 --- a/trace_decoder/src/type2.rs +++ b/trace_decoder/src/type2.rs @@ -5,16 +5,16 @@ use std::collections::{BTreeMap, HashSet}; use anyhow::{bail, ensure, Context as _}; use ethereum_types::{Address, U256}; +use evm_arithmetization::{ + tries::SmtKey, + world::{Type2Entry, Type2World}, +}; use itertools::EitherOrBoth; use keccak_hash::H256; use nunny::NonEmpty; use stackstack::Stack; -use crate::{ - tries::SmtKey, - wire::{Instruction, SmtLeaf, SmtLeafType}, - world::{Type2Entry, Type2World}, -}; +use crate::wire::{Instruction, SmtLeaf, SmtLeafType}; pub struct Frontend { pub world: Type2World, @@ -175,7 +175,7 @@ fn visit( #[test] fn test_tries() { - use crate::world::World as _; + use evm_arithmetization::world::World as _; for (ix, case) in serde_json::from_str::>(include_str!("cases/hermez_cdk_erigon.json")) .unwrap()