Skip to content

Commit

Permalink
Add consensus as a generic-typed node component
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianBland committed Jun 1, 2024
1 parent 4e7741c commit 86efc50
Show file tree
Hide file tree
Showing 22 changed files with 340 additions and 149 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

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

20 changes: 12 additions & 8 deletions crates/blockchain-tree/src/blockchain_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ use tracing::{debug, error, info, instrument, trace, warn};
/// * [BlockchainTree::make_canonical]: Check if we have the hash of a block that is the current
/// canonical head and commit it to db.
#[derive(Debug)]
pub struct BlockchainTree<DB, E> {
pub struct BlockchainTree<DB, C, E> {
/// The state of the tree
///
/// Tracks all the chains, the block indices, and the block buffer.
state: TreeState,
/// External components (the database, consensus engine etc.)
externals: TreeExternals<DB, E>,
externals: TreeExternals<DB, C, E>,
/// Tree configuration
config: BlockchainTreeConfig,
/// Prune modes.
Expand All @@ -74,7 +74,7 @@ pub struct BlockchainTree<DB, E> {
metrics: TreeMetrics,
}

impl<DB, E> BlockchainTree<DB, E> {
impl<DB, C, E> BlockchainTree<DB, C, E> {
/// Subscribe to new blocks events.
///
/// Note: Only canonical blocks are emitted by the tree.
Expand All @@ -88,9 +88,10 @@ impl<DB, E> BlockchainTree<DB, E> {
}
}

impl<DB, E> BlockchainTree<DB, E>
impl<DB, C, E> BlockchainTree<DB, C, E>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
/// Builds the blockchain tree for the node.
Expand All @@ -114,7 +115,7 @@ where
/// storage space efficiently. It's important to validate this configuration to ensure it does
/// not lead to unintended data loss.
pub fn new(
externals: TreeExternals<DB, E>,
externals: TreeExternals<DB, C, E>,
config: BlockchainTreeConfig,
prune_modes: Option<PruneModes>,
) -> ProviderResult<Self> {
Expand Down Expand Up @@ -1403,7 +1404,7 @@ mod tests {

fn setup_externals(
exec_res: Vec<BundleStateWithReceipts>,
) -> TreeExternals<Arc<TempDatabase<DatabaseEnv>>, MockExecutorProvider> {
) -> TreeExternals<Arc<TempDatabase<DatabaseEnv>>, TestConsensus, MockExecutorProvider> {
let chain_spec = Arc::new(
ChainSpecBuilder::default()
.chain(MAINNET.chain)
Expand All @@ -1412,7 +1413,7 @@ mod tests {
.build(),
);
let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec);
let consensus = Arc::new(TestConsensus::default());
let consensus = TestConsensus::default();
let executor_factory = MockExecutorProvider::default();
executor_factory.extend(exec_res);

Expand Down Expand Up @@ -1497,7 +1498,10 @@ mod tests {
self
}

fn assert<DB: Database, E: BlockExecutorProvider>(self, tree: &BlockchainTree<DB, E>) {
fn assert<DB: Database, C: Consensus, E: BlockExecutorProvider>(
self,
tree: &BlockchainTree<DB, C, E>,
) {
if let Some(chain_num) = self.chain_num {
assert_eq!(tree.state.chains.len(), chain_num);
}
Expand Down
20 changes: 12 additions & 8 deletions crates/blockchain-tree/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,18 @@ impl AppendableChain {
///
/// if [BlockValidationKind::Exhaustive] is specified, the method will verify the state root of
/// the block.
pub fn new_canonical_fork<DB, E>(
pub fn new_canonical_fork<DB, C, E>(
block: SealedBlockWithSenders,
parent_header: &SealedHeader,
canonical_block_hashes: &BTreeMap<BlockNumber, BlockHash>,
canonical_fork: ForkBlock,
externals: &TreeExternals<DB, E>,
externals: &TreeExternals<DB, C, E>,
block_attachment: BlockAttachment,
block_validation_kind: BlockValidationKind,
) -> Result<Self, InsertBlockErrorKind>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
let state = BundleStateWithReceipts::default();
Expand Down Expand Up @@ -104,17 +105,18 @@ impl AppendableChain {
/// Create a new chain that forks off of an existing sidechain.
///
/// This differs from [AppendableChain::new_canonical_fork] in that this starts a new fork.
pub(crate) fn new_chain_fork<DB, E>(
pub(crate) fn new_chain_fork<DB, C, E>(
&self,
block: SealedBlockWithSenders,
side_chain_block_hashes: BTreeMap<BlockNumber, BlockHash>,
canonical_block_hashes: &BTreeMap<BlockNumber, BlockHash>,
canonical_fork: ForkBlock,
externals: &TreeExternals<DB, E>,
externals: &TreeExternals<DB, C, E>,
block_validation_kind: BlockValidationKind,
) -> Result<Self, InsertBlockErrorKind>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
let parent_number =
Expand Down Expand Up @@ -167,17 +169,18 @@ impl AppendableChain {
/// - [BlockAttachment] represents if the block extends the canonical chain, and thus we can
/// cache the trie state updates.
/// - [BlockValidationKind] determines if the state root __should__ be validated.
fn validate_and_execute<BSDP, DB, E>(
fn validate_and_execute<BSDP, DB, C, E>(
block: SealedBlockWithSenders,
parent_block: &SealedHeader,
bundle_state_data_provider: BSDP,
externals: &TreeExternals<DB, E>,
externals: &TreeExternals<DB, C, E>,
block_attachment: BlockAttachment,
block_validation_kind: BlockValidationKind,
) -> Result<(BundleStateWithReceipts, Option<TrieUpdates>), BlockExecutionError>
where
BSDP: FullBundleStateDataProvider,
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
// some checks are done before blocks comes here.
Expand Down Expand Up @@ -271,18 +274,19 @@ impl AppendableChain {
/// __not__ the canonical head.
#[track_caller]
#[allow(clippy::too_many_arguments)]
pub(crate) fn append_block<DB, E>(
pub(crate) fn append_block<DB, C, E>(
&mut self,
block: SealedBlockWithSenders,
side_chain_block_hashes: BTreeMap<BlockNumber, BlockHash>,
canonical_block_hashes: &BTreeMap<BlockNumber, BlockHash>,
externals: &TreeExternals<DB, E>,
externals: &TreeExternals<DB, C, E>,
canonical_fork: ForkBlock,
block_attachment: BlockAttachment,
block_validation_kind: BlockValidationKind,
) -> Result<(), InsertBlockErrorKind>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
let parent_block = self.chain.tip();
Expand Down
17 changes: 6 additions & 11 deletions crates/blockchain-tree/src/externals.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
//! Blockchain tree externals.
use reth_consensus::Consensus;
use reth_db::{
cursor::DbCursorRO, database::Database, static_file::HeaderMask, tables, transaction::DbTx,
};
use reth_primitives::{BlockHash, BlockNumber, StaticFileSegment};
use reth_provider::{ProviderFactory, StaticFileProviderFactory, StatsReader};
use reth_storage_errors::provider::ProviderResult;
use std::{collections::BTreeMap, sync::Arc};
use std::collections::BTreeMap;

/// A container for external components.
///
Expand All @@ -19,27 +18,23 @@ use std::{collections::BTreeMap, sync::Arc};
/// - The executor factory to execute blocks with
/// - The chain spec
#[derive(Debug)]
pub struct TreeExternals<DB, E> {
pub struct TreeExternals<DB, C, E> {
/// The provider factory, used to commit the canonical chain, or unwind it.
pub(crate) provider_factory: ProviderFactory<DB>,
/// The consensus engine.
pub(crate) consensus: Arc<dyn Consensus>,
pub(crate) consensus: C,
/// The executor factory to execute blocks with.
pub(crate) executor_factory: E,
}

impl<DB, E> TreeExternals<DB, E> {
impl<DB, C, E> TreeExternals<DB, C, E> {
/// Create new tree externals.
pub fn new(
provider_factory: ProviderFactory<DB>,
consensus: Arc<dyn Consensus>,
executor_factory: E,
) -> Self {
pub fn new(provider_factory: ProviderFactory<DB>, consensus: C, executor_factory: E) -> Self {
Self { provider_factory, consensus, executor_factory }
}
}

impl<DB: Database, E> TreeExternals<DB, E> {
impl<DB: Database, C, E> TreeExternals<DB, C, E> {
/// Fetches the latest canonical block hashes by walking backwards from the head.
///
/// Returns the hashes sorted by increasing block numbers
Expand Down
21 changes: 13 additions & 8 deletions crates/blockchain-tree/src/shareable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use reth_blockchain_tree_api::{
BlockValidationKind, BlockchainTreeEngine, BlockchainTreeViewer, CanonicalOutcome,
InsertPayloadOk,
};
use reth_consensus::Consensus;
use reth_db::database::Database;
use reth_evm::execute::BlockExecutorProvider;
use reth_primitives::{
Expand All @@ -22,21 +23,22 @@ use tracing::trace;

/// Shareable blockchain tree that is behind a RwLock
#[derive(Clone, Debug)]
pub struct ShareableBlockchainTree<DB, E> {
pub struct ShareableBlockchainTree<DB, C, E> {
/// BlockchainTree
pub tree: Arc<RwLock<BlockchainTree<DB, E>>>,
pub tree: Arc<RwLock<BlockchainTree<DB, C, E>>>,
}

impl<DB, E> ShareableBlockchainTree<DB, E> {
impl<DB, C, E> ShareableBlockchainTree<DB, C, E> {
/// Create a new shareable database.
pub fn new(tree: BlockchainTree<DB, E>) -> Self {
pub fn new(tree: BlockchainTree<DB, C, E>) -> Self {
Self { tree: Arc::new(RwLock::new(tree)) }
}
}

impl<DB, E> BlockchainTreeEngine for ShareableBlockchainTree<DB, E>
impl<DB, C, E> BlockchainTreeEngine for ShareableBlockchainTree<DB, C, E>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
fn buffer_block(&self, block: SealedBlockWithSenders) -> Result<(), InsertBlockError> {
Expand Down Expand Up @@ -103,9 +105,10 @@ where
}
}

impl<DB, E> BlockchainTreeViewer for ShareableBlockchainTree<DB, E>
impl<DB, C, E> BlockchainTreeViewer for ShareableBlockchainTree<DB, C, E>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
fn header_by_hash(&self, hash: BlockHash) -> Option<SealedHeader> {
Expand Down Expand Up @@ -166,9 +169,10 @@ where
}
}

impl<DB, E> BlockchainTreePendingStateProvider for ShareableBlockchainTree<DB, E>
impl<DB, C, E> BlockchainTreePendingStateProvider for ShareableBlockchainTree<DB, C, E>
where
DB: Database + Clone,
C: Consensus,
E: BlockExecutorProvider,
{
fn find_pending_state_provider(
Expand All @@ -181,9 +185,10 @@ where
}
}

impl<DB, E> CanonStateSubscriptions for ShareableBlockchainTree<DB, E>
impl<DB, C, E> CanonStateSubscriptions for ShareableBlockchainTree<DB, C, E>
where
DB: Send + Sync,
C: Consensus,
E: Send + Sync,
{
fn subscribe_to_canonical_state(&self) -> reth_provider::CanonStateNotifications {
Expand Down
2 changes: 1 addition & 1 deletion crates/ethereum/consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use validation::validate_block_post_execution;
/// Ethereum beacon consensus
///
/// This consensus engine does basic checks as outlined in the execution specs.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct EthBeaconConsensus {
/// Configuration
chain_spec: Arc<ChainSpec>,
Expand Down
3 changes: 2 additions & 1 deletion crates/ethereum/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ reth-provider.workspace = true
reth-transaction-pool.workspace = true
reth-network.workspace = true
reth-evm-ethereum.workspace = true
reth-auto-seal-consensus.workspace = true
reth-beacon-consensus.workspace = true

# misc
eyre.workspace = true
Expand All @@ -38,4 +40,3 @@ futures.workspace = true
tokio.workspace = true
futures-util.workspace = true
serde_json.workspace = true

25 changes: 24 additions & 1 deletion crates/ethereum/node/src/node.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
//! Ethereum Node types config.
use crate::{EthEngineTypes, EthEvmConfig};
use reth_auto_seal_consensus::AutoSealConsensus;
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
use reth_beacon_consensus::EthBeaconConsensus;
use reth_evm_ethereum::execute::EthExecutorProvider;
use reth_network::NetworkHandle;
use reth_node_builder::{
components::{
ComponentsBuilder, ExecutorBuilder, NetworkBuilder, PayloadServiceBuilder, PoolBuilder,
ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder,
PayloadServiceBuilder, PoolBuilder,
},
node::{FullNodeTypes, NodeTypes},
BuilderContext, Node, PayloadBuilderConfig,
Expand All @@ -32,6 +35,7 @@ impl EthereumNode {
EthereumPayloadBuilder,
EthereumNetworkBuilder,
EthereumExecutorBuilder,
EthereumConsensusBuilder,
>
where
Node: FullNodeTypes<Engine = EthEngineTypes>,
Expand All @@ -42,6 +46,7 @@ impl EthereumNode {
.payload(EthereumPayloadBuilder::default())
.network(EthereumNetworkBuilder::default())
.executor(EthereumExecutorBuilder::default())
.consensus(EthereumConsensusBuilder::default())
}
}

Expand All @@ -60,6 +65,7 @@ where
EthereumPayloadBuilder,
EthereumNetworkBuilder,
EthereumExecutorBuilder,
EthereumConsensusBuilder,
>;

fn components_builder(self) -> Self::ComponentsBuilder {
Expand Down Expand Up @@ -227,3 +233,20 @@ where
Ok(handle)
}
}

/// A basic ethereum consensus builder.
#[derive(Debug, Default, Clone, Copy)]
pub struct EthereumConsensusBuilder {
// TODO add closure to modify consensus
}

impl<Node> ConsensusBuilder<Node> for EthereumConsensusBuilder
where
Node: FullNodeTypes,
{
type Consensus = EthBeaconConsensus;

async fn build_consensus(self, ctx: &BuilderContext<Node>) -> eyre::Result<Self::Consensus> {
Ok(EthBeaconConsensus::new(ctx.chain_spec()))
}
}
Loading

0 comments on commit 86efc50

Please sign in to comment.