Skip to content
This repository was archived by the owner on Jan 16, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ homepage.workspace = true
[lints]
workspace = true

[profile.bench]
default = ["kona-mpt/test-utils"]

[dependencies]
# General
thiserror.workspace = true
Expand Down
2 changes: 1 addition & 1 deletion crates/executor/benches/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use alloy_rpc_types_engine::PayloadAttributes;
use anyhow::{anyhow, Result};
use criterion::{criterion_group, criterion_main, Bencher, Criterion};
use kona_executor::StatelessL2BlockExecutor;
use kona_mpt::{NoopTrieHinter, TrieProvider};
use kona_mpt::{test_utils::NoopTrieHinter, TrieProvider};
use op_alloy_genesis::{RollupConfig, OP_MAINNET_BASE_FEE_PARAMS};
use op_alloy_rpc_types_engine::OptimismPayloadAttributes;
use pprof::criterion::{Output, PProfProfiler};
Expand Down
2 changes: 1 addition & 1 deletion crates/executor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,7 @@ mod test {
use alloy_rlp::Decodable;
use alloy_rpc_types_engine::PayloadAttributes;
use anyhow::{anyhow, Result};
use kona_mpt::NoopTrieHinter;
use kona_mpt::test_utils::NoopTrieHinter;
use op_alloy_genesis::OP_MAINNET_BASE_FEE_PARAMS;
use serde::Deserialize;
use std::collections::HashMap;
Expand Down
19 changes: 18 additions & 1 deletion crates/mpt/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,20 @@ homepage.workspace = true
[lints]
workspace = true

[profile.bench]
default = ["test-utils"]

[dependencies]
# General
tracing.workspace = true
thiserror.workspace = true

# `test-utils`
anyhow = { workspace = true, optional = true }
reqwest = { workspace = true, optional = true }
alloy-provider = { workspace = true, features = ["reqwest"], optional = true }
alloy-rpc-types = { workspace = true, features = ["eth"], optional = true }

# Revm + Alloy
revm.workspace = true
alloy-primitives = { workspace = true, features = ["rlp"] }
Expand All @@ -25,7 +34,6 @@ alloy-trie.workspace = true

[dev-dependencies]
tokio.workspace = true
anyhow.workspace = true
reqwest.workspace = true
futures.workspace = true
tracing-subscriber.workspace = true
Expand All @@ -40,6 +48,15 @@ proptest.workspace = true
criterion.workspace = true
pprof.workspace = true

[features]
default = []
test-utils = [
"dep:anyhow",
"dep:reqwest",
"dep:alloy-provider",
"dep:alloy-rpc-types",
]

[[bench]]
name = "trie_node"
harness = false
5 changes: 4 additions & 1 deletion crates/mpt/benches/trie_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@

use alloy_trie::Nibbles;
use criterion::{criterion_group, criterion_main, Criterion};
use kona_mpt::{NoopTrieHinter, NoopTrieProvider, TrieNode};
use kona_mpt::{
test_utils::{NoopTrieHinter, NoopTrieProvider},
TrieNode,
};
use pprof::criterion::{Output, PProfProfiler};
use rand::{rngs::StdRng, seq::SliceRandom, Rng, SeedableRng};

Expand Down
59 changes: 31 additions & 28 deletions crates/mpt/src/db/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,34 +46,37 @@ pub use account::TrieAccount;
/// [BLOCK_HASH_HISTORY] blocks back relative to the current parent block hash.
///
/// **Example Construction**:
/// ```rust
/// use alloy_consensus::{Header, Sealable};
/// use alloy_primitives::{Bytes, B256};
/// use anyhow::Result;
/// use kona_mpt::{NoopTrieHinter, NoopTrieProvider, TrieDB};
/// use revm::{db::states::bundle_state::BundleRetention, EvmBuilder, StateBuilder};
///
/// let mock_starting_root = B256::default();
/// let mock_parent_block_header = Header::default();
///
/// let trie_db = TrieDB::new(
/// mock_starting_root,
/// mock_parent_block_header.seal_slow(),
/// NoopTrieProvider,
/// NoopTrieHinter,
/// );
/// let mut state = StateBuilder::new_with_database(trie_db).with_bundle_update().build();
/// let evm = EvmBuilder::default().with_db(&mut state).build();
///
/// // Execute your block's transactions...
///
/// // Drop the EVM prior to merging the state transitions.
/// drop(evm);
///
/// state.merge_transitions(BundleRetention::Reverts);
/// let bundle = state.take_bundle();
/// let state_root = state.database.state_root(&bundle).expect("Failed to compute state root");
/// ```
#[cfg_attr(
feature = "test-utils",
doc = "
use alloy_consensus::{Header, Sealable};
use alloy_primitives::{Bytes, B256};
use anyhow::Result;
use kona_mpt::{NoopTrieHinter, NoopTrieProvider, TrieDB};
use revm::{db::states::bundle_state::BundleRetention, EvmBuilder, StateBuilder};

let mock_starting_root = B256::default();
let mock_parent_block_header = Header::default();

let trie_db = TrieDB::new(
mock_starting_root,
mock_parent_block_header.seal_slow(),
NoopTrieProvider,
NoopTrieHinter,
);
let mut state = StateBuilder::new_with_database(trie_db).with_bundle_update().build();
let evm = EvmBuilder::default().with_db(&mut state).build();

// Execute your block's transactions...

// Drop the EVM prior to merging the state transitions.
drop(evm);

state.merge_transitions(BundleRetention::Reverts);
let bundle = state.take_bundle();
let state_root = state.database.state_root(&bundle).expect(\"Failed to compute state root\");
"
)]
///
/// [State]: revm::State
#[derive(Debug, Clone)]
Expand Down
47 changes: 1 addition & 46 deletions crates/mpt/src/fetcher.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//! Contains the [TrieProvider] trait for fetching trie node preimages, contract bytecode, and
//! headers.

use alloc::string::{String, ToString};
use alloc::string::ToString;
use alloy_consensus::Header;
use alloy_primitives::{Address, Bytes, B256, U256};
use core::fmt::Display;
Expand Down Expand Up @@ -93,48 +93,3 @@ pub trait TrieHinter {
block_number: u64,
) -> Result<(), Self::Error>;
}

/// The default, no-op implementation of the [TrieProvider] trait, used for testing.
#[derive(Debug, Clone, Copy)]
pub struct NoopTrieProvider;

impl TrieProvider for NoopTrieProvider {
type Error = String;

fn trie_node_preimage(&self, _key: B256) -> Result<Bytes, Self::Error> {
Ok(Bytes::new())
}

fn bytecode_by_hash(&self, _code_hash: B256) -> Result<Bytes, Self::Error> {
Ok(Bytes::new())
}

fn header_by_hash(&self, _hash: B256) -> Result<Header, Self::Error> {
Ok(Header::default())
}
}

/// The default, no-op implementation of the [TrieHinter] trait, used for testing.
#[derive(Debug, Clone, Copy)]
pub struct NoopTrieHinter;

impl TrieHinter for NoopTrieHinter {
type Error = String;

fn hint_trie_node(&self, _hash: B256) -> Result<(), Self::Error> {
Ok(())
}

fn hint_account_proof(&self, _address: Address, _block_number: u64) -> Result<(), Self::Error> {
Ok(())
}

fn hint_storage_proof(
&self,
_address: Address,
_slot: U256,
_block_number: u64,
) -> Result<(), Self::Error> {
Ok(())
}
}
6 changes: 3 additions & 3 deletions crates/mpt/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub use errors::{
};

mod fetcher;
pub use fetcher::{NoopTrieHinter, NoopTrieProvider, TrieHinter, TrieProvider};
pub use fetcher::{TrieHinter, TrieProvider};

mod node;
pub use node::TrieNode;
Expand All @@ -30,5 +30,5 @@ pub use list_walker::OrderedListWalker;
mod util;
pub use util::ordered_trie_with_encoder;

#[cfg(test)]
mod test_util;
#[cfg(any(test, feature = "test-utils"))]
pub mod test_utils;
5 changes: 2 additions & 3 deletions crates/mpt/src/list_walker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,10 @@ mod test {
use super::*;
use crate::{
ordered_trie_with_encoder,
test_util::{
test_utils::{
get_live_derivable_receipts_list, get_live_derivable_transactions_list,
TrieNodeProvider,
NoopTrieProvider, TrieNodeProvider,
},
NoopTrieProvider,
};
use alloc::{collections::BTreeMap, string::String, vec::Vec};
use alloy_consensus::{ReceiptEnvelope, TxEnvelope};
Expand Down
5 changes: 3 additions & 2 deletions crates/mpt/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,8 +684,9 @@ impl Decodable for TrieNode {
mod test {
use super::*;
use crate::{
fetcher::NoopTrieProvider, ordered_trie_with_encoder, test_util::TrieNodeProvider,
NoopTrieHinter, TrieNode,
ordered_trie_with_encoder,
test_utils::{NoopTrieHinter, NoopTrieProvider, TrieNodeProvider},
TrieNode,
};
use alloc::{collections::BTreeMap, vec, vec::Vec};
use alloy_primitives::{b256, bytes, hex, keccak256};
Expand Down
63 changes: 55 additions & 8 deletions crates/mpt/src/test_util.rs → crates/mpt/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//! Testing utilities for `kona-mpt`

use crate::{ordered_trie_with_encoder, TrieProvider};
use alloc::{collections::BTreeMap, vec::Vec};
use alloy_consensus::{Receipt, ReceiptEnvelope, ReceiptWithBloom, TxEnvelope, TxType};
use alloy_primitives::{keccak256, Bytes, Log, B256};
use crate::{ordered_trie_with_encoder, TrieHinter, TrieProvider};
use alloc::{collections::BTreeMap, string::String, vec::Vec};
use alloy_consensus::{Header, Receipt, ReceiptEnvelope, ReceiptWithBloom, TxEnvelope, TxType};
use alloy_primitives::{keccak256, Address, Bytes, Log, B256, U256};
use alloy_provider::{network::eip2718::Encodable2718, Provider, ProviderBuilder};
use alloy_rpc_types::{BlockTransactions, BlockTransactionsKind};
use anyhow::{anyhow, Result};
Expand All @@ -12,7 +12,7 @@ use reqwest::Url;
const RPC_URL: &str = "https://docs-demo.quiknode.pro/";

/// Grabs a live merkleized receipts list within a block header.
pub(crate) async fn get_live_derivable_receipts_list(
pub async fn get_live_derivable_receipts_list(
) -> Result<(B256, BTreeMap<B256, Bytes>, Vec<ReceiptEnvelope>)> {
// Initialize the provider.
let provider = ProviderBuilder::new().on_http(Url::parse(RPC_URL).expect("invalid rpc url"));
Expand Down Expand Up @@ -78,7 +78,7 @@ pub(crate) async fn get_live_derivable_receipts_list(
}

/// Grabs a live merkleized transactions list within a block header.
pub(crate) async fn get_live_derivable_transactions_list(
pub async fn get_live_derivable_transactions_list(
) -> Result<(B256, BTreeMap<B256, Bytes>, Vec<TxEnvelope>)> {
// Initialize the provider.
let provider = ProviderBuilder::new().on_http(Url::parse(RPC_URL).expect("invalid rpc url"));
Expand Down Expand Up @@ -118,15 +118,62 @@ pub(crate) async fn get_live_derivable_transactions_list(
Ok((root, preimages, consensus_txs))
}

/// The default, no-op implementation of the [TrieProvider] trait, used for testing.
#[derive(Debug, Clone, Copy)]
pub struct NoopTrieProvider;

impl TrieProvider for NoopTrieProvider {
type Error = String;

fn trie_node_preimage(&self, _key: B256) -> Result<Bytes, Self::Error> {
Ok(Bytes::new())
}

fn bytecode_by_hash(&self, _code_hash: B256) -> Result<Bytes, Self::Error> {
Ok(Bytes::new())
}

fn header_by_hash(&self, _hash: B256) -> Result<Header, Self::Error> {
Ok(Header::default())
}
}

/// The default, no-op implementation of the [TrieHinter] trait, used for testing.
#[derive(Debug, Clone, Copy)]
pub struct NoopTrieHinter;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these belong in test utils unfortunately. Succinct and other downstream implementers use this - non FPVM targets don't have hints.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifically the hinter - if we really want to we can keep the provider behind the test utils, but may as well also distribute it if we have the noop hinter distributed.


impl TrieHinter for NoopTrieHinter {
type Error = String;

fn hint_trie_node(&self, _hash: B256) -> Result<(), Self::Error> {
Ok(())
}

fn hint_account_proof(&self, _address: Address, _block_number: u64) -> Result<(), Self::Error> {
Ok(())
}

fn hint_storage_proof(
&self,
_address: Address,
_slot: U256,
_block_number: u64,
) -> Result<(), Self::Error> {
Ok(())
}
}

/// A mock [TrieProvider] for testing that serves in-memory preimages.
pub(crate) struct TrieNodeProvider {
#[derive(Debug, Clone)]
pub struct TrieNodeProvider {
preimages: BTreeMap<B256, Bytes>,
bytecode: BTreeMap<B256, Bytes>,
headers: BTreeMap<B256, alloy_consensus::Header>,
}

impl TrieNodeProvider {
pub(crate) const fn new(
/// Constructs a new [TrieNodeProvider].
pub const fn new(
preimages: BTreeMap<B256, Bytes>,
bytecode: BTreeMap<B256, Bytes>,
headers: BTreeMap<B256, alloy_consensus::Header>,
Expand Down