Skip to content

Commit

Permalink
feat: introduce StateCommitment type (paradigmxyz#11842)
Browse files Browse the repository at this point in the history
  • Loading branch information
frisitano authored Oct 30, 2024
1 parent 734c78f commit 129f3ba
Show file tree
Hide file tree
Showing 18 changed files with 120 additions and 15 deletions.
5 changes: 5 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions crates/ethereum/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ reth-node-api.workspace = true
reth-chainspec.workspace = true
reth-primitives.workspace = true
reth-revm = { workspace = true, features = ["std"] }
reth-trie-db.workspace = true

# revm with required ethereum features
revm = { workspace = true, features = ["secp256k1", "blst", "c-kzg"] }
Expand Down Expand Up @@ -72,6 +73,7 @@ test-utils = [
"reth-db/test-utils",
"reth-provider/test-utils",
"reth-transaction-pool/test-utils",
"reth-trie-db/test-utils",
"revm/test-utils",
"reth-evm/test-utils"
]
2 changes: 2 additions & 0 deletions crates/ethereum/node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use reth_transaction_pool::{
blobstore::DiskFileBlobStore, EthTransactionPool, TransactionPool,
TransactionValidationTaskExecutor,
};
use reth_trie_db::MerklePatriciaTrie;

use crate::{EthEngineTypes, EthEvmConfig};

Expand Down Expand Up @@ -81,6 +82,7 @@ impl EthereumNode {
impl NodeTypes for EthereumNode {
type Primitives = EthPrimitives;
type ChainSpec = ChainSpec;
type StateCommitment = MerklePatriciaTrie;
}

impl NodeTypesWithEngine for EthereumNode {
Expand Down
1 change: 1 addition & 0 deletions crates/exex/test-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ reth-primitives.workspace = true
reth-provider = { workspace = true, features = ["test-utils"] }
reth-tasks.workspace = true
reth-transaction-pool = { workspace = true, features = ["test-utils"] }
reth-trie-db.workspace = true

## async
futures-util.workspace = true
Expand Down
1 change: 1 addition & 0 deletions crates/exex/test-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub struct TestNode;
impl NodeTypes for TestNode {
type Primitives = ();
type ChainSpec = ChainSpec;
type StateCommitment = reth_trie_db::MerklePatriciaTrie;
}

impl NodeTypesWithEngine for TestNode {
Expand Down
2 changes: 2 additions & 0 deletions crates/node/builder/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ where
type Primitives = <N::Types as NodeTypes>::Primitives;

type ChainSpec = <N::Types as NodeTypes>::ChainSpec;

type StateCommitment = <N::Types as NodeTypes>::StateCommitment;
}

impl<N, C, AO> NodeTypesWithEngine for AnyNode<N, C, AO>
Expand Down
1 change: 1 addition & 0 deletions crates/node/types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ reth-db-api.workspace = true
reth-engine-primitives.workspace = true
reth-primitives.workspace = true
reth-primitives-traits.workspace = true
reth-trie-db.workspace = true
49 changes: 34 additions & 15 deletions crates/node/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use reth_db_api::{
Database,
};
use reth_engine_primitives::EngineTypes;
use reth_trie_db::StateCommitment;

/// Configures all the primitive types of the node.
pub trait NodePrimitives {
Expand All @@ -39,6 +40,8 @@ pub trait NodeTypes: Send + Sync + Unpin + 'static {
type Primitives: NodePrimitives;
/// The type used for configuration of the EVM.
type ChainSpec: EthChainSpec;
/// The type used to perform state commitment operations.
type StateCommitment: StateCommitment;
}

/// The type that configures an Ethereum-like node with an engine for consensus.
Expand Down Expand Up @@ -89,6 +92,7 @@ where
{
type Primitives = Types::Primitives;
type ChainSpec = Types::ChainSpec;
type StateCommitment = Types::StateCommitment;
}

impl<Types, DB> NodeTypesWithEngine for NodeTypesWithDBAdapter<Types, DB>
Expand All @@ -109,70 +113,85 @@ where

/// A [`NodeTypes`] type builder.
#[derive(Default, Debug)]
pub struct AnyNodeTypes<P = (), C = ()>(PhantomData<P>, PhantomData<C>);
pub struct AnyNodeTypes<P = (), C = (), S = ()>(PhantomData<P>, PhantomData<C>, PhantomData<S>);

impl<P, C> AnyNodeTypes<P, C> {
impl<P, C, S> AnyNodeTypes<P, C, S> {
/// Sets the `Primitives` associated type.
pub const fn primitives<T>(self) -> AnyNodeTypes<T, C> {
AnyNodeTypes::<T, C>(PhantomData::<T>, PhantomData::<C>)
pub const fn primitives<T>(self) -> AnyNodeTypes<T, C, S> {
AnyNodeTypes::<T, C, S>(PhantomData::<T>, PhantomData::<C>, PhantomData::<S>)
}

/// Sets the `ChainSpec` associated type.
pub const fn chain_spec<T>(self) -> AnyNodeTypes<P, T> {
AnyNodeTypes::<P, T>(PhantomData::<P>, PhantomData::<T>)
pub const fn chain_spec<T>(self) -> AnyNodeTypes<P, T, S> {
AnyNodeTypes::<P, T, S>(PhantomData::<P>, PhantomData::<T>, PhantomData::<S>)
}

/// Sets the `StateCommitment` associated type.
pub const fn state_commitment<T>(self) -> AnyNodeTypes<P, C, T> {
AnyNodeTypes::<P, C, T>(PhantomData::<P>, PhantomData::<C>, PhantomData::<T>)
}
}

impl<P, C> NodeTypes for AnyNodeTypes<P, C>
impl<P, C, S> NodeTypes for AnyNodeTypes<P, C, S>
where
P: NodePrimitives + Send + Sync + Unpin + 'static,
C: EthChainSpec + 'static,
S: StateCommitment,
{
type Primitives = P;
type ChainSpec = C;
type StateCommitment = S;
}

/// A [`NodeTypesWithEngine`] type builder.
#[derive(Default, Debug)]
pub struct AnyNodeTypesWithEngine<P = (), E = (), C = ()> {
pub struct AnyNodeTypesWithEngine<P = (), E = (), C = (), S = ()> {
/// Embedding the basic node types.
base: AnyNodeTypes<P, C>,
base: AnyNodeTypes<P, C, S>,
/// Phantom data for the engine.
_engine: PhantomData<E>,
}

impl<P, E, C> AnyNodeTypesWithEngine<P, E, C> {
impl<P, E, C, S> AnyNodeTypesWithEngine<P, E, C, S> {
/// Sets the `Primitives` associated type.
pub const fn primitives<T>(self) -> AnyNodeTypesWithEngine<T, E, C> {
pub const fn primitives<T>(self) -> AnyNodeTypesWithEngine<T, E, C, S> {
AnyNodeTypesWithEngine { base: self.base.primitives::<T>(), _engine: PhantomData }
}

/// Sets the `Engine` associated type.
pub const fn engine<T>(self) -> AnyNodeTypesWithEngine<P, T, C> {
pub const fn engine<T>(self) -> AnyNodeTypesWithEngine<P, T, C, S> {
AnyNodeTypesWithEngine { base: self.base, _engine: PhantomData::<T> }
}

/// Sets the `ChainSpec` associated type.
pub const fn chain_spec<T>(self) -> AnyNodeTypesWithEngine<P, E, T> {
pub const fn chain_spec<T>(self) -> AnyNodeTypesWithEngine<P, E, T, S> {
AnyNodeTypesWithEngine { base: self.base.chain_spec::<T>(), _engine: PhantomData }
}

/// Sets the `StateCommitment` associated type.
pub const fn state_commitment<T>(self) -> AnyNodeTypesWithEngine<P, E, C, T> {
AnyNodeTypesWithEngine { base: self.base.state_commitment::<T>(), _engine: PhantomData }
}
}

impl<P, E, C> NodeTypes for AnyNodeTypesWithEngine<P, E, C>
impl<P, E, C, S> NodeTypes for AnyNodeTypesWithEngine<P, E, C, S>
where
P: NodePrimitives + Send + Sync + Unpin + 'static,
E: EngineTypes + Send + Sync + Unpin,
C: EthChainSpec + 'static,
S: StateCommitment,
{
type Primitives = P;
type ChainSpec = C;
type StateCommitment = S;
}

impl<P, E, C> NodeTypesWithEngine for AnyNodeTypesWithEngine<P, E, C>
impl<P, E, C, S> NodeTypesWithEngine for AnyNodeTypesWithEngine<P, E, C, S>
where
P: NodePrimitives + Send + Sync + Unpin + 'static,
E: EngineTypes + Send + Sync + Unpin,
C: EthChainSpec + 'static,
S: StateCommitment,
{
type Engine = E;
}
2 changes: 2 additions & 0 deletions crates/optimism/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ reth-network.workspace = true
reth-evm.workspace = true
reth-revm = { workspace = true, features = ["std"] }
reth-beacon-consensus.workspace = true
reth-trie-db.workspace = true

# op-reth
reth-optimism-payload-builder.workspace = true
Expand Down Expand Up @@ -99,5 +100,6 @@ test-utils = [
"reth-db/test-utils",
"reth-provider/test-utils",
"reth-transaction-pool/test-utils",
"reth-trie-db/test-utils",
"revm/test-utils"
]
2 changes: 2 additions & 0 deletions crates/optimism/node/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use reth_transaction_pool::{
blobstore::DiskFileBlobStore, CoinbaseTipOrdering, TransactionPool,
TransactionValidationTaskExecutor,
};
use reth_trie_db::MerklePatriciaTrie;

use crate::{
args::RollupArgs,
Expand Down Expand Up @@ -122,6 +123,7 @@ where
impl NodeTypes for OptimismNode {
type Primitives = OpPrimitives;
type ChainSpec = OpChainSpec;
type StateCommitment = MerklePatriciaTrie;
}

impl NodeTypesWithEngine for OptimismNode {
Expand Down
2 changes: 2 additions & 0 deletions crates/storage/provider/src/test_utils/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ use reth_trie::{
updates::TrieUpdates, AccountProof, HashedPostState, HashedStorage, MultiProof, StorageProof,
TrieInput,
};
use reth_trie_db::MerklePatriciaTrie;
use revm::primitives::{BlockEnv, CfgEnvWithHandlerCfg};
use std::{
collections::BTreeMap,
Expand Down Expand Up @@ -157,6 +158,7 @@ pub struct MockNode;
impl NodeTypes for MockNode {
type Primitives = ();
type ChainSpec = ChainSpec;
type StateCommitment = MerklePatriciaTrie;
}

impl DatabaseProviderFactory for MockEthProvider {
Expand Down
1 change: 1 addition & 0 deletions crates/storage/provider/src/test_utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ pub type MockNodeTypes = reth_node_types::AnyNodeTypesWithEngine<
(),
reth_ethereum_engine_primitives::EthEngineTypes,
reth_chainspec::ChainSpec,
reth_trie_db::MerklePatriciaTrie,
>;

/// Mock [`reth_node_types::NodeTypesWithDB`] for testing.
Expand Down
18 changes: 18 additions & 0 deletions crates/trie/common/src/key.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use alloy_primitives::B256;
use revm_primitives::keccak256;

/// Trait for hashing keys in state.
pub trait KeyHasher: Default + Clone + Send + Sync + 'static {
/// Hashes the given bytes into a 256-bit hash.
fn hash_key<T: AsRef<[u8]>>(bytes: T) -> B256;
}

/// A key hasher that uses the Keccak-256 hash function.
#[derive(Clone, Debug, Default)]
pub struct KeccakKeyHasher;

impl KeyHasher for KeccakKeyHasher {
fn hash_key<T: AsRef<[u8]>>(bytes: T) -> B256 {
keccak256(bytes)
}
}
3 changes: 3 additions & 0 deletions crates/trie/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pub mod hash_builder;
mod account;
pub use account::TrieAccount;

mod key;
pub use key::{KeccakKeyHasher, KeyHasher};

mod nibbles;
pub use nibbles::{Nibbles, StoredNibbles, StoredNibblesSubKey};

Expand Down
39 changes: 39 additions & 0 deletions crates/trie/db/src/commitment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use crate::{
DatabaseHashedCursorFactory, DatabaseProof, DatabaseStateRoot, DatabaseStorageRoot,
DatabaseTrieCursorFactory, DatabaseTrieWitness,
};
use reth_db::transaction::DbTx;
use reth_trie::{
proof::Proof, witness::TrieWitness, KeccakKeyHasher, KeyHasher, StateRoot, StorageRoot,
};

/// The `StateCommitment` trait provides associated types for state commitment operations.
pub trait StateCommitment: std::fmt::Debug + Send + Sync + Unpin + 'static {
/// The state root type.
type StateRoot<'a, TX: DbTx + 'a>: DatabaseStateRoot<'a, TX>;
/// The storage root type.
type StorageRoot<'a, TX: DbTx + 'a>: DatabaseStorageRoot<'a, TX>;
/// The state proof type.
type StateProof<'a, TX: DbTx + 'a>: DatabaseProof<'a, TX>;
/// The state witness type.
type StateWitness<'a, TX: DbTx + 'a>: DatabaseTrieWitness<'a, TX>;
/// The key hasher type.
type KeyHasher: KeyHasher;
}

/// The state commitment type for Ethereum's Merkle Patricia Trie.
#[derive(Debug)]
#[non_exhaustive]
pub struct MerklePatriciaTrie;

impl StateCommitment for MerklePatriciaTrie {
type StateRoot<'a, TX: DbTx + 'a> =
StateRoot<DatabaseTrieCursorFactory<'a, TX>, DatabaseHashedCursorFactory<'a, TX>>;
type StorageRoot<'a, TX: DbTx + 'a> =
StorageRoot<DatabaseTrieCursorFactory<'a, TX>, DatabaseHashedCursorFactory<'a, TX>>;
type StateProof<'a, TX: DbTx + 'a> =
Proof<DatabaseTrieCursorFactory<'a, TX>, DatabaseHashedCursorFactory<'a, TX>>;
type StateWitness<'a, TX: DbTx + 'a> =
TrieWitness<DatabaseTrieCursorFactory<'a, TX>, DatabaseHashedCursorFactory<'a, TX>>;
type KeyHasher = KeccakKeyHasher;
}
2 changes: 2 additions & 0 deletions crates/trie/db/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! An integration of [`reth-trie`] with [`reth-db`].

mod commitment;
mod hashed_cursor;
mod prefix_set;
mod proof;
Expand All @@ -8,6 +9,7 @@ mod storage;
mod trie_cursor;
mod witness;

pub use commitment::{MerklePatriciaTrie, StateCommitment};
pub use hashed_cursor::{
DatabaseHashedAccountCursor, DatabaseHashedCursorFactory, DatabaseHashedStorageCursor,
};
Expand Down
1 change: 1 addition & 0 deletions examples/custom-engine-types/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ reth-basic-payload-builder.workspace = true
reth-ethereum-payload-builder.workspace = true
reth-node-ethereum = { workspace = true, features = ["test-utils"] }
reth-tracing.workspace = true
reth-trie-db.workspace = true
alloy-genesis.workspace = true
alloy-rpc-types = { workspace = true, features = ["engine"] }
alloy-primitives.workspace = true
Expand Down
2 changes: 2 additions & 0 deletions examples/custom-engine-types/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use reth_payload_builder::{
};
use reth_primitives::Withdrawals;
use reth_tracing::{RethTracer, Tracer};
use reth_trie_db::MerklePatriciaTrie;

/// A custom payload attributes type.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
Expand Down Expand Up @@ -228,6 +229,7 @@ struct MyCustomNode;
impl NodeTypes for MyCustomNode {
type Primitives = ();
type ChainSpec = ChainSpec;
type StateCommitment = MerklePatriciaTrie;
}

/// Configure the node types with the custom engine types
Expand Down

0 comments on commit 129f3ba

Please sign in to comment.