Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: integrate BlockchainProvider2 in EthNodeLauncher #9754

Merged
merged 5 commits into from
Jul 24, 2024
Merged
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
1 change: 1 addition & 0 deletions Cargo.lock

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

29 changes: 5 additions & 24 deletions crates/ethereum/engine/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use reth_evm_ethereum::execute::EthExecutorProvider;
use reth_network_p2p::{bodies::client::BodiesClient, headers::client::HeadersClient};
use reth_payload_builder::PayloadBuilderHandle;
use reth_payload_validator::ExecutionPayloadValidator;
use reth_provider::{providers::BlockchainProvider, ProviderFactory};
use reth_provider::{providers::BlockchainProvider2, ProviderFactory};
use reth_prune::Pruner;
use reth_stages_api::Pipeline;
use reth_tasks::TaskSpawner;
Expand Down Expand Up @@ -65,7 +65,7 @@ where
pipeline: Pipeline<DB>,
pipeline_task_spawner: Box<dyn TaskSpawner>,
provider: ProviderFactory<DB>,
blockchain_db: BlockchainProvider<DB>,
blockchain_db: BlockchainProvider2<DB>,
pruner: Pruner<DB, ProviderFactory<DB>>,
payload_builder: PayloadBuilderHandle<EthEngineTypes>,
) -> Self {
Expand Down Expand Up @@ -123,18 +123,13 @@ pub struct EthServiceError {}
#[cfg(test)]
mod tests {
use super::*;
use reth_blockchain_tree::{
BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals,
};
use reth_chainspec::{ChainSpecBuilder, MAINNET};
use reth_consensus::test_utils::TestConsensus;
use reth_engine_tree::test_utils::TestPipelineBuilder;
use reth_ethereum_engine_primitives::EthEngineTypes;
use reth_exex_types::FinishedExExHeight;
use reth_network_p2p::test_utils::TestFullBlockClient;
use reth_primitives::SealedHeader;
use reth_provider::test_utils::create_test_provider_factory_with_chain_spec;
use reth_prune::PruneModes;
use reth_tasks::TokioTaskExecutor;
use std::sync::Arc;
use tokio::sync::{mpsc::unbounded_channel, watch};
Expand All @@ -157,23 +152,9 @@ mod tests {
let pipeline = TestPipelineBuilder::new().build(chain_spec.clone());
let pipeline_task_spawner = Box::<TokioTaskExecutor>::default();
let provider_factory = create_test_provider_factory_with_chain_spec(chain_spec.clone());
let consensus = Arc::new(TestConsensus::default());
let executor_factory = EthExecutorProvider::ethereum(chain_spec.clone());
let externals = TreeExternals::new(provider_factory.clone(), consensus, executor_factory);
let tree = Arc::new(ShareableBlockchainTree::new(
BlockchainTree::new(
externals,
BlockchainTreeConfig::new(1, 2, 3, 2),
PruneModes::default(),
)
.expect("failed to create tree"),
));

let blockchain_db = BlockchainProvider::with_latest(
provider_factory.clone(),
tree,
SealedHeader::default(),
);

let blockchain_db =
BlockchainProvider2::with_latest(provider_factory.clone(), SealedHeader::default());

let (_tx, rx) = watch::channel(FinishedExExHeight::NoExExs);
let pruner =
Expand Down
1 change: 1 addition & 0 deletions crates/ethereum/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ reth-tokio-util.workspace = true
reth-node-events.workspace = true
reth-node-core.workspace = true
reth-exex.workspace = true
reth-blockchain-tree.workspace = true

# misc
eyre.workspace = true
Expand Down
18 changes: 15 additions & 3 deletions crates/ethereum/node/src/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use reth_beacon_consensus::{
hooks::{EngineHooks, StaticFileHook},
BeaconConsensusEngineHandle,
};
use reth_blockchain_tree::BlockchainTreeConfig;
use reth_ethereum_engine::service::{ChainEvent, EthService};
use reth_ethereum_engine_primitives::EthEngineTypes;
use reth_exex::ExExManagerHandle;
Expand All @@ -23,7 +24,7 @@ use reth_node_core::{
version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA},
};
use reth_node_events::{cl::ConsensusLayerHealthEvents, node};
use reth_provider::providers::BlockchainProvider;
use reth_provider::providers::BlockchainProvider2;
use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi};
use reth_rpc_types::engine::ClientVersionV1;
use reth_tasks::TaskExecutor;
Expand All @@ -49,7 +50,7 @@ impl EthNodeLauncher {
impl<T, CB, AO> LaunchNode<NodeBuilderWithComponents<T, CB, AO>> for EthNodeLauncher
where
T: FullNodeTypes<
Provider = BlockchainProvider<<T as FullNodeTypes>::DB>,
Provider = BlockchainProvider2<<T as FullNodeTypes>::DB>,
Engine = EthEngineTypes,
>,
CB: NodeComponentsBuilder<T>,
Expand All @@ -72,6 +73,15 @@ where
} = target;
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;

// TODO: move tree_config and canon_state_notification_sender
// initialization to with_blockchain_db once the engine revamp is done
// https://github.com/paradigmxyz/reth/issues/8742
let tree_config = BlockchainTreeConfig::default();

// NOTE: This is a temporary workaround to provide the canon state notification sender to the components builder because there's a cyclic dependency between the blockchain provider and the tree component. This will be removed once the Blockchain provider no longer depends on an instance of the tree: <https://github.com/paradigmxyz/reth/issues/7154>
let (canon_state_notification_sender, _receiver) =
tokio::sync::broadcast::channel(tree_config.max_reorg_depth() as usize * 2);

// setup the launch context
let ctx = ctx
.with_configured_globals()
Expand Down Expand Up @@ -99,7 +109,9 @@ where
.with_metrics_task()
// passing FullNodeTypes as type parameter here so that we can build
// later the components.
.with_blockchain_db::<T>()?
.with_blockchain_db::<T, _>(move |provider_factory| {
Ok(BlockchainProvider2::new(provider_factory)?)
}, tree_config, canon_state_notification_sender)?
.with_components(components_builder, on_component_initialized).await?;

// spawn exexs
Expand Down
10 changes: 8 additions & 2 deletions crates/ethereum/node/tests/it/builder.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
//! Node builder setup tests.

use reth_db::test_utils::create_test_rw_db;
use std::sync::Arc;

use reth_db::{
test_utils::{create_test_rw_db, TempDatabase},
DatabaseEnv,
};
use reth_node_builder::{FullNodeComponents, NodeBuilder, NodeConfig};
use reth_node_ethereum::{
launch::EthNodeLauncher,
node::{EthereumAddOns, EthereumNode},
};
use reth_provider::providers::BlockchainProvider2;
use reth_tasks::TaskManager;

#[test]
Expand Down Expand Up @@ -45,7 +51,7 @@ async fn test_eth_launcher() {
let db = create_test_rw_db();
let _builder = NodeBuilder::new(config)
.with_database(db)
.with_types::<EthereumNode>()
.with_types_and_provider::<EthereumNode, BlockchainProvider2<Arc<TempDatabase<DatabaseEnv>>>>()
.with_components(EthereumNode::components())
.with_add_ons::<EthereumAddOns>()
.launch_with_fn(|builder| {
Expand Down
82 changes: 53 additions & 29 deletions crates/node/builder/src/launch/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ use rayon::ThreadPoolBuilder;
use reth_auto_seal_consensus::MiningMode;
use reth_beacon_consensus::EthBeaconConsensus;
use reth_blockchain_tree::{
noop::NoopBlockchainTree, BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree,
TreeExternals,
BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals,
};
use reth_chainspec::{Chain, ChainSpec};
use reth_config::{config::EtlConfig, PruneConfig};
Expand All @@ -29,8 +28,9 @@ use reth_node_core::{
};
use reth_primitives::{BlockNumber, Head, B256};
use reth_provider::{
providers::{BlockchainProvider, StaticFileProvider},
CanonStateNotificationSender, ProviderFactory, StaticFileProviderFactory,
providers::{BlockchainProvider, BlockchainProvider2, StaticFileProvider},
CanonStateNotificationSender, FullProvider, ProviderFactory, StaticFileProviderFactory,
TreeViewer,
};
use reth_prune::{PruneModes, PrunerBuilder};
use reth_rpc_builder::config::RethRpcServerConfig;
Expand All @@ -45,6 +45,27 @@ use tokio::sync::{
oneshot, watch,
};

/// Allows to set a tree viewer for a configured blockchain provider.
// TODO: remove this helper trait once the engine revamp is done, the new
// blockchain provider won't require a TreeViewer.
// https://github.com/paradigmxyz/reth/issues/8742
pub trait WithTree {
/// Setter for tree viewer.
fn set_tree(self, tree: Arc<dyn TreeViewer>) -> Self;
}

impl<DB: Database> WithTree for BlockchainProvider<DB> {
fn set_tree(self, tree: Arc<dyn TreeViewer>) -> Self {
self.with_tree(tree)
}
}

impl<DB: Database> WithTree for BlockchainProvider2<DB> {
fn set_tree(self, _tree: Arc<dyn TreeViewer>) -> Self {
self
}
}

/// Reusable setup for launching a node.
///
/// This provides commonly used boilerplate for launching a node.
Expand Down Expand Up @@ -525,24 +546,18 @@ where
}

/// Creates a `BlockchainProvider` and attaches it to the launch context.
pub fn with_blockchain_db<T>(
pub fn with_blockchain_db<T, F>(
self,
create_blockchain_provider: F,
tree_config: BlockchainTreeConfig,
canon_state_notification_sender: CanonStateNotificationSender,
) -> eyre::Result<LaunchContextWith<Attached<WithConfigs, WithMeteredProviders<DB, T>>>>
where
T: FullNodeTypes<Provider = BlockchainProvider<<T as FullNodeTypes>::DB>>,
T: FullNodeTypes,
T::Provider: FullProvider<DB>,
F: FnOnce(ProviderFactory<DB>) -> eyre::Result<T::Provider>,
{
let tree_config = BlockchainTreeConfig::default();

// NOTE: This is a temporary workaround to provide the canon state notification sender to the components builder because there's a cyclic dependency between the blockchain provider and the tree component. This will be removed once the Blockchain provider no longer depends on an instance of the tree: <https://github.com/paradigmxyz/reth/issues/7154>
let (canon_state_notification_sender, _receiver) =
tokio::sync::broadcast::channel(tree_config.max_reorg_depth() as usize * 2);

let blockchain_db = BlockchainProvider::new(
self.provider_factory().clone(),
Arc::new(NoopBlockchainTree::with_canon_state_notifications(
canon_state_notification_sender.clone(),
)),
)?;
let blockchain_db = create_blockchain_provider(self.provider_factory().clone())?;

let metered_providers = WithMeteredProviders {
db_provider_container: WithMeteredProvider {
Expand All @@ -568,7 +583,8 @@ where
impl<DB, T> LaunchContextWith<Attached<WithConfigs, WithMeteredProviders<DB, T>>>
where
DB: Database + DatabaseMetrics + Send + Sync + Clone + 'static,
T: FullNodeTypes<Provider = BlockchainProvider<DB>>,
T: FullNodeTypes,
T::Provider: FullProvider<DB> + WithTree,
{
/// Returns access to the underlying database.
pub fn database(&self) -> &DB {
Expand All @@ -594,8 +610,8 @@ where
self.right().db_provider_container.metrics_sender.clone()
}

/// Returns a reference to the `BlockchainProvider`.
pub const fn blockchain_db(&self) -> &BlockchainProvider<DB> {
/// Returns a reference to the blockchain provider.
pub const fn blockchain_db(&self) -> &T::Provider {
&self.right().blockchain_db
}

Expand Down Expand Up @@ -650,7 +666,7 @@ where
let blockchain_tree = Arc::new(ShareableBlockchainTree::new(tree));

// Replace the tree component with the actual tree
let blockchain_db = self.blockchain_db().clone().with_tree(blockchain_tree);
let blockchain_db = self.blockchain_db().clone().set_tree(blockchain_tree);

debug!(target: "reth::cli", "configured blockchain tree");

Expand Down Expand Up @@ -687,7 +703,8 @@ where
impl<DB, T, CB> LaunchContextWith<Attached<WithConfigs, WithComponents<DB, T, CB>>>
where
DB: Database + DatabaseMetrics + Send + Sync + Clone + 'static,
T: FullNodeTypes<Provider = BlockchainProvider<DB>>,
T: FullNodeTypes,
T::Provider: FullProvider<DB> + WithTree,
CB: NodeComponentsBuilder<T>,
{
/// Returns the configured `ProviderFactory`.
Expand Down Expand Up @@ -724,8 +741,8 @@ where
&self.right().node_adapter
}

/// Returns a reference to the `BlockchainProvider`.
pub const fn blockchain_db(&self) -> &BlockchainProvider<DB> {
/// Returns a reference to the blockchain provider.
pub const fn blockchain_db(&self) -> &T::Provider {
&self.right().blockchain_db
}

Expand Down Expand Up @@ -821,9 +838,14 @@ pub struct WithMeteredProvider<DB> {
/// Helper container to bundle the [`ProviderFactory`], [`BlockchainProvider`]
/// and a metrics sender.
#[allow(missing_debug_implementations)]
pub struct WithMeteredProviders<DB, T> {
pub struct WithMeteredProviders<DB, T>
where
DB: Database,
T: FullNodeTypes,
T::Provider: FullProvider<DB>,
{
db_provider_container: WithMeteredProvider<DB>,
blockchain_db: BlockchainProvider<DB>,
blockchain_db: T::Provider,
canon_state_notification_sender: CanonStateNotificationSender,
tree_config: BlockchainTreeConfig,
// this field is used to store a reference to the FullNodeTypes so that we
Expand All @@ -835,12 +857,14 @@ pub struct WithMeteredProviders<DB, T> {
#[allow(missing_debug_implementations)]
pub struct WithComponents<DB, T, CB>
where
T: FullNodeTypes<Provider = BlockchainProvider<DB>>,
DB: Database,
T: FullNodeTypes,
T::Provider: FullProvider<DB>,
CB: NodeComponentsBuilder<T>,
{
db_provider_container: WithMeteredProvider<DB>,
tree_config: BlockchainTreeConfig,
blockchain_db: BlockchainProvider<DB>,
blockchain_db: T::Provider,
node_adapter: NodeAdapter<T, CB::Components>,
head: Head,
consensus: Arc<dyn Consensus>,
Expand Down
18 changes: 17 additions & 1 deletion crates/node/builder/src/launch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use reth_beacon_consensus::{
hooks::{EngineHooks, PruneHook, StaticFileHook},
BeaconConsensusEngine,
};
use reth_blockchain_tree::{noop::NoopBlockchainTree, BlockchainTreeConfig};
use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider, RpcBlockProvider};
use reth_engine_util::EngineMessageStreamExt;
use reth_exex::ExExManagerHandle;
Expand Down Expand Up @@ -119,6 +120,19 @@ where
} = target;
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;

// TODO: remove tree and move tree_config and canon_state_notification_sender
// initialization to with_blockchain_db once the engine revamp is done
// https://github.com/paradigmxyz/reth/issues/8742
let tree_config = BlockchainTreeConfig::default();

// NOTE: This is a temporary workaround to provide the canon state notification sender to the components builder because there's a cyclic dependency between the blockchain provider and the tree component. This will be removed once the Blockchain provider no longer depends on an instance of the tree: <https://github.com/paradigmxyz/reth/issues/7154>
let (canon_state_notification_sender, _receiver) =
tokio::sync::broadcast::channel(tree_config.max_reorg_depth() as usize * 2);

let tree = Arc::new(NoopBlockchainTree::with_canon_state_notifications(
canon_state_notification_sender.clone(),
));

// setup the launch context
let ctx = ctx
.with_configured_globals()
Expand Down Expand Up @@ -146,7 +160,9 @@ where
.with_metrics_task()
// passing FullNodeTypes as type parameter here so that we can build
// later the components.
.with_blockchain_db::<T>()?
.with_blockchain_db::<T, _>(move |provider_factory| {
Ok(BlockchainProvider::new(provider_factory, tree)?)
}, tree_config, canon_state_notification_sender)?
.with_components(components_builder, on_component_initialized).await?;

// spawn exexs
Expand Down
Loading