feat: introduce StateCommitment type (#11842)

This commit is contained in:
frisitano
2024-10-30 16:48:43 +08:00
committed by GitHub
parent 734c78fdfb
commit 129f3ba911
18 changed files with 120 additions and 15 deletions

5
Cargo.lock generated
View File

@ -2856,6 +2856,7 @@ dependencies = [
"reth-payload-builder",
"reth-primitives",
"reth-tracing",
"reth-trie-db",
"serde",
"thiserror",
"tokio",
@ -7564,6 +7565,7 @@ dependencies = [
"reth-provider",
"reth-tasks",
"reth-transaction-pool",
"reth-trie-db",
"tempfile",
"thiserror",
"tokio",
@ -8024,6 +8026,7 @@ dependencies = [
"reth-tasks",
"reth-tracing",
"reth-transaction-pool",
"reth-trie-db",
"revm",
"serde_json",
"tokio",
@ -8086,6 +8089,7 @@ dependencies = [
"reth-engine-primitives",
"reth-primitives",
"reth-primitives-traits",
"reth-trie-db",
]
[[package]]
@ -8246,6 +8250,7 @@ dependencies = [
"reth-revm",
"reth-tracing",
"reth-transaction-pool",
"reth-trie-db",
"revm",
"serde",
"serde_json",

View File

@ -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"] }
@ -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"
]

View File

@ -34,6 +34,7 @@ use reth_transaction_pool::{
blobstore::DiskFileBlobStore, EthTransactionPool, TransactionPool,
TransactionValidationTaskExecutor,
};
use reth_trie_db::MerklePatriciaTrie;
use crate::{EthEngineTypes, EthEvmConfig};
@ -81,6 +82,7 @@ impl EthereumNode {
impl NodeTypes for EthereumNode {
type Primitives = EthPrimitives;
type ChainSpec = ChainSpec;
type StateCommitment = MerklePatriciaTrie;
}
impl NodeTypesWithEngine for EthereumNode {

View File

@ -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

View File

@ -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 {

View File

@ -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>

View File

@ -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

View File

@ -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 {
@ -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.
@ -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>
@ -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;
}

View File

@ -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
@ -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"
]

View File

@ -30,6 +30,7 @@ use reth_transaction_pool::{
blobstore::DiskFileBlobStore, CoinbaseTipOrdering, TransactionPool,
TransactionValidationTaskExecutor,
};
use reth_trie_db::MerklePatriciaTrie;
use crate::{
args::RollupArgs,
@ -122,6 +123,7 @@ where
impl NodeTypes for OptimismNode {
type Primitives = OpPrimitives;
type ChainSpec = OpChainSpec;
type StateCommitment = MerklePatriciaTrie;
}
impl NodeTypesWithEngine for OptimismNode {

View File

@ -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,
@ -157,6 +158,7 @@ pub struct MockNode;
impl NodeTypes for MockNode {
type Primitives = ();
type ChainSpec = ChainSpec;
type StateCommitment = MerklePatriciaTrie;
}
impl DatabaseProviderFactory for MockEthProvider {

View File

@ -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.

View File

@ -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)
}
}

View File

@ -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};

View File

@ -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;
}

View File

@ -1,5 +1,6 @@
//! An integration of [`reth-trie`] with [`reth-db`].
mod commitment;
mod hashed_cursor;
mod prefix_set;
mod proof;
@ -8,6 +9,7 @@ mod storage;
mod trie_cursor;
mod witness;
pub use commitment::{MerklePatriciaTrie, StateCommitment};
pub use hashed_cursor::{
DatabaseHashedAccountCursor, DatabaseHashedCursorFactory, DatabaseHashedStorageCursor,
};

View File

@ -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

View File

@ -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)]
@ -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