mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore(rpc): expose ethapi in node builder for op customisation (#9444)
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
This commit is contained in:
9
Cargo.lock
generated
9
Cargo.lock
generated
@ -6837,6 +6837,7 @@ dependencies = [
|
|||||||
"reth-db",
|
"reth-db",
|
||||||
"reth-network-peers",
|
"reth-network-peers",
|
||||||
"reth-node-builder",
|
"reth-node-builder",
|
||||||
|
"reth-node-ethereum",
|
||||||
"reth-payload-builder",
|
"reth-payload-builder",
|
||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
"reth-provider",
|
"reth-provider",
|
||||||
@ -7581,6 +7582,7 @@ dependencies = [
|
|||||||
"reth-rpc",
|
"reth-rpc",
|
||||||
"reth-rpc-builder",
|
"reth-rpc-builder",
|
||||||
"reth-rpc-engine-api",
|
"reth-rpc-engine-api",
|
||||||
|
"reth-rpc-eth-types",
|
||||||
"reth-rpc-layer",
|
"reth-rpc-layer",
|
||||||
"reth-rpc-types",
|
"reth-rpc-types",
|
||||||
"reth-stages",
|
"reth-stages",
|
||||||
@ -7683,6 +7685,7 @@ dependencies = [
|
|||||||
"reth-node-core",
|
"reth-node-core",
|
||||||
"reth-payload-builder",
|
"reth-payload-builder",
|
||||||
"reth-provider",
|
"reth-provider",
|
||||||
|
"reth-rpc",
|
||||||
"reth-tracing",
|
"reth-tracing",
|
||||||
"reth-transaction-pool",
|
"reth-transaction-pool",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
@ -7740,6 +7743,7 @@ dependencies = [
|
|||||||
"reth-node-builder",
|
"reth-node-builder",
|
||||||
"reth-optimism-consensus",
|
"reth-optimism-consensus",
|
||||||
"reth-optimism-payload-builder",
|
"reth-optimism-payload-builder",
|
||||||
|
"reth-optimism-rpc",
|
||||||
"reth-payload-builder",
|
"reth-payload-builder",
|
||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
"reth-provider",
|
"reth-provider",
|
||||||
@ -7749,6 +7753,7 @@ dependencies = [
|
|||||||
"reth-rpc-eth-types",
|
"reth-rpc-eth-types",
|
||||||
"reth-rpc-types",
|
"reth-rpc-types",
|
||||||
"reth-rpc-types-compat",
|
"reth-rpc-types-compat",
|
||||||
|
"reth-tasks",
|
||||||
"reth-tracing",
|
"reth-tracing",
|
||||||
"reth-transaction-pool",
|
"reth-transaction-pool",
|
||||||
"revm-primitives",
|
"revm-primitives",
|
||||||
@ -7848,8 +7853,10 @@ dependencies = [
|
|||||||
"reth-errors",
|
"reth-errors",
|
||||||
"reth-evm",
|
"reth-evm",
|
||||||
"reth-evm-optimism",
|
"reth-evm-optimism",
|
||||||
|
"reth-node-api",
|
||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
"reth-provider",
|
"reth-provider",
|
||||||
|
"reth-rpc",
|
||||||
"reth-rpc-eth-api",
|
"reth-rpc-eth-api",
|
||||||
"reth-rpc-eth-types",
|
"reth-rpc-eth-types",
|
||||||
"reth-rpc-server-types",
|
"reth-rpc-server-types",
|
||||||
@ -8119,6 +8126,7 @@ dependencies = [
|
|||||||
"reth-evm-optimism",
|
"reth-evm-optimism",
|
||||||
"reth-network-api",
|
"reth-network-api",
|
||||||
"reth-network-peers",
|
"reth-network-peers",
|
||||||
|
"reth-node-api",
|
||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
"reth-provider",
|
"reth-provider",
|
||||||
"reth-revm",
|
"reth-revm",
|
||||||
@ -8195,6 +8203,7 @@ dependencies = [
|
|||||||
"reth-metrics",
|
"reth-metrics",
|
||||||
"reth-network-api",
|
"reth-network-api",
|
||||||
"reth-network-peers",
|
"reth-network-peers",
|
||||||
|
"reth-node-api",
|
||||||
"reth-node-core",
|
"reth-node-core",
|
||||||
"reth-payload-builder",
|
"reth-payload-builder",
|
||||||
"reth-primitives",
|
"reth-primitives",
|
||||||
|
|||||||
@ -22,6 +22,7 @@ reth-node-builder = { workspace = true, features = ["test-utils"] }
|
|||||||
reth-tokio-util.workspace = true
|
reth-tokio-util.workspace = true
|
||||||
reth-stages-types.workspace = true
|
reth-stages-types.workspace = true
|
||||||
reth-network-peers.workspace = true
|
reth-network-peers.workspace = true
|
||||||
|
reth-node-ethereum.workspace = true
|
||||||
|
|
||||||
jsonrpsee.workspace = true
|
jsonrpsee.workspace = true
|
||||||
|
|
||||||
|
|||||||
@ -1,16 +1,19 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use node::NodeTestContext;
|
use node::NodeTestContext;
|
||||||
use reth::{
|
use reth::{
|
||||||
args::{DiscoveryArgs, NetworkArgs, RpcServerArgs},
|
args::{DiscoveryArgs, NetworkArgs, RpcServerArgs},
|
||||||
builder::{NodeBuilder, NodeConfig, NodeHandle},
|
builder::{NodeBuilder, NodeConfig, NodeHandle},
|
||||||
|
rpc::api::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||||
tasks::TaskManager,
|
tasks::TaskManager,
|
||||||
};
|
};
|
||||||
use reth_chainspec::ChainSpec;
|
use reth_chainspec::ChainSpec;
|
||||||
use reth_db::{test_utils::TempDatabase, DatabaseEnv};
|
use reth_db::{test_utils::TempDatabase, DatabaseEnv};
|
||||||
use reth_node_builder::{
|
use reth_node_builder::{
|
||||||
components::NodeComponentsBuilder, FullNodeTypesAdapter, Node, NodeAdapter, RethFullAdapter,
|
components::NodeComponentsBuilder, rpc::EthApiBuilderProvider, FullNodeTypesAdapter, Node,
|
||||||
|
NodeAdapter, NodeAddOns, RethFullAdapter,
|
||||||
};
|
};
|
||||||
use reth_provider::providers::BlockchainProvider;
|
use reth_provider::providers::BlockchainProvider;
|
||||||
use std::sync::Arc;
|
|
||||||
use tracing::{span, Level};
|
use tracing::{span, Level};
|
||||||
use wallet::Wallet;
|
use wallet::Wallet;
|
||||||
|
|
||||||
@ -42,9 +45,11 @@ pub async fn setup<N>(
|
|||||||
num_nodes: usize,
|
num_nodes: usize,
|
||||||
chain_spec: Arc<ChainSpec>,
|
chain_spec: Arc<ChainSpec>,
|
||||||
is_dev: bool,
|
is_dev: bool,
|
||||||
) -> eyre::Result<(Vec<NodeHelperType<N>>, TaskManager, Wallet)>
|
) -> eyre::Result<(Vec<NodeHelperType<N, N::AddOns>>, TaskManager, Wallet)>
|
||||||
where
|
where
|
||||||
N: Default + Node<TmpNodeAdapter<N>>,
|
N: Default + Node<TmpNodeAdapter<N>>,
|
||||||
|
<N::AddOns as NodeAddOns<Adapter<N>>>::EthApi:
|
||||||
|
FullEthApiServer + AddDevSigners + EthApiBuilderProvider<Adapter<N>>,
|
||||||
{
|
{
|
||||||
let tasks = TaskManager::current();
|
let tasks = TaskManager::current();
|
||||||
let exec = tasks.executor();
|
let exec = tasks.executor();
|
||||||
@ -55,7 +60,7 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create nodes and peer them
|
// Create nodes and peer them
|
||||||
let mut nodes: Vec<NodeTestContext<_>> = Vec::with_capacity(num_nodes);
|
let mut nodes: Vec<NodeTestContext<_, _>> = Vec::with_capacity(num_nodes);
|
||||||
|
|
||||||
for idx in 0..num_nodes {
|
for idx in 0..num_nodes {
|
||||||
let node_config = NodeConfig::test()
|
let node_config = NodeConfig::test()
|
||||||
@ -106,4 +111,4 @@ type Adapter<N> = NodeAdapter<
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
/// Type alias for a type of NodeHelper
|
/// Type alias for a type of NodeHelper
|
||||||
pub type NodeHelperType<N> = NodeTestContext<Adapter<N>>;
|
pub type NodeHelperType<N, AO> = NodeTestContext<Adapter<N>, AO>;
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
use crate::{
|
use std::{marker::PhantomData, pin::Pin};
|
||||||
engine_api::EngineApiTestContext, network::NetworkTestContext, payload::PayloadTestContext,
|
|
||||||
rpc::RpcTestContext, traits::PayloadEnvelopeExt,
|
|
||||||
};
|
|
||||||
|
|
||||||
use alloy_rpc_types::BlockNumberOrTag;
|
use alloy_rpc_types::BlockNumberOrTag;
|
||||||
use eyre::Ok;
|
use eyre::Ok;
|
||||||
@ -11,32 +8,41 @@ use reth::{
|
|||||||
builder::FullNode,
|
builder::FullNode,
|
||||||
payload::PayloadTypes,
|
payload::PayloadTypes,
|
||||||
providers::{BlockReader, BlockReaderIdExt, CanonStateSubscriptions, StageCheckpointReader},
|
providers::{BlockReader, BlockReaderIdExt, CanonStateSubscriptions, StageCheckpointReader},
|
||||||
rpc::types::engine::PayloadStatusEnum,
|
rpc::{
|
||||||
|
api::eth::helpers::{EthApiSpec, EthTransactions, TraceExt},
|
||||||
|
types::engine::PayloadStatusEnum,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use reth_node_builder::NodeTypes;
|
use reth_node_builder::{NodeAddOns, NodeTypes};
|
||||||
use reth_primitives::{BlockHash, BlockNumber, Bytes, B256};
|
use reth_primitives::{BlockHash, BlockNumber, Bytes, B256};
|
||||||
use reth_stages_types::StageId;
|
use reth_stages_types::StageId;
|
||||||
use std::{marker::PhantomData, pin::Pin};
|
|
||||||
use tokio_stream::StreamExt;
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
engine_api::EngineApiTestContext, network::NetworkTestContext, payload::PayloadTestContext,
|
||||||
|
rpc::RpcTestContext, traits::PayloadEnvelopeExt,
|
||||||
|
};
|
||||||
|
|
||||||
/// An helper struct to handle node actions
|
/// An helper struct to handle node actions
|
||||||
pub struct NodeTestContext<Node>
|
pub struct NodeTestContext<Node, AddOns>
|
||||||
where
|
where
|
||||||
Node: FullNodeComponents,
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
{
|
{
|
||||||
pub inner: FullNode<Node>,
|
pub inner: FullNode<Node, AddOns>,
|
||||||
pub payload: PayloadTestContext<Node::Engine>,
|
pub payload: PayloadTestContext<Node::Engine>,
|
||||||
pub network: NetworkTestContext,
|
pub network: NetworkTestContext,
|
||||||
pub engine_api: EngineApiTestContext<Node::Engine>,
|
pub engine_api: EngineApiTestContext<Node::Engine>,
|
||||||
pub rpc: RpcTestContext<Node>,
|
pub rpc: RpcTestContext<Node, AddOns::EthApi>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node> NodeTestContext<Node>
|
impl<Node, AddOns> NodeTestContext<Node, AddOns>
|
||||||
where
|
where
|
||||||
Node: FullNodeComponents,
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
{
|
{
|
||||||
/// Creates a new test node
|
/// Creates a new test node
|
||||||
pub async fn new(node: FullNode<Node>) -> eyre::Result<Self> {
|
pub async fn new(node: FullNode<Node, AddOns>) -> eyre::Result<Self> {
|
||||||
let builder = node.payload_builder.clone();
|
let builder = node.payload_builder.clone();
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -53,7 +59,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Establish a connection to the node
|
/// Establish a connection to the node
|
||||||
pub async fn connect(&mut self, node: &mut NodeTestContext<Node>) {
|
pub async fn connect(&mut self, node: &mut NodeTestContext<Node, AddOns>) {
|
||||||
self.network.add_peer(node.network.record()).await;
|
self.network.add_peer(node.network.record()).await;
|
||||||
node.network.next_session_established().await;
|
node.network.next_session_established().await;
|
||||||
self.network.next_session_established().await;
|
self.network.next_session_established().await;
|
||||||
@ -77,6 +83,7 @@ where
|
|||||||
where
|
where
|
||||||
<Node::Engine as EngineTypes>::ExecutionPayloadV3:
|
<Node::Engine as EngineTypes>::ExecutionPayloadV3:
|
||||||
From<<Node::Engine as PayloadTypes>::BuiltPayload> + PayloadEnvelopeExt,
|
From<<Node::Engine as PayloadTypes>::BuiltPayload> + PayloadEnvelopeExt,
|
||||||
|
AddOns::EthApi: EthApiSpec + EthTransactions + TraceExt,
|
||||||
{
|
{
|
||||||
let mut chain = Vec::with_capacity(length as usize);
|
let mut chain = Vec::with_capacity(length as usize);
|
||||||
for i in 0..length {
|
for i in 0..length {
|
||||||
|
|||||||
@ -3,17 +3,23 @@ use alloy_network::eip2718::Decodable2718;
|
|||||||
use reth::{
|
use reth::{
|
||||||
builder::{rpc::RpcRegistry, FullNodeComponents},
|
builder::{rpc::RpcRegistry, FullNodeComponents},
|
||||||
rpc::{
|
rpc::{
|
||||||
api::{eth::helpers::EthTransactions, DebugApiServer},
|
api::{
|
||||||
|
eth::helpers::{EthApiSpec, EthTransactions, TraceExt},
|
||||||
|
DebugApiServer,
|
||||||
|
},
|
||||||
server_types::eth::EthResult,
|
server_types::eth::EthResult,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use reth_primitives::{Bytes, B256};
|
use reth_primitives::{Bytes, B256};
|
||||||
|
|
||||||
pub struct RpcTestContext<Node: FullNodeComponents> {
|
pub struct RpcTestContext<Node: FullNodeComponents, EthApi> {
|
||||||
pub inner: RpcRegistry<Node>,
|
pub inner: RpcRegistry<Node, EthApi>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> RpcTestContext<Node> {
|
impl<Node: FullNodeComponents, EthApi> RpcTestContext<Node, EthApi>
|
||||||
|
where
|
||||||
|
EthApi: EthApiSpec + EthTransactions + TraceExt,
|
||||||
|
{
|
||||||
/// Injects a raw transaction into the node tx pool via RPC server
|
/// Injects a raw transaction into the node tx pool via RPC server
|
||||||
pub async fn inject_tx(&mut self, raw_tx: Bytes) -> EthResult<B256> {
|
pub async fn inject_tx(&mut self, raw_tx: Bytes) -> EthResult<B256> {
|
||||||
let eth_api = self.inner.eth_api();
|
let eth_api = self.inner.eth_api();
|
||||||
|
|||||||
@ -25,6 +25,8 @@ reth-evm-ethereum.workspace = true
|
|||||||
reth-consensus.workspace = true
|
reth-consensus.workspace = true
|
||||||
reth-auto-seal-consensus.workspace = true
|
reth-auto-seal-consensus.workspace = true
|
||||||
reth-beacon-consensus.workspace = true
|
reth-beacon-consensus.workspace = true
|
||||||
|
reth-rpc.workspace = true
|
||||||
|
reth-node-api.workspace = true
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
eyre.workspace = true
|
eyre.workspace = true
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
//! Ethereum Node types config.
|
//! Ethereum Node types config.
|
||||||
|
|
||||||
use crate::{EthEngineTypes, EthEvmConfig};
|
use std::sync::Arc;
|
||||||
|
|
||||||
use reth_auto_seal_consensus::AutoSealConsensus;
|
use reth_auto_seal_consensus::AutoSealConsensus;
|
||||||
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
|
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
|
||||||
use reth_beacon_consensus::EthBeaconConsensus;
|
use reth_beacon_consensus::EthBeaconConsensus;
|
||||||
@ -9,6 +10,7 @@ use reth_ethereum_engine_primitives::{
|
|||||||
};
|
};
|
||||||
use reth_evm_ethereum::execute::EthExecutorProvider;
|
use reth_evm_ethereum::execute::EthExecutorProvider;
|
||||||
use reth_network::NetworkHandle;
|
use reth_network::NetworkHandle;
|
||||||
|
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||||
use reth_node_builder::{
|
use reth_node_builder::{
|
||||||
components::{
|
components::{
|
||||||
ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder,
|
ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder,
|
||||||
@ -19,12 +21,14 @@ use reth_node_builder::{
|
|||||||
};
|
};
|
||||||
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
|
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
|
||||||
use reth_provider::CanonStateSubscriptions;
|
use reth_provider::CanonStateSubscriptions;
|
||||||
|
use reth_rpc::EthApi;
|
||||||
use reth_tracing::tracing::{debug, info};
|
use reth_tracing::tracing::{debug, info};
|
||||||
use reth_transaction_pool::{
|
use reth_transaction_pool::{
|
||||||
blobstore::DiskFileBlobStore, EthTransactionPool, TransactionPool,
|
blobstore::DiskFileBlobStore, EthTransactionPool, TransactionPool,
|
||||||
TransactionValidationTaskExecutor,
|
TransactionValidationTaskExecutor,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
|
||||||
|
use crate::{EthEngineTypes, EthEvmConfig};
|
||||||
|
|
||||||
/// Type configuration for a regular Ethereum node.
|
/// Type configuration for a regular Ethereum node.
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
@ -64,6 +68,14 @@ impl NodeTypes for EthereumNode {
|
|||||||
type Engine = EthEngineTypes;
|
type Engine = EthEngineTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add-ons w.r.t. l1 ethereum.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EthereumAddOns;
|
||||||
|
|
||||||
|
impl<N: FullNodeComponents> NodeAddOns<N> for EthereumAddOns {
|
||||||
|
type EthApi = EthApi<N::Provider, N::Pool, NetworkHandle, N::Evm>;
|
||||||
|
}
|
||||||
|
|
||||||
impl<N> Node<N> for EthereumNode
|
impl<N> Node<N> for EthereumNode
|
||||||
where
|
where
|
||||||
N: FullNodeTypes<Engine = EthEngineTypes>,
|
N: FullNodeTypes<Engine = EthEngineTypes>,
|
||||||
@ -77,7 +89,9 @@ where
|
|||||||
EthereumConsensusBuilder,
|
EthereumConsensusBuilder,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
fn components_builder(self) -> Self::ComponentsBuilder {
|
type AddOns = EthereumAddOns;
|
||||||
|
|
||||||
|
fn components_builder(&self) -> Self::ComponentsBuilder {
|
||||||
Self::components()
|
Self::components()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use std::sync::Arc;
|
|||||||
use alloy_genesis::Genesis;
|
use alloy_genesis::Genesis;
|
||||||
use alloy_primitives::{b256, hex};
|
use alloy_primitives::{b256, hex};
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use reth::rpc::api::eth::helpers::EthTransactions;
|
use reth::core::rpc::eth::helpers::EthTransactions;
|
||||||
use reth_chainspec::ChainSpec;
|
use reth_chainspec::ChainSpec;
|
||||||
use reth_e2e_test_utils::setup;
|
use reth_e2e_test_utils::setup;
|
||||||
use reth_provider::CanonStateSubscriptions;
|
use reth_provider::CanonStateSubscriptions;
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
use alloy_primitives::{Address, B256};
|
use alloy_primitives::{Address, B256};
|
||||||
use reth::rpc::types::engine::PayloadAttributes;
|
use reth::rpc::types::engine::PayloadAttributes;
|
||||||
use reth_e2e_test_utils::NodeHelperType;
|
use reth_e2e_test_utils::NodeHelperType;
|
||||||
use reth_node_ethereum::EthereumNode;
|
use reth_node_ethereum::{node::EthereumAddOns, EthereumNode};
|
||||||
use reth_payload_builder::EthPayloadBuilderAttributes;
|
use reth_payload_builder::EthPayloadBuilderAttributes;
|
||||||
|
|
||||||
/// Ethereum Node Helper type
|
/// Ethereum Node Helper type
|
||||||
pub(crate) type EthNode = NodeHelperType<EthereumNode>;
|
pub(crate) type EthNode = NodeHelperType<EthereumNode, EthereumAddOns>;
|
||||||
|
|
||||||
/// Helper function to create a new eth payload attributes
|
/// Helper function to create a new eth payload attributes
|
||||||
pub(crate) fn eth_payload_attributes(timestamp: u64) -> EthPayloadBuilderAttributes {
|
pub(crate) fn eth_payload_attributes(timestamp: u64) -> EthPayloadBuilderAttributes {
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
//! Node builder setup tests.
|
//! Node builder setup tests.
|
||||||
|
|
||||||
use reth_db::test_utils::create_test_rw_db;
|
use reth_db::test_utils::create_test_rw_db;
|
||||||
use reth_node_api::FullNodeComponents;
|
use reth_node_builder::{FullNodeComponents, NodeBuilder, NodeConfig};
|
||||||
use reth_node_builder::{NodeBuilder, NodeConfig};
|
use reth_node_ethereum::node::{EthereumAddOns, EthereumNode};
|
||||||
use reth_node_ethereum::node::EthereumNode;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic_setup() {
|
fn test_basic_setup() {
|
||||||
@ -15,6 +14,7 @@ fn test_basic_setup() {
|
|||||||
.with_database(db)
|
.with_database(db)
|
||||||
.with_types::<EthereumNode>()
|
.with_types::<EthereumNode>()
|
||||||
.with_components(EthereumNode::components())
|
.with_components(EthereumNode::components())
|
||||||
|
.with_add_ons::<EthereumAddOns>()
|
||||||
.on_component_initialized(move |ctx| {
|
.on_component_initialized(move |ctx| {
|
||||||
let _provider = ctx.provider();
|
let _provider = ctx.provider();
|
||||||
println!("{msg}");
|
println!("{msg}");
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use reth_db::test_utils::create_test_rw_db;
|
|||||||
use reth_exex::ExExContext;
|
use reth_exex::ExExContext;
|
||||||
use reth_node_api::FullNodeComponents;
|
use reth_node_api::FullNodeComponents;
|
||||||
use reth_node_builder::{NodeBuilder, NodeConfig};
|
use reth_node_builder::{NodeBuilder, NodeConfig};
|
||||||
use reth_node_ethereum::EthereumNode;
|
use reth_node_ethereum::{node::EthereumAddOns, EthereumNode};
|
||||||
use std::{
|
use std::{
|
||||||
future::Future,
|
future::Future,
|
||||||
pin::Pin,
|
pin::Pin,
|
||||||
@ -33,6 +33,7 @@ fn basic_exex() {
|
|||||||
.with_database(db)
|
.with_database(db)
|
||||||
.with_types::<EthereumNode>()
|
.with_types::<EthereumNode>()
|
||||||
.with_components(EthereumNode::components())
|
.with_components(EthereumNode::components())
|
||||||
|
.with_add_ons::<EthereumAddOns>()
|
||||||
.install_exex("dummy", move |ctx| future::ok(DummyExEx { _ctx: ctx }))
|
.install_exex("dummy", move |ctx| future::ok(DummyExEx { _ctx: ctx }))
|
||||||
.check_launch();
|
.check_launch();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,7 +28,7 @@ use reth_node_builder::{
|
|||||||
};
|
};
|
||||||
use reth_node_core::node_config::NodeConfig;
|
use reth_node_core::node_config::NodeConfig;
|
||||||
use reth_node_ethereum::{
|
use reth_node_ethereum::{
|
||||||
node::{EthereumNetworkBuilder, EthereumPayloadBuilder},
|
node::{EthereumAddOns, EthereumNetworkBuilder, EthereumPayloadBuilder},
|
||||||
EthEngineTypes, EthEvmConfig,
|
EthEngineTypes, EthEvmConfig,
|
||||||
};
|
};
|
||||||
use reth_payload_builder::noop::NoopPayloadBuilderService;
|
use reth_payload_builder::noop::NoopPayloadBuilderService;
|
||||||
@ -125,8 +125,9 @@ where
|
|||||||
TestExecutorBuilder,
|
TestExecutorBuilder,
|
||||||
TestConsensusBuilder,
|
TestConsensusBuilder,
|
||||||
>;
|
>;
|
||||||
|
type AddOns = EthereumAddOns;
|
||||||
|
|
||||||
fn components_builder(self) -> Self::ComponentsBuilder {
|
fn components_builder(&self) -> Self::ComponentsBuilder {
|
||||||
ComponentsBuilder::default()
|
ComponentsBuilder::default()
|
||||||
.node_types::<N>()
|
.node_types::<N>()
|
||||||
.pool(TestPoolBuilder::default())
|
.pool(TestPoolBuilder::default())
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
//! Traits for configuring a node.
|
//! Traits for configuring a node.
|
||||||
|
|
||||||
use crate::{primitives::NodePrimitives, ConfigureEvm, EngineTypes};
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
use reth_db_api::{
|
use reth_db_api::{
|
||||||
database::Database,
|
database::Database,
|
||||||
database_metrics::{DatabaseMetadata, DatabaseMetrics},
|
database_metrics::{DatabaseMetadata, DatabaseMetrics},
|
||||||
@ -11,7 +12,8 @@ use reth_payload_builder::PayloadBuilderHandle;
|
|||||||
use reth_provider::FullProvider;
|
use reth_provider::FullProvider;
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use reth_transaction_pool::TransactionPool;
|
use reth_transaction_pool::TransactionPool;
|
||||||
use std::marker::PhantomData;
|
|
||||||
|
use crate::{primitives::NodePrimitives, ConfigureEvm, EngineTypes};
|
||||||
|
|
||||||
/// The type that configures the essential types of an ethereum like node.
|
/// The type that configures the essential types of an ethereum like node.
|
||||||
///
|
///
|
||||||
@ -145,3 +147,34 @@ pub trait FullNodeComponents: FullNodeTypes + Clone + 'static {
|
|||||||
/// Returns the task executor.
|
/// Returns the task executor.
|
||||||
fn task_executor(&self) -> &TaskExecutor;
|
fn task_executor(&self) -> &TaskExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Customizable node add-on types.
|
||||||
|
pub trait NodeAddOns<N: FullNodeComponents>: Send + Sync + Unpin + Clone + 'static {
|
||||||
|
/// The core `eth` namespace API type to install on the RPC server (see
|
||||||
|
/// `reth_rpc_eth_api::EthApiServer`).
|
||||||
|
type EthApi: Send + Clone;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: FullNodeComponents> NodeAddOns<N> for () {
|
||||||
|
type EthApi = ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the builder for type.
|
||||||
|
pub trait BuilderProvider<N: FullNodeComponents>: Send {
|
||||||
|
/// Context required to build type.
|
||||||
|
type Ctx<'a>;
|
||||||
|
|
||||||
|
/// Returns builder for type.
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N: FullNodeComponents> BuilderProvider<N> for () {
|
||||||
|
type Ctx<'a> = ();
|
||||||
|
|
||||||
|
fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send> {
|
||||||
|
Box::new(noop_builder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn noop_builder(_: ()) {}
|
||||||
|
|||||||
@ -47,6 +47,7 @@ reth-consensus-debug-client.workspace = true
|
|||||||
reth-rpc-types.workspace = true
|
reth-rpc-types.workspace = true
|
||||||
reth-engine-util.workspace = true
|
reth-engine-util.workspace = true
|
||||||
reth-cli-util.workspace = true
|
reth-cli-util.workspace = true
|
||||||
|
reth-rpc-eth-types.workspace = true
|
||||||
|
|
||||||
## async
|
## async
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
|
|||||||
29
crates/node/builder/src/builder/add_ons.rs
Normal file
29
crates/node/builder/src/builder/add_ons.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
//! Node add-ons. Depend on core [`NodeComponents`](crate::NodeComponents).
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||||
|
|
||||||
|
use crate::{exex::BoxedLaunchExEx, hooks::NodeHooks, rpc::RpcHooks};
|
||||||
|
|
||||||
|
/// Additional node extensions.
|
||||||
|
///
|
||||||
|
/// At this point we consider all necessary components defined.
|
||||||
|
pub struct AddOns<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||||
|
/// Additional `NodeHooks` that are called at specific points in the node's launch lifecycle.
|
||||||
|
pub hooks: NodeHooks<Node, AddOns>,
|
||||||
|
/// The `ExExs` (execution extensions) of the node.
|
||||||
|
pub exexs: Vec<(String, Box<dyn BoxedLaunchExEx<Node>>)>,
|
||||||
|
/// Additional RPC add-ons.
|
||||||
|
pub rpc: RpcAddOns<Node, AddOns::EthApi>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Captures node specific addons that can be installed on top of the type configured node and are
|
||||||
|
/// required for launching the node, such as RPC.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct RpcAddOns<Node: FullNodeComponents, EthApi> {
|
||||||
|
/// Core `eth` API type to install on the RPC server, configured w.r.t. network.
|
||||||
|
pub _eth_api: PhantomData<EthApi>,
|
||||||
|
/// Additional RPC hooks.
|
||||||
|
pub hooks: RpcHooks<Node, EthApi>,
|
||||||
|
}
|
||||||
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
#![allow(clippy::type_complexity, missing_debug_implementations)]
|
#![allow(clippy::type_complexity, missing_debug_implementations)]
|
||||||
|
|
||||||
use crate::{
|
pub mod add_ons;
|
||||||
common::WithConfigs,
|
mod states;
|
||||||
components::NodeComponentsBuilder,
|
|
||||||
node::FullNode,
|
pub use states::*;
|
||||||
rpc::{RethRpcServerHandles, RpcContext},
|
|
||||||
DefaultNodeLauncher, Node, NodeHandle,
|
use std::sync::Arc;
|
||||||
};
|
|
||||||
use futures::Future;
|
use futures::Future;
|
||||||
use reth_chainspec::ChainSpec;
|
use reth_chainspec::ChainSpec;
|
||||||
use reth_cli_util::get_secret_key;
|
use reth_cli_util::get_secret_key;
|
||||||
@ -20,23 +20,28 @@ use reth_exex::ExExContext;
|
|||||||
use reth_network::{
|
use reth_network::{
|
||||||
NetworkBuilder, NetworkConfig, NetworkConfigBuilder, NetworkHandle, NetworkManager,
|
NetworkBuilder, NetworkConfig, NetworkConfigBuilder, NetworkHandle, NetworkManager,
|
||||||
};
|
};
|
||||||
use reth_node_api::{FullNodeTypes, FullNodeTypesAdapter, NodeTypes};
|
use reth_node_api::{FullNodeTypes, FullNodeTypesAdapter, NodeAddOns, NodeTypes};
|
||||||
use reth_node_core::{
|
use reth_node_core::{
|
||||||
cli::config::{PayloadBuilderConfig, RethTransactionPoolConfig},
|
cli::config::{PayloadBuilderConfig, RethTransactionPoolConfig},
|
||||||
dirs::{ChainPath, DataDirPath},
|
dirs::{ChainPath, DataDirPath},
|
||||||
node_config::NodeConfig,
|
node_config::NodeConfig,
|
||||||
primitives::Head,
|
primitives::Head,
|
||||||
|
rpc::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||||
};
|
};
|
||||||
use reth_primitives::revm_primitives::EnvKzgSettings;
|
use reth_primitives::revm_primitives::EnvKzgSettings;
|
||||||
use reth_provider::{providers::BlockchainProvider, ChainSpecProvider};
|
use reth_provider::{providers::BlockchainProvider, ChainSpecProvider};
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use reth_transaction_pool::{PoolConfig, TransactionPool};
|
use reth_transaction_pool::{PoolConfig, TransactionPool};
|
||||||
use secp256k1::SecretKey;
|
use secp256k1::SecretKey;
|
||||||
pub use states::*;
|
|
||||||
use std::sync::Arc;
|
|
||||||
use tracing::{info, trace, warn};
|
use tracing::{info, trace, warn};
|
||||||
|
|
||||||
mod states;
|
use crate::{
|
||||||
|
common::WithConfigs,
|
||||||
|
components::NodeComponentsBuilder,
|
||||||
|
node::FullNode,
|
||||||
|
rpc::{EthApiBuilderProvider, RethRpcServerHandles, RpcContext},
|
||||||
|
DefaultNodeLauncher, Node, NodeHandle,
|
||||||
|
};
|
||||||
|
|
||||||
/// The adapter type for a reth node with the builtin provider type
|
/// The adapter type for a reth node with the builtin provider type
|
||||||
// Note: we need to hardcode this because custom components might depend on it in associated types.
|
// Note: we need to hardcode this because custom components might depend on it in associated types.
|
||||||
@ -212,11 +217,11 @@ where
|
|||||||
pub fn node<N>(
|
pub fn node<N>(
|
||||||
self,
|
self,
|
||||||
node: N,
|
node: N,
|
||||||
) -> NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder>
|
) -> NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>
|
||||||
where
|
where
|
||||||
N: Node<RethFullAdapter<DB, N>>,
|
N: Node<RethFullAdapter<DB, N>>,
|
||||||
{
|
{
|
||||||
self.with_types().with_components(node.components_builder())
|
self.with_types().with_components(node.components_builder()).with_add_ons::<N::AddOns>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,11 +264,13 @@ where
|
|||||||
pub fn node<N>(
|
pub fn node<N>(
|
||||||
self,
|
self,
|
||||||
node: N,
|
node: N,
|
||||||
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder>>
|
) -> WithLaunchContext<
|
||||||
|
NodeBuilderWithComponents<RethFullAdapter<DB, N>, N::ComponentsBuilder, N::AddOns>,
|
||||||
|
>
|
||||||
where
|
where
|
||||||
N: Node<RethFullAdapter<DB, N>>,
|
N: Node<RethFullAdapter<DB, N>>,
|
||||||
{
|
{
|
||||||
self.with_types().with_components(node.components_builder())
|
self.with_types().with_components(node.components_builder()).with_add_ons::<N::AddOns>()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launches a preconfigured [Node]
|
/// Launches a preconfigured [Node]
|
||||||
@ -280,10 +287,22 @@ where
|
|||||||
RethFullAdapter<DB, N>,
|
RethFullAdapter<DB, N>,
|
||||||
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
||||||
>,
|
>,
|
||||||
|
N::AddOns,
|
||||||
>,
|
>,
|
||||||
>
|
>
|
||||||
where
|
where
|
||||||
N: Node<RethFullAdapter<DB, N>>,
|
N: Node<RethFullAdapter<DB, N>>,
|
||||||
|
<N::AddOns as NodeAddOns<
|
||||||
|
NodeAdapter<
|
||||||
|
RethFullAdapter<DB, N>,
|
||||||
|
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
||||||
|
>,
|
||||||
|
>>::EthApi: EthApiBuilderProvider<
|
||||||
|
NodeAdapter<
|
||||||
|
RethFullAdapter<DB, N>,
|
||||||
|
<N::ComponentsBuilder as NodeComponentsBuilder<RethFullAdapter<DB, N>>>::Components,
|
||||||
|
>,
|
||||||
|
> + FullEthApiServer + AddDevSigners,
|
||||||
{
|
{
|
||||||
self.node(node).launch().await
|
self.node(node).launch().await
|
||||||
}
|
}
|
||||||
@ -298,7 +317,7 @@ where
|
|||||||
pub fn with_components<CB>(
|
pub fn with_components<CB>(
|
||||||
self,
|
self,
|
||||||
components_builder: CB,
|
components_builder: CB,
|
||||||
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB>>
|
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, ()>>
|
||||||
where
|
where
|
||||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||||
{
|
{
|
||||||
@ -309,11 +328,35 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, DB, CB> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB>>
|
impl<T, DB, CB> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, ()>>
|
||||||
where
|
where
|
||||||
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
||||||
T: NodeTypes,
|
T: NodeTypes,
|
||||||
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||||
|
{
|
||||||
|
/// Advances the state of the node builder to the next state where all customizable
|
||||||
|
/// [`NodeAddOns`] types are configured.
|
||||||
|
pub fn with_add_ons<AO>(
|
||||||
|
self,
|
||||||
|
) -> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, AO>>
|
||||||
|
where
|
||||||
|
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||||
|
AO: NodeAddOns<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||||
|
{
|
||||||
|
WithLaunchContext {
|
||||||
|
builder: self.builder.with_add_ons::<AO>(),
|
||||||
|
task_executor: self.task_executor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, DB, CB, AO> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, AO>>
|
||||||
|
where
|
||||||
|
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
||||||
|
T: NodeTypes,
|
||||||
|
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||||
|
AO: NodeAddOns<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||||
|
AO::EthApi: FullEthApiServer + AddDevSigners,
|
||||||
{
|
{
|
||||||
/// Sets the hook that is run once the node's components are initialized.
|
/// Sets the hook that is run once the node's components are initialized.
|
||||||
pub fn on_component_initialized<F>(self, hook: F) -> Self
|
pub fn on_component_initialized<F>(self, hook: F) -> Self
|
||||||
@ -332,7 +375,7 @@ where
|
|||||||
pub fn on_node_started<F>(self, hook: F) -> Self
|
pub fn on_node_started<F>(self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(
|
F: FnOnce(
|
||||||
FullNode<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
FullNode<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO>,
|
||||||
) -> eyre::Result<()>
|
) -> eyre::Result<()>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
@ -344,7 +387,7 @@ where
|
|||||||
pub fn on_rpc_started<F>(self, hook: F) -> Self
|
pub fn on_rpc_started<F>(self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(
|
F: FnOnce(
|
||||||
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO::EthApi>,
|
||||||
RethRpcServerHandles,
|
RethRpcServerHandles,
|
||||||
) -> eyre::Result<()>
|
) -> eyre::Result<()>
|
||||||
+ Send
|
+ Send
|
||||||
@ -357,7 +400,7 @@ where
|
|||||||
pub fn extend_rpc_modules<F>(self, hook: F) -> Self
|
pub fn extend_rpc_modules<F>(self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(
|
F: FnOnce(
|
||||||
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
RpcContext<'_, NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO::EthApi>,
|
||||||
) -> eyre::Result<()>
|
) -> eyre::Result<()>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
@ -384,16 +427,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launches the node and returns a handle to it.
|
|
||||||
pub async fn launch(
|
|
||||||
self,
|
|
||||||
) -> eyre::Result<NodeHandle<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>> {
|
|
||||||
let Self { builder, task_executor } = self;
|
|
||||||
|
|
||||||
let launcher = DefaultNodeLauncher::new(task_executor, builder.config.datadir());
|
|
||||||
builder.launch_with(launcher).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Check that the builder can be launched
|
/// Check that the builder can be launched
|
||||||
///
|
///
|
||||||
/// This is useful when writing tests to ensure that the builder is configured correctly.
|
/// This is useful when writing tests to ensure that the builder is configured correctly.
|
||||||
@ -402,6 +435,27 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, DB, CB, AO> WithLaunchContext<NodeBuilderWithComponents<RethFullAdapter<DB, T>, CB, AO>>
|
||||||
|
where
|
||||||
|
DB: Database + DatabaseMetrics + DatabaseMetadata + Clone + Unpin + 'static,
|
||||||
|
T: NodeTypes,
|
||||||
|
CB: NodeComponentsBuilder<RethFullAdapter<DB, T>>,
|
||||||
|
AO: NodeAddOns<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>,
|
||||||
|
AO::EthApi: EthApiBuilderProvider<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>>
|
||||||
|
+ FullEthApiServer
|
||||||
|
+ AddDevSigners,
|
||||||
|
{
|
||||||
|
/// Launches the node with the [`DefaultNodeLauncher`] that sets up engine API consensus and rpc
|
||||||
|
pub async fn launch(
|
||||||
|
self,
|
||||||
|
) -> eyre::Result<NodeHandle<NodeAdapter<RethFullAdapter<DB, T>, CB::Components>, AO>> {
|
||||||
|
let Self { builder, task_executor } = self;
|
||||||
|
|
||||||
|
let launcher = DefaultNodeLauncher::new(task_executor, builder.config.datadir());
|
||||||
|
builder.launch_with(launcher).await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Captures the necessary context for building the components of the node.
|
/// Captures the necessary context for building the components of the node.
|
||||||
pub struct BuilderContext<Node: FullNodeTypes> {
|
pub struct BuilderContext<Node: FullNodeTypes> {
|
||||||
/// The current head of the blockchain at launch.
|
/// The current head of the blockchain at launch.
|
||||||
|
|||||||
@ -5,21 +5,25 @@
|
|||||||
//! The node builder process is essentially a state machine that transitions through various states
|
//! The node builder process is essentially a state machine that transitions through various states
|
||||||
//! before the node can be launched.
|
//! before the node can be launched.
|
||||||
|
|
||||||
use crate::{
|
use std::{fmt, future::Future, marker::PhantomData};
|
||||||
components::{NodeComponents, NodeComponentsBuilder},
|
|
||||||
exex::BoxedLaunchExEx,
|
|
||||||
hooks::NodeHooks,
|
|
||||||
launch::LaunchNode,
|
|
||||||
rpc::{RethRpcServerHandles, RpcContext, RpcHooks},
|
|
||||||
FullNode,
|
|
||||||
};
|
|
||||||
use reth_exex::ExExContext;
|
use reth_exex::ExExContext;
|
||||||
use reth_network::NetworkHandle;
|
use reth_network::NetworkHandle;
|
||||||
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeTypes};
|
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeAddOns, NodeTypes};
|
||||||
use reth_node_core::node_config::NodeConfig;
|
use reth_node_core::{
|
||||||
|
node_config::NodeConfig,
|
||||||
|
rpc::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||||
|
};
|
||||||
use reth_payload_builder::PayloadBuilderHandle;
|
use reth_payload_builder::PayloadBuilderHandle;
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use std::{fmt, future::Future};
|
|
||||||
|
use crate::{
|
||||||
|
components::{NodeComponents, NodeComponentsBuilder},
|
||||||
|
hooks::NodeHooks,
|
||||||
|
launch::LaunchNode,
|
||||||
|
rpc::{EthApiBuilderProvider, RethRpcServerHandles, RpcContext, RpcHooks},
|
||||||
|
AddOns, FullNode, RpcAddOns,
|
||||||
|
};
|
||||||
|
|
||||||
/// A node builder that also has the configured types.
|
/// A node builder that also has the configured types.
|
||||||
pub struct NodeBuilderWithTypes<T: FullNodeTypes> {
|
pub struct NodeBuilderWithTypes<T: FullNodeTypes> {
|
||||||
@ -36,7 +40,7 @@ impl<T: FullNodeTypes> NodeBuilderWithTypes<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Advances the state of the node builder to the next state where all components are configured
|
/// Advances the state of the node builder to the next state where all components are configured
|
||||||
pub fn with_components<CB>(self, components_builder: CB) -> NodeBuilderWithComponents<T, CB>
|
pub fn with_components<CB>(self, components_builder: CB) -> NodeBuilderWithComponents<T, CB, ()>
|
||||||
where
|
where
|
||||||
CB: NodeComponentsBuilder<T>,
|
CB: NodeComponentsBuilder<T>,
|
||||||
{
|
{
|
||||||
@ -46,9 +50,9 @@ impl<T: FullNodeTypes> NodeBuilderWithTypes<T> {
|
|||||||
config,
|
config,
|
||||||
adapter,
|
adapter,
|
||||||
components_builder,
|
components_builder,
|
||||||
add_ons: NodeAddOns {
|
add_ons: AddOns {
|
||||||
hooks: NodeHooks::default(),
|
hooks: NodeHooks::default(),
|
||||||
rpc: RpcHooks::new(),
|
rpc: RpcAddOns { _eth_api: PhantomData::<()>, hooks: RpcHooks::default() },
|
||||||
exexs: Vec::new(),
|
exexs: Vec::new(),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -142,7 +146,11 @@ impl<T: FullNodeTypes, C: NodeComponents<T>> Clone for NodeAdapter<T, C> {
|
|||||||
/// A fully type configured node builder.
|
/// A fully type configured node builder.
|
||||||
///
|
///
|
||||||
/// Supports adding additional addons to the node.
|
/// Supports adding additional addons to the node.
|
||||||
pub struct NodeBuilderWithComponents<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> {
|
pub struct NodeBuilderWithComponents<
|
||||||
|
T: FullNodeTypes,
|
||||||
|
CB: NodeComponentsBuilder<T>,
|
||||||
|
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||||
|
> {
|
||||||
/// All settings for how the node should be configured.
|
/// All settings for how the node should be configured.
|
||||||
pub(crate) config: NodeConfig,
|
pub(crate) config: NodeConfig,
|
||||||
/// Adapter for the underlying node types and database
|
/// Adapter for the underlying node types and database
|
||||||
@ -150,10 +158,41 @@ pub struct NodeBuilderWithComponents<T: FullNodeTypes, CB: NodeComponentsBuilder
|
|||||||
/// container for type specific components
|
/// container for type specific components
|
||||||
pub(crate) components_builder: CB,
|
pub(crate) components_builder: CB,
|
||||||
/// Additional node extensions.
|
/// Additional node extensions.
|
||||||
pub(crate) add_ons: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
pub(crate) add_ons: AddOns<NodeAdapter<T, CB::Components>, AO>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T, CB> {
|
impl<T, CB> NodeBuilderWithComponents<T, CB, ()>
|
||||||
|
where
|
||||||
|
T: FullNodeTypes,
|
||||||
|
CB: NodeComponentsBuilder<T>,
|
||||||
|
{
|
||||||
|
/// Advances the state of the node builder to the next state where all customizable
|
||||||
|
/// [`NodeAddOns`] types are configured.
|
||||||
|
pub fn with_add_ons<AO>(self) -> NodeBuilderWithComponents<T, CB, AO>
|
||||||
|
where
|
||||||
|
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||||
|
{
|
||||||
|
let Self { config, adapter, components_builder, .. } = self;
|
||||||
|
|
||||||
|
NodeBuilderWithComponents {
|
||||||
|
config,
|
||||||
|
adapter,
|
||||||
|
components_builder,
|
||||||
|
add_ons: AddOns {
|
||||||
|
hooks: NodeHooks::default(),
|
||||||
|
rpc: RpcAddOns { _eth_api: PhantomData::<AO::EthApi>, hooks: RpcHooks::default() },
|
||||||
|
exexs: Vec::new(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, CB, AO> NodeBuilderWithComponents<T, CB, AO>
|
||||||
|
where
|
||||||
|
T: FullNodeTypes,
|
||||||
|
CB: NodeComponentsBuilder<T>,
|
||||||
|
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||||
|
{
|
||||||
/// Sets the hook that is run once the node's components are initialized.
|
/// Sets the hook that is run once the node's components are initialized.
|
||||||
pub fn on_component_initialized<F>(mut self, hook: F) -> Self
|
pub fn on_component_initialized<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
@ -166,7 +205,9 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
|||||||
/// Sets the hook that is run once the node has started.
|
/// Sets the hook that is run once the node has started.
|
||||||
pub fn on_node_started<F>(mut self, hook: F) -> Self
|
pub fn on_node_started<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(FullNode<NodeAdapter<T, CB::Components>>) -> eyre::Result<()> + Send + 'static,
|
F: FnOnce(FullNode<NodeAdapter<T, CB::Components>, AO>) -> eyre::Result<()>
|
||||||
|
+ Send
|
||||||
|
+ 'static,
|
||||||
{
|
{
|
||||||
self.add_ons.hooks.set_on_node_started(hook);
|
self.add_ons.hooks.set_on_node_started(hook);
|
||||||
self
|
self
|
||||||
@ -176,24 +217,24 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
|||||||
pub fn on_rpc_started<F>(mut self, hook: F) -> Self
|
pub fn on_rpc_started<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(
|
F: FnOnce(
|
||||||
RpcContext<'_, NodeAdapter<T, CB::Components>>,
|
RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>,
|
||||||
RethRpcServerHandles,
|
RethRpcServerHandles,
|
||||||
) -> eyre::Result<()>
|
) -> eyre::Result<()>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
{
|
{
|
||||||
self.add_ons.rpc.set_on_rpc_started(hook);
|
self.add_ons.rpc.hooks.set_on_rpc_started(hook);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the hook that is run to configure the rpc modules.
|
/// Sets the hook that is run to configure the rpc modules.
|
||||||
pub fn extend_rpc_modules<F>(mut self, hook: F) -> Self
|
pub fn extend_rpc_modules<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: FnOnce(RpcContext<'_, NodeAdapter<T, CB::Components>>) -> eyre::Result<()>
|
F: FnOnce(RpcContext<'_, NodeAdapter<T, CB::Components>, AO::EthApi>) -> eyre::Result<()>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
{
|
{
|
||||||
self.add_ons.rpc.set_extend_rpc_modules(hook);
|
self.add_ons.rpc.hooks.set_extend_rpc_modules(hook);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,14 +253,6 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Launches the node with the given launcher.
|
|
||||||
pub async fn launch_with<L>(self, launcher: L) -> eyre::Result<L::Node>
|
|
||||||
where
|
|
||||||
L: LaunchNode<Self>,
|
|
||||||
{
|
|
||||||
launcher.launch_node(self).await
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Launches the node with the given closure.
|
/// Launches the node with the given closure.
|
||||||
pub fn launch_with_fn<L, R>(self, launcher: L) -> R
|
pub fn launch_with_fn<L, R>(self, launcher: L) -> R
|
||||||
where
|
where
|
||||||
@ -236,12 +269,19 @@ impl<T: FullNodeTypes, CB: NodeComponentsBuilder<T>> NodeBuilderWithComponents<T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional node extensions.
|
impl<T, CB, AO> NodeBuilderWithComponents<T, CB, AO>
|
||||||
pub(crate) struct NodeAddOns<Node: FullNodeComponents> {
|
where
|
||||||
/// Additional `NodeHooks` that are called at specific points in the node's launch lifecycle.
|
T: FullNodeTypes,
|
||||||
pub(crate) hooks: NodeHooks<Node>,
|
CB: NodeComponentsBuilder<T>,
|
||||||
/// Additional RPC hooks.
|
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||||
pub(crate) rpc: RpcHooks<Node>,
|
AO::EthApi:
|
||||||
/// The `ExExs` (execution extensions) of the node.
|
EthApiBuilderProvider<NodeAdapter<T, CB::Components>> + FullEthApiServer + AddDevSigners,
|
||||||
pub(crate) exexs: Vec<(String, Box<dyn BoxedLaunchExEx<Node>>)>,
|
{
|
||||||
|
/// Launches the node with the given launcher.
|
||||||
|
pub async fn launch_with<L>(self, launcher: L) -> eyre::Result<L::Node>
|
||||||
|
where
|
||||||
|
L: LaunchNode<Self>,
|
||||||
|
{
|
||||||
|
launcher.launch_node(self).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
//! A generic [`NodeComponentsBuilder`]
|
//! A generic [`NodeComponentsBuilder`]
|
||||||
|
|
||||||
|
use std::{future::Future, marker::PhantomData};
|
||||||
|
|
||||||
|
use reth_consensus::Consensus;
|
||||||
|
use reth_evm::execute::BlockExecutorProvider;
|
||||||
|
use reth_transaction_pool::TransactionPool;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::{
|
components::{
|
||||||
Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents,
|
Components, ConsensusBuilder, ExecutorBuilder, NetworkBuilder, NodeComponents,
|
||||||
@ -7,10 +13,6 @@ use crate::{
|
|||||||
},
|
},
|
||||||
BuilderContext, ConfigureEvm, FullNodeTypes,
|
BuilderContext, ConfigureEvm, FullNodeTypes,
|
||||||
};
|
};
|
||||||
use reth_consensus::Consensus;
|
|
||||||
use reth_evm::execute::BlockExecutorProvider;
|
|
||||||
use reth_transaction_pool::TransactionPool;
|
|
||||||
use std::{future::Future, marker::PhantomData};
|
|
||||||
|
|
||||||
/// A generic, general purpose and customizable [`NodeComponentsBuilder`] implementation.
|
/// A generic, general purpose and customizable [`NodeComponentsBuilder`] implementation.
|
||||||
///
|
///
|
||||||
|
|||||||
@ -1,25 +1,35 @@
|
|||||||
use crate::node::FullNode;
|
|
||||||
use reth_node_api::FullNodeComponents;
|
|
||||||
use reth_node_core::exit::NodeExitFuture;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||||
|
use reth_node_core::exit::NodeExitFuture;
|
||||||
|
|
||||||
|
use crate::node::FullNode;
|
||||||
|
|
||||||
/// A Handle to the launched node.
|
/// A Handle to the launched node.
|
||||||
#[must_use = "Needs to await the node exit future"]
|
#[must_use = "Needs to await the node exit future"]
|
||||||
pub struct NodeHandle<Node: FullNodeComponents> {
|
pub struct NodeHandle<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||||
/// All node components.
|
/// All node components.
|
||||||
pub node: FullNode<Node>,
|
pub node: FullNode<Node, AddOns>,
|
||||||
/// The exit future of the node.
|
/// The exit future of the node.
|
||||||
pub node_exit_future: NodeExitFuture,
|
pub node_exit_future: NodeExitFuture,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> NodeHandle<Node> {
|
impl<Node, AddOns> NodeHandle<Node, AddOns>
|
||||||
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
/// Waits for the node to exit, if it was configured to exit.
|
/// Waits for the node to exit, if it was configured to exit.
|
||||||
pub async fn wait_for_node_exit(self) -> eyre::Result<()> {
|
pub async fn wait_for_node_exit(self) -> eyre::Result<()> {
|
||||||
self.node_exit_future.await
|
self.node_exit_future.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> fmt::Debug for NodeHandle<Node> {
|
impl<Node, AddOns> fmt::Debug for NodeHandle<Node, AddOns>
|
||||||
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("NodeHandle")
|
f.debug_struct("NodeHandle")
|
||||||
.field("node", &"...")
|
.field("node", &"...")
|
||||||
|
|||||||
@ -1,17 +1,25 @@
|
|||||||
use crate::node::FullNode;
|
|
||||||
use reth_node_api::FullNodeComponents;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||||
|
|
||||||
|
use crate::node::FullNode;
|
||||||
|
|
||||||
/// Container for all the configurable hook functions.
|
/// Container for all the configurable hook functions.
|
||||||
pub(crate) struct NodeHooks<Node: FullNodeComponents> {
|
pub struct NodeHooks<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||||
pub(crate) on_component_initialized: Box<dyn OnComponentInitializedHook<Node>>,
|
/// Hook to run once core components are initialized.
|
||||||
pub(crate) on_node_started: Box<dyn OnNodeStartedHook<Node>>,
|
pub on_component_initialized: Box<dyn OnComponentInitializedHook<Node>>,
|
||||||
pub(crate) _marker: std::marker::PhantomData<Node>,
|
/// Hook to run once the node is started.
|
||||||
|
pub on_node_started: Box<dyn OnNodeStartedHook<Node, AddOns>>,
|
||||||
|
_marker: std::marker::PhantomData<Node>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> NodeHooks<Node> {
|
impl<Node, AddOns> NodeHooks<Node, AddOns>
|
||||||
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
/// Creates a new, empty [`NodeHooks`] instance for the given node type.
|
/// Creates a new, empty [`NodeHooks`] instance for the given node type.
|
||||||
pub(crate) fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
on_component_initialized: Box::<()>::default(),
|
on_component_initialized: Box::<()>::default(),
|
||||||
on_node_started: Box::<()>::default(),
|
on_node_started: Box::<()>::default(),
|
||||||
@ -41,7 +49,7 @@ impl<Node: FullNodeComponents> NodeHooks<Node> {
|
|||||||
/// Sets the hook that is run once the node has started.
|
/// Sets the hook that is run once the node has started.
|
||||||
pub(crate) fn set_on_node_started<F>(&mut self, hook: F) -> &mut Self
|
pub(crate) fn set_on_node_started<F>(&mut self, hook: F) -> &mut Self
|
||||||
where
|
where
|
||||||
F: OnNodeStartedHook<Node> + 'static,
|
F: OnNodeStartedHook<Node, AddOns> + 'static,
|
||||||
{
|
{
|
||||||
self.on_node_started = Box::new(hook);
|
self.on_node_started = Box::new(hook);
|
||||||
self
|
self
|
||||||
@ -51,19 +59,27 @@ impl<Node: FullNodeComponents> NodeHooks<Node> {
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn on_node_started<F>(mut self, hook: F) -> Self
|
pub(crate) fn on_node_started<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: OnNodeStartedHook<Node> + 'static,
|
F: OnNodeStartedHook<Node, AddOns> + 'static,
|
||||||
{
|
{
|
||||||
self.set_on_node_started(hook);
|
self.set_on_node_started(hook);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> Default for NodeHooks<Node> {
|
impl<Node, AddOns> Default for NodeHooks<Node, AddOns>
|
||||||
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Node: FullNodeComponents> fmt::Debug for NodeHooks<Node> {
|
impl<Node, AddOns> fmt::Debug for NodeHooks<Node, AddOns>
|
||||||
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("NodeHooks")
|
f.debug_struct("NodeHooks")
|
||||||
.field("on_component_initialized", &"...")
|
.field("on_component_initialized", &"...")
|
||||||
@ -90,19 +106,20 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A helper trait that is run once the node is started.
|
/// A helper trait that is run once the node is started.
|
||||||
pub trait OnNodeStartedHook<Node: FullNodeComponents>: Send {
|
pub trait OnNodeStartedHook<Node: FullNodeComponents, AddOns: NodeAddOns<Node>>: Send {
|
||||||
/// Consumes the event hook and runs it.
|
/// Consumes the event hook and runs it.
|
||||||
///
|
///
|
||||||
/// If this returns an error, the node launch will be aborted.
|
/// If this returns an error, the node launch will be aborted.
|
||||||
fn on_event(self: Box<Self>, node: FullNode<Node>) -> eyre::Result<()>;
|
fn on_event(self: Box<Self>, node: FullNode<Node, AddOns>) -> eyre::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node, F> OnNodeStartedHook<Node> for F
|
impl<Node, AddOns, F> OnNodeStartedHook<Node, AddOns> for F
|
||||||
where
|
where
|
||||||
Node: FullNodeComponents,
|
Node: FullNodeComponents,
|
||||||
F: FnOnce(FullNode<Node>) -> eyre::Result<()> + Send,
|
AddOns: NodeAddOns<Node>,
|
||||||
|
F: FnOnce(FullNode<Node, AddOns>) -> eyre::Result<()> + Send,
|
||||||
{
|
{
|
||||||
fn on_event(self: Box<Self>, node: FullNode<Node>) -> eyre::Result<()> {
|
fn on_event(self: Box<Self>, node: FullNode<Node, AddOns>) -> eyre::Result<()> {
|
||||||
(*self)(node)
|
(*self)(node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,8 +130,12 @@ impl<Node> OnComponentInitializedHook<Node> for () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> OnNodeStartedHook<Node> for () {
|
impl<Node, AddOns> OnNodeStartedHook<Node, AddOns> for ()
|
||||||
fn on_event(self: Box<Self>, _node: FullNode<Node>) -> eyre::Result<()> {
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
|
fn on_event(self: Box<Self>, _node: FullNode<Node, AddOns>) -> eyre::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
//! Abstraction for launching a node.
|
//! Abstraction for launching a node.
|
||||||
|
|
||||||
use crate::{
|
pub mod common;
|
||||||
builder::{NodeAdapter, NodeAddOns, NodeTypesAdapter},
|
mod exex;
|
||||||
components::{NodeComponents, NodeComponentsBuilder},
|
|
||||||
hooks::NodeHooks,
|
pub use common::LaunchContext;
|
||||||
node::FullNode,
|
pub use exex::ExExLauncher;
|
||||||
NodeBuilderWithComponents, NodeHandle,
|
|
||||||
};
|
use std::{future::Future, sync::Arc};
|
||||||
|
|
||||||
use futures::{future::Either, stream, stream_select, StreamExt};
|
use futures::{future::Either, stream, stream_select, StreamExt};
|
||||||
use reth_beacon_consensus::{
|
use reth_beacon_consensus::{
|
||||||
hooks::{EngineHooks, PruneHook, StaticFileHook},
|
hooks::{EngineHooks, PruneHook, StaticFileHook},
|
||||||
@ -15,11 +16,12 @@ use reth_beacon_consensus::{
|
|||||||
use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider, RpcBlockProvider};
|
use reth_consensus_debug_client::{DebugConsensusClient, EtherscanBlockProvider, RpcBlockProvider};
|
||||||
use reth_engine_util::EngineMessageStreamExt;
|
use reth_engine_util::EngineMessageStreamExt;
|
||||||
use reth_exex::ExExManagerHandle;
|
use reth_exex::ExExManagerHandle;
|
||||||
use reth_network::NetworkEvents;
|
use reth_network::{NetworkEvents, NetworkHandle};
|
||||||
use reth_node_api::FullNodeTypes;
|
use reth_node_api::{FullNodeComponents, FullNodeTypes, NodeAddOns};
|
||||||
use reth_node_core::{
|
use reth_node_core::{
|
||||||
dirs::{ChainPath, DataDirPath},
|
dirs::{ChainPath, DataDirPath},
|
||||||
exit::NodeExitFuture,
|
exit::NodeExitFuture,
|
||||||
|
rpc::eth::{helpers::AddDevSigners, FullEthApiServer},
|
||||||
version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA},
|
version::{CARGO_PKG_VERSION, CLIENT_CODE, NAME_CLIENT, VERGEN_GIT_SHA},
|
||||||
};
|
};
|
||||||
use reth_node_events::{cl::ConsensusLayerHealthEvents, node};
|
use reth_node_events::{cl::ConsensusLayerHealthEvents, node};
|
||||||
@ -30,18 +32,32 @@ use reth_rpc_types::engine::ClientVersionV1;
|
|||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use reth_tracing::tracing::{debug, info};
|
use reth_tracing::tracing::{debug, info};
|
||||||
use reth_transaction_pool::TransactionPool;
|
use reth_transaction_pool::TransactionPool;
|
||||||
use std::{future::Future, sync::Arc};
|
|
||||||
use tokio::sync::{mpsc::unbounded_channel, oneshot};
|
use tokio::sync::{mpsc::unbounded_channel, oneshot};
|
||||||
use tokio_stream::wrappers::UnboundedReceiverStream;
|
use tokio_stream::wrappers::UnboundedReceiverStream;
|
||||||
|
|
||||||
pub mod common;
|
use crate::{
|
||||||
pub use common::LaunchContext;
|
builder::{NodeAdapter, NodeTypesAdapter},
|
||||||
mod exex;
|
components::{NodeComponents, NodeComponentsBuilder},
|
||||||
pub use exex::ExExLauncher;
|
hooks::NodeHooks,
|
||||||
|
node::FullNode,
|
||||||
|
rpc::EthApiBuilderProvider,
|
||||||
|
AddOns, NodeBuilderWithComponents, NodeHandle,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Alias for [`reth_rpc_eth_types::EthApiBuilderCtx`], adapter for [`FullNodeComponents`].
|
||||||
|
pub type EthApiBuilderCtx<N> = reth_rpc_eth_types::EthApiBuilderCtx<
|
||||||
|
<N as FullNodeTypes>::Provider,
|
||||||
|
<N as FullNodeComponents>::Pool,
|
||||||
|
<N as FullNodeComponents>::Evm,
|
||||||
|
NetworkHandle,
|
||||||
|
TaskExecutor,
|
||||||
|
<N as FullNodeTypes>::Provider,
|
||||||
|
>;
|
||||||
|
|
||||||
/// A general purpose trait that launches a new node of any kind.
|
/// A general purpose trait that launches a new node of any kind.
|
||||||
///
|
///
|
||||||
/// Acts as a node factory.
|
/// Acts as a node factory that targets a certain node configuration and returns a handle to the
|
||||||
|
/// node.
|
||||||
///
|
///
|
||||||
/// This is essentially the launch logic for a node.
|
/// This is essentially the launch logic for a node.
|
||||||
///
|
///
|
||||||
@ -80,22 +96,25 @@ impl DefaultNodeLauncher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, CB> LaunchNode<NodeBuilderWithComponents<T, CB>> for DefaultNodeLauncher
|
impl<T, CB, AO> LaunchNode<NodeBuilderWithComponents<T, CB, AO>> for DefaultNodeLauncher
|
||||||
where
|
where
|
||||||
T: FullNodeTypes<Provider = BlockchainProvider<<T as FullNodeTypes>::DB>>,
|
T: FullNodeTypes<Provider = BlockchainProvider<<T as FullNodeTypes>::DB>>,
|
||||||
CB: NodeComponentsBuilder<T>,
|
CB: NodeComponentsBuilder<T>,
|
||||||
|
AO: NodeAddOns<NodeAdapter<T, CB::Components>>,
|
||||||
|
AO::EthApi:
|
||||||
|
EthApiBuilderProvider<NodeAdapter<T, CB::Components>> + FullEthApiServer + AddDevSigners,
|
||||||
{
|
{
|
||||||
type Node = NodeHandle<NodeAdapter<T, CB::Components>>;
|
type Node = NodeHandle<NodeAdapter<T, CB::Components>, AO>;
|
||||||
|
|
||||||
async fn launch_node(
|
async fn launch_node(
|
||||||
self,
|
self,
|
||||||
target: NodeBuilderWithComponents<T, CB>,
|
target: NodeBuilderWithComponents<T, CB, AO>,
|
||||||
) -> eyre::Result<Self::Node> {
|
) -> eyre::Result<Self::Node> {
|
||||||
let Self { ctx } = self;
|
let Self { ctx } = self;
|
||||||
let NodeBuilderWithComponents {
|
let NodeBuilderWithComponents {
|
||||||
adapter: NodeTypesAdapter { database },
|
adapter: NodeTypesAdapter { database },
|
||||||
components_builder,
|
components_builder,
|
||||||
add_ons: NodeAddOns { hooks, rpc, exexs: installed_exex },
|
add_ons: AddOns { hooks, rpc, exexs: installed_exex },
|
||||||
config,
|
config,
|
||||||
} = target;
|
} = target;
|
||||||
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;
|
let NodeHooks { on_component_initialized, on_node_started, .. } = hooks;
|
||||||
|
|||||||
@ -17,9 +17,13 @@ pub use node::*;
|
|||||||
|
|
||||||
/// Support for configuring the components of a node.
|
/// Support for configuring the components of a node.
|
||||||
pub mod components;
|
pub mod components;
|
||||||
|
pub use components::{NodeComponents, NodeComponentsBuilder};
|
||||||
|
|
||||||
mod builder;
|
mod builder;
|
||||||
pub use builder::*;
|
pub use builder::{
|
||||||
|
add_ons::{AddOns, RpcAddOns},
|
||||||
|
*,
|
||||||
|
};
|
||||||
|
|
||||||
mod launch;
|
mod launch;
|
||||||
pub use launch::*;
|
pub use launch::*;
|
||||||
|
|||||||
@ -1,4 +1,8 @@
|
|||||||
use crate::rpc::{RethRpcServerHandles, RpcRegistry};
|
// re-export the node api types
|
||||||
|
pub use reth_node_api::{FullNodeTypes, NodeTypes};
|
||||||
|
|
||||||
|
use std::{marker::PhantomData, sync::Arc};
|
||||||
|
|
||||||
use reth_chainspec::ChainSpec;
|
use reth_chainspec::ChainSpec;
|
||||||
use reth_network::NetworkHandle;
|
use reth_network::NetworkHandle;
|
||||||
use reth_node_api::FullNodeComponents;
|
use reth_node_api::FullNodeComponents;
|
||||||
@ -11,11 +15,12 @@ use reth_payload_builder::PayloadBuilderHandle;
|
|||||||
use reth_provider::ChainSpecProvider;
|
use reth_provider::ChainSpecProvider;
|
||||||
use reth_rpc_builder::{auth::AuthServerHandle, RpcServerHandle};
|
use reth_rpc_builder::{auth::AuthServerHandle, RpcServerHandle};
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use std::{marker::PhantomData, sync::Arc};
|
|
||||||
|
|
||||||
// re-export the node api types
|
use crate::{
|
||||||
use crate::components::NodeComponentsBuilder;
|
components::NodeComponentsBuilder,
|
||||||
pub use reth_node_api::{FullNodeTypes, NodeTypes};
|
rpc::{RethRpcServerHandles, RpcRegistry},
|
||||||
|
NodeAdapter, NodeAddOns,
|
||||||
|
};
|
||||||
|
|
||||||
/// A [`crate::Node`] is a [`NodeTypes`] that comes with preconfigured components.
|
/// A [`crate::Node`] is a [`NodeTypes`] that comes with preconfigured components.
|
||||||
///
|
///
|
||||||
@ -24,45 +29,53 @@ pub trait Node<N: FullNodeTypes>: NodeTypes + Clone {
|
|||||||
/// The type that builds the node's components.
|
/// The type that builds the node's components.
|
||||||
type ComponentsBuilder: NodeComponentsBuilder<N>;
|
type ComponentsBuilder: NodeComponentsBuilder<N>;
|
||||||
|
|
||||||
|
/// Exposes the customizable node add-on types.
|
||||||
|
type AddOns: NodeAddOns<
|
||||||
|
NodeAdapter<N, <Self::ComponentsBuilder as NodeComponentsBuilder<N>>::Components>,
|
||||||
|
>;
|
||||||
|
|
||||||
/// Returns a [`NodeComponentsBuilder`] for the node.
|
/// Returns a [`NodeComponentsBuilder`] for the node.
|
||||||
fn components_builder(self) -> Self::ComponentsBuilder;
|
fn components_builder(&self) -> Self::ComponentsBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [`Node`] type builder
|
/// A [`Node`] type builder
|
||||||
#[derive(Clone, Default, Debug)]
|
#[derive(Clone, Default, Debug)]
|
||||||
pub struct AnyNode<N = (), C = ()>(PhantomData<N>, C);
|
pub struct AnyNode<N = (), C = (), AO = ()>(PhantomData<(N, AO)>, C);
|
||||||
|
|
||||||
impl<N, C> AnyNode<N, C> {
|
impl<N, C> AnyNode<N, C> {
|
||||||
/// Configures the types of the node.
|
/// Configures the types of the node.
|
||||||
pub fn types<T>(self) -> AnyNode<T, C> {
|
pub fn types<T>(self) -> AnyNode<T, C> {
|
||||||
AnyNode::<T, C>(PhantomData::<T>, self.1)
|
AnyNode::<T, C>(PhantomData::<(T, ())>, self.1)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the node components builder.
|
/// Sets the node components builder.
|
||||||
pub fn components_builder<T>(self, value: T) -> AnyNode<N, T> {
|
pub const fn components_builder<T>(&self, value: T) -> AnyNode<N, T> {
|
||||||
AnyNode::<N, T>(PhantomData::<N>, value)
|
AnyNode::<N, T>(PhantomData::<(N, ())>, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, C> NodeTypes for AnyNode<N, C>
|
impl<N, C, AO> NodeTypes for AnyNode<N, C, AO>
|
||||||
where
|
where
|
||||||
N: FullNodeTypes,
|
N: FullNodeTypes,
|
||||||
C: NodeComponentsBuilder<N> + Sync + Unpin + 'static,
|
C: Send + Sync + Unpin + 'static,
|
||||||
|
AO: Send + Sync + Unpin + Clone + 'static,
|
||||||
{
|
{
|
||||||
type Primitives = N::Primitives;
|
type Primitives = N::Primitives;
|
||||||
|
|
||||||
type Engine = N::Engine;
|
type Engine = N::Engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<N, C> Node<N> for AnyNode<N, C>
|
impl<N, C, AO> Node<N> for AnyNode<N, C, AO>
|
||||||
where
|
where
|
||||||
N: FullNodeTypes + Clone,
|
N: FullNodeTypes + Clone,
|
||||||
C: NodeComponentsBuilder<N> + Clone + Sync + Unpin + 'static,
|
C: NodeComponentsBuilder<N> + Clone + Sync + Unpin + 'static,
|
||||||
|
AO: NodeAddOns<NodeAdapter<N, C::Components>>,
|
||||||
{
|
{
|
||||||
type ComponentsBuilder = C;
|
type ComponentsBuilder = C;
|
||||||
|
type AddOns = AO;
|
||||||
|
|
||||||
fn components_builder(self) -> Self::ComponentsBuilder {
|
fn components_builder(&self) -> Self::ComponentsBuilder {
|
||||||
self.1
|
self.1.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +83,7 @@ where
|
|||||||
///
|
///
|
||||||
/// This can be used to interact with the launched node.
|
/// This can be used to interact with the launched node.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct FullNode<Node: FullNodeComponents> {
|
pub struct FullNode<Node: FullNodeComponents, AddOns: NodeAddOns<Node>> {
|
||||||
/// The evm configuration.
|
/// The evm configuration.
|
||||||
pub evm_config: Node::Evm,
|
pub evm_config: Node::Evm,
|
||||||
/// The executor of the node.
|
/// The executor of the node.
|
||||||
@ -88,14 +101,18 @@ pub struct FullNode<Node: FullNodeComponents> {
|
|||||||
/// Handles to the node's rpc servers
|
/// Handles to the node's rpc servers
|
||||||
pub rpc_server_handles: RethRpcServerHandles,
|
pub rpc_server_handles: RethRpcServerHandles,
|
||||||
/// The configured rpc namespaces
|
/// The configured rpc namespaces
|
||||||
pub rpc_registry: RpcRegistry<Node>,
|
pub rpc_registry: RpcRegistry<Node, AddOns::EthApi>,
|
||||||
/// The initial node config.
|
/// The initial node config.
|
||||||
pub config: NodeConfig,
|
pub config: NodeConfig,
|
||||||
/// The data dir of the node.
|
/// The data dir of the node.
|
||||||
pub data_dir: ChainPath<DataDirPath>,
|
pub data_dir: ChainPath<DataDirPath>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> FullNode<Node> {
|
impl<Node, AddOns> FullNode<Node, AddOns>
|
||||||
|
where
|
||||||
|
Node: FullNodeComponents,
|
||||||
|
AddOns: NodeAddOns<Node>,
|
||||||
|
{
|
||||||
/// Returns the [`ChainSpec`] of the node.
|
/// Returns the [`ChainSpec`] of the node.
|
||||||
pub fn chain_spec(&self) -> Arc<ChainSpec> {
|
pub fn chain_spec(&self) -> Arc<ChainSpec> {
|
||||||
self.provider.chain_spec()
|
self.provider.chain_spec()
|
||||||
|
|||||||
@ -7,19 +7,23 @@ use std::{
|
|||||||
|
|
||||||
use futures::TryFutureExt;
|
use futures::TryFutureExt;
|
||||||
use reth_network::NetworkHandle;
|
use reth_network::NetworkHandle;
|
||||||
use reth_node_api::FullNodeComponents;
|
use reth_node_api::{BuilderProvider, FullNodeComponents};
|
||||||
use reth_node_core::{node_config::NodeConfig, rpc::api::EngineApiServer};
|
use reth_node_core::{
|
||||||
|
node_config::NodeConfig,
|
||||||
|
rpc::{api::EngineApiServer, eth::FullEthApiServer},
|
||||||
|
};
|
||||||
use reth_payload_builder::PayloadBuilderHandle;
|
use reth_payload_builder::PayloadBuilderHandle;
|
||||||
use reth_rpc::eth::EthApi;
|
|
||||||
use reth_rpc_builder::{
|
use reth_rpc_builder::{
|
||||||
auth::{AuthRpcModule, AuthServerHandle},
|
auth::{AuthRpcModule, AuthServerHandle},
|
||||||
config::RethRpcServerConfig,
|
config::RethRpcServerConfig,
|
||||||
EthApiBuild, RpcModuleBuilder, RpcRegistryInner, RpcServerHandle, TransportRpcModules,
|
RpcModuleBuilder, RpcRegistryInner, RpcServerHandle, TransportRpcModules,
|
||||||
};
|
};
|
||||||
use reth_rpc_layer::JwtSecret;
|
use reth_rpc_layer::JwtSecret;
|
||||||
use reth_tasks::TaskExecutor;
|
use reth_tasks::TaskExecutor;
|
||||||
use reth_tracing::tracing::{debug, info};
|
use reth_tracing::tracing::{debug, info};
|
||||||
|
|
||||||
|
use crate::{EthApiBuilderCtx, RpcAddOns};
|
||||||
|
|
||||||
/// Contains the handles to the spawned RPC servers.
|
/// Contains the handles to the spawned RPC servers.
|
||||||
///
|
///
|
||||||
/// This can be used to access the endpoints of the servers.
|
/// This can be used to access the endpoints of the servers.
|
||||||
@ -32,21 +36,24 @@ pub struct RethRpcServerHandles {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Contains hooks that are called during the rpc setup.
|
/// Contains hooks that are called during the rpc setup.
|
||||||
pub(crate) struct RpcHooks<Node: FullNodeComponents> {
|
pub struct RpcHooks<Node: FullNodeComponents, EthApi> {
|
||||||
pub(crate) on_rpc_started: Box<dyn OnRpcStarted<Node>>,
|
/// Hooks to run once RPC server is running.
|
||||||
pub(crate) extend_rpc_modules: Box<dyn ExtendRpcModules<Node>>,
|
pub on_rpc_started: Box<dyn OnRpcStarted<Node, EthApi>>,
|
||||||
|
/// Hooks to run to configure RPC server API.
|
||||||
|
pub extend_rpc_modules: Box<dyn ExtendRpcModules<Node, EthApi>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> RpcHooks<Node> {
|
impl<Node: FullNodeComponents, EthApi> Default for RpcHooks<Node, EthApi> {
|
||||||
/// Creates a new, empty [`RpcHooks`] instance for the given node type.
|
fn default() -> Self {
|
||||||
pub(crate) fn new() -> Self {
|
|
||||||
Self { on_rpc_started: Box::<()>::default(), extend_rpc_modules: Box::<()>::default() }
|
Self { on_rpc_started: Box::<()>::default(), extend_rpc_modules: Box::<()>::default() }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Node: FullNodeComponents, EthApi> RpcHooks<Node, EthApi> {
|
||||||
/// Sets the hook that is run once the rpc server is started.
|
/// Sets the hook that is run once the rpc server is started.
|
||||||
pub(crate) fn set_on_rpc_started<F>(&mut self, hook: F) -> &mut Self
|
pub(crate) fn set_on_rpc_started<F>(&mut self, hook: F) -> &mut Self
|
||||||
where
|
where
|
||||||
F: OnRpcStarted<Node> + 'static,
|
F: OnRpcStarted<Node, EthApi> + 'static,
|
||||||
{
|
{
|
||||||
self.on_rpc_started = Box::new(hook);
|
self.on_rpc_started = Box::new(hook);
|
||||||
self
|
self
|
||||||
@ -56,7 +63,7 @@ impl<Node: FullNodeComponents> RpcHooks<Node> {
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn on_rpc_started<F>(mut self, hook: F) -> Self
|
pub(crate) fn on_rpc_started<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: OnRpcStarted<Node> + 'static,
|
F: OnRpcStarted<Node, EthApi> + 'static,
|
||||||
{
|
{
|
||||||
self.set_on_rpc_started(hook);
|
self.set_on_rpc_started(hook);
|
||||||
self
|
self
|
||||||
@ -65,7 +72,7 @@ impl<Node: FullNodeComponents> RpcHooks<Node> {
|
|||||||
/// Sets the hook that is run to configure the rpc modules.
|
/// Sets the hook that is run to configure the rpc modules.
|
||||||
pub(crate) fn set_extend_rpc_modules<F>(&mut self, hook: F) -> &mut Self
|
pub(crate) fn set_extend_rpc_modules<F>(&mut self, hook: F) -> &mut Self
|
||||||
where
|
where
|
||||||
F: ExtendRpcModules<Node> + 'static,
|
F: ExtendRpcModules<Node, EthApi> + 'static,
|
||||||
{
|
{
|
||||||
self.extend_rpc_modules = Box::new(hook);
|
self.extend_rpc_modules = Box::new(hook);
|
||||||
self
|
self
|
||||||
@ -75,14 +82,14 @@ impl<Node: FullNodeComponents> RpcHooks<Node> {
|
|||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub(crate) fn extend_rpc_modules<F>(mut self, hook: F) -> Self
|
pub(crate) fn extend_rpc_modules<F>(mut self, hook: F) -> Self
|
||||||
where
|
where
|
||||||
F: ExtendRpcModules<Node> + 'static,
|
F: ExtendRpcModules<Node, EthApi> + 'static,
|
||||||
{
|
{
|
||||||
self.set_extend_rpc_modules(hook);
|
self.set_extend_rpc_modules(hook);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> fmt::Debug for RpcHooks<Node> {
|
impl<Node: FullNodeComponents, EthApi> fmt::Debug for RpcHooks<Node, EthApi> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("RpcHooks")
|
f.debug_struct("RpcHooks")
|
||||||
.field("on_rpc_started", &"...")
|
.field("on_rpc_started", &"...")
|
||||||
@ -92,33 +99,33 @@ impl<Node: FullNodeComponents> fmt::Debug for RpcHooks<Node> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Event hook that is called once the rpc server is started.
|
/// Event hook that is called once the rpc server is started.
|
||||||
pub trait OnRpcStarted<Node: FullNodeComponents>: Send {
|
pub trait OnRpcStarted<Node: FullNodeComponents, EthApi>: Send {
|
||||||
/// The hook that is called once the rpc server is started.
|
/// The hook that is called once the rpc server is started.
|
||||||
fn on_rpc_started(
|
fn on_rpc_started(
|
||||||
self: Box<Self>,
|
self: Box<Self>,
|
||||||
ctx: RpcContext<'_, Node>,
|
ctx: RpcContext<'_, Node, EthApi>,
|
||||||
handles: RethRpcServerHandles,
|
handles: RethRpcServerHandles,
|
||||||
) -> eyre::Result<()>;
|
) -> eyre::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node, F> OnRpcStarted<Node> for F
|
impl<Node, EthApi, F> OnRpcStarted<Node, EthApi> for F
|
||||||
where
|
where
|
||||||
F: FnOnce(RpcContext<'_, Node>, RethRpcServerHandles) -> eyre::Result<()> + Send,
|
F: FnOnce(RpcContext<'_, Node, EthApi>, RethRpcServerHandles) -> eyre::Result<()> + Send,
|
||||||
Node: FullNodeComponents,
|
Node: FullNodeComponents,
|
||||||
{
|
{
|
||||||
fn on_rpc_started(
|
fn on_rpc_started(
|
||||||
self: Box<Self>,
|
self: Box<Self>,
|
||||||
ctx: RpcContext<'_, Node>,
|
ctx: RpcContext<'_, Node, EthApi>,
|
||||||
handles: RethRpcServerHandles,
|
handles: RethRpcServerHandles,
|
||||||
) -> eyre::Result<()> {
|
) -> eyre::Result<()> {
|
||||||
(*self)(ctx, handles)
|
(*self)(ctx, handles)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> OnRpcStarted<Node> for () {
|
impl<Node: FullNodeComponents, EthApi> OnRpcStarted<Node, EthApi> for () {
|
||||||
fn on_rpc_started(
|
fn on_rpc_started(
|
||||||
self: Box<Self>,
|
self: Box<Self>,
|
||||||
_: RpcContext<'_, Node>,
|
_: RpcContext<'_, Node, EthApi>,
|
||||||
_: RethRpcServerHandles,
|
_: RethRpcServerHandles,
|
||||||
) -> eyre::Result<()> {
|
) -> eyre::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -126,49 +133,49 @@ impl<Node: FullNodeComponents> OnRpcStarted<Node> for () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Event hook that is called when the rpc server is started.
|
/// Event hook that is called when the rpc server is started.
|
||||||
pub trait ExtendRpcModules<Node: FullNodeComponents>: Send {
|
pub trait ExtendRpcModules<Node: FullNodeComponents, EthApi>: Send {
|
||||||
/// The hook that is called once the rpc server is started.
|
/// The hook that is called once the rpc server is started.
|
||||||
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node>) -> eyre::Result<()>;
|
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node, EthApi>) -> eyre::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node, F> ExtendRpcModules<Node> for F
|
impl<Node, EthApi, F> ExtendRpcModules<Node, EthApi> for F
|
||||||
where
|
where
|
||||||
F: FnOnce(RpcContext<'_, Node>) -> eyre::Result<()> + Send,
|
F: FnOnce(RpcContext<'_, Node, EthApi>) -> eyre::Result<()> + Send,
|
||||||
Node: FullNodeComponents,
|
Node: FullNodeComponents,
|
||||||
{
|
{
|
||||||
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node>) -> eyre::Result<()> {
|
fn extend_rpc_modules(self: Box<Self>, ctx: RpcContext<'_, Node, EthApi>) -> eyre::Result<()> {
|
||||||
(*self)(ctx)
|
(*self)(ctx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> ExtendRpcModules<Node> for () {
|
impl<Node: FullNodeComponents, EthApi> ExtendRpcModules<Node, EthApi> for () {
|
||||||
fn extend_rpc_modules(self: Box<Self>, _: RpcContext<'_, Node>) -> eyre::Result<()> {
|
fn extend_rpc_modules(self: Box<Self>, _: RpcContext<'_, Node, EthApi>) -> eyre::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper wrapper type to encapsulate the [`RpcRegistryInner`] over components trait.
|
/// Helper wrapper type to encapsulate the [`RpcRegistryInner`] over components trait.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub struct RpcRegistry<Node: FullNodeComponents> {
|
pub struct RpcRegistry<Node: FullNodeComponents, EthApi> {
|
||||||
pub(crate) registry: RpcRegistryInner<
|
pub(crate) registry: RpcRegistryInner<
|
||||||
Node::Provider,
|
Node::Provider,
|
||||||
Node::Pool,
|
Node::Pool,
|
||||||
NetworkHandle,
|
NetworkHandle,
|
||||||
TaskExecutor,
|
TaskExecutor,
|
||||||
Node::Provider,
|
Node::Provider,
|
||||||
EthApi<Node::Provider, Node::Pool, NetworkHandle, Node::Evm>,
|
EthApi,
|
||||||
>,
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> Deref for RpcRegistry<Node> {
|
impl<Node: FullNodeComponents, EthApi> Deref for RpcRegistry<Node, EthApi> {
|
||||||
type Target = RpcRegistryInner<
|
type Target = RpcRegistryInner<
|
||||||
Node::Provider,
|
Node::Provider,
|
||||||
Node::Pool,
|
Node::Pool,
|
||||||
NetworkHandle,
|
NetworkHandle,
|
||||||
TaskExecutor,
|
TaskExecutor,
|
||||||
Node::Provider,
|
Node::Provider,
|
||||||
EthApi<Node::Provider, Node::Pool, NetworkHandle, Node::Evm>,
|
EthApi,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -176,18 +183,12 @@ impl<Node: FullNodeComponents> Deref for RpcRegistry<Node> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> DerefMut for RpcRegistry<Node> {
|
impl<Node: FullNodeComponents, EthApi> DerefMut for RpcRegistry<Node, EthApi> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.registry
|
&mut self.registry
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Node: FullNodeComponents> Clone for RpcRegistry<Node> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
Self { registry: self.registry.clone() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper container to encapsulate [`RpcRegistryInner`], [`TransportRpcModules`] and
|
/// Helper container to encapsulate [`RpcRegistryInner`], [`TransportRpcModules`] and
|
||||||
/// [`AuthRpcModule`].
|
/// [`AuthRpcModule`].
|
||||||
///
|
///
|
||||||
@ -196,7 +197,7 @@ impl<Node: FullNodeComponents> Clone for RpcRegistry<Node> {
|
|||||||
/// transport modules [`TransportRpcModules`] as well as configured authenticated methods
|
/// transport modules [`TransportRpcModules`] as well as configured authenticated methods
|
||||||
/// [`AuthRpcModule`].
|
/// [`AuthRpcModule`].
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct RpcContext<'a, Node: FullNodeComponents> {
|
pub struct RpcContext<'a, Node: FullNodeComponents, EthApi> {
|
||||||
/// The node components.
|
/// The node components.
|
||||||
pub(crate) node: Node,
|
pub(crate) node: Node,
|
||||||
|
|
||||||
@ -206,7 +207,7 @@ pub struct RpcContext<'a, Node: FullNodeComponents> {
|
|||||||
/// A Helper type the holds instances of the configured modules.
|
/// A Helper type the holds instances of the configured modules.
|
||||||
///
|
///
|
||||||
/// This provides easy access to rpc handlers, such as [`RpcRegistryInner::eth_api`].
|
/// This provides easy access to rpc handlers, such as [`RpcRegistryInner::eth_api`].
|
||||||
pub registry: &'a mut RpcRegistry<Node>,
|
pub registry: &'a mut RpcRegistry<Node, EthApi>,
|
||||||
/// Holds installed modules per transport type.
|
/// Holds installed modules per transport type.
|
||||||
///
|
///
|
||||||
/// This can be used to merge additional modules into the configured transports (http, ipc,
|
/// This can be used to merge additional modules into the configured transports (http, ipc,
|
||||||
@ -218,7 +219,7 @@ pub struct RpcContext<'a, Node: FullNodeComponents> {
|
|||||||
pub auth_module: &'a mut AuthRpcModule,
|
pub auth_module: &'a mut AuthRpcModule,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Node: FullNodeComponents> RpcContext<'a, Node> {
|
impl<'a, Node: FullNodeComponents, EthApi> RpcContext<'a, Node, EthApi> {
|
||||||
/// Returns the config of the node.
|
/// Returns the config of the node.
|
||||||
pub const fn config(&self) -> &NodeConfig {
|
pub const fn config(&self) -> &NodeConfig {
|
||||||
self.config
|
self.config
|
||||||
@ -251,19 +252,18 @@ impl<'a, Node: FullNodeComponents> RpcContext<'a, Node> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Launch the rpc servers.
|
/// Launch the rpc servers.
|
||||||
pub(crate) async fn launch_rpc_servers<Node, Engine>(
|
pub(crate) async fn launch_rpc_servers<Node, Engine, EthApi>(
|
||||||
node: Node,
|
node: Node,
|
||||||
engine_api: Engine,
|
engine_api: Engine,
|
||||||
config: &NodeConfig,
|
config: &NodeConfig,
|
||||||
jwt_secret: JwtSecret,
|
jwt_secret: JwtSecret,
|
||||||
hooks: RpcHooks<Node>,
|
add_ons: RpcAddOns<Node, EthApi>,
|
||||||
) -> eyre::Result<(RethRpcServerHandles, RpcRegistry<Node>)>
|
) -> eyre::Result<(RethRpcServerHandles, RpcRegistry<Node, EthApi>)>
|
||||||
where
|
where
|
||||||
|
EthApi: EthApiBuilderProvider<Node> + FullEthApiServer,
|
||||||
Node: FullNodeComponents + Clone,
|
Node: FullNodeComponents + Clone,
|
||||||
Engine: EngineApiServer<Node::Engine>,
|
Engine: EngineApiServer<Node::Engine>,
|
||||||
{
|
{
|
||||||
let RpcHooks { on_rpc_started, extend_rpc_modules } = hooks;
|
|
||||||
|
|
||||||
let auth_config = config.rpc.auth_server_config(jwt_secret)?;
|
let auth_config = config.rpc.auth_server_config(jwt_secret)?;
|
||||||
let module_config = config.rpc.transport_rpc_module_config();
|
let module_config = config.rpc.transport_rpc_module_config();
|
||||||
debug!(target: "reth::cli", http=?module_config.http(), ws=?module_config.ws(), "Using RPC module config");
|
debug!(target: "reth::cli", http=?module_config.http(), ws=?module_config.ws(), "Using RPC module config");
|
||||||
@ -275,7 +275,7 @@ where
|
|||||||
.with_events(node.provider().clone())
|
.with_events(node.provider().clone())
|
||||||
.with_executor(node.task_executor().clone())
|
.with_executor(node.task_executor().clone())
|
||||||
.with_evm_config(node.evm_config().clone())
|
.with_evm_config(node.evm_config().clone())
|
||||||
.build_with_auth_server(module_config, engine_api, EthApiBuild::build);
|
.build_with_auth_server(module_config, engine_api, EthApi::eth_api_builder());
|
||||||
|
|
||||||
let mut registry = RpcRegistry { registry };
|
let mut registry = RpcRegistry { registry };
|
||||||
let ctx = RpcContext {
|
let ctx = RpcContext {
|
||||||
@ -286,6 +286,9 @@ where
|
|||||||
auth_module: &mut auth_module,
|
auth_module: &mut auth_module,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let RpcAddOns { hooks, .. } = add_ons;
|
||||||
|
let RpcHooks { on_rpc_started, extend_rpc_modules } = hooks;
|
||||||
|
|
||||||
extend_rpc_modules.extend_rpc_modules(ctx)?;
|
extend_rpc_modules.extend_rpc_modules(ctx)?;
|
||||||
|
|
||||||
let server_config = config.rpc.rpc_server_config();
|
let server_config = config.rpc.rpc_server_config();
|
||||||
@ -329,3 +332,20 @@ where
|
|||||||
|
|
||||||
Ok((handles, registry))
|
Ok((handles, registry))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Provides builder for the core `eth` API type.
|
||||||
|
pub trait EthApiBuilderProvider<N: FullNodeComponents>: BuilderProvider<N> {
|
||||||
|
/// Returns the eth api builder.
|
||||||
|
#[allow(clippy::type_complexity)]
|
||||||
|
fn eth_api_builder() -> Box<dyn Fn(&EthApiBuilderCtx<N>) -> Self + Send>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, F> EthApiBuilderProvider<N> for F
|
||||||
|
where
|
||||||
|
N: FullNodeComponents,
|
||||||
|
for<'a> F: BuilderProvider<N, Ctx<'a> = &'a EthApiBuilderCtx<N>>,
|
||||||
|
{
|
||||||
|
fn eth_api_builder() -> Box<dyn Fn(&EthApiBuilderCtx<N>) -> Self + Send> {
|
||||||
|
F::builder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -37,6 +37,8 @@ revm-primitives.workspace = true
|
|||||||
reth-discv5.workspace = true
|
reth-discv5.workspace = true
|
||||||
reth-rpc-eth-types.workspace = true
|
reth-rpc-eth-types.workspace = true
|
||||||
reth-rpc-eth-api.workspace = true
|
reth-rpc-eth-api.workspace = true
|
||||||
|
reth-optimism-rpc.workspace = true
|
||||||
|
reth-tasks.workspace = true
|
||||||
|
|
||||||
# async
|
# async
|
||||||
async-trait.workspace = true
|
async-trait.workspace = true
|
||||||
@ -78,6 +80,7 @@ optimism = [
|
|||||||
"reth-beacon-consensus/optimism",
|
"reth-beacon-consensus/optimism",
|
||||||
"reth-revm/optimism",
|
"reth-revm/optimism",
|
||||||
"reth-auto-seal-consensus/optimism",
|
"reth-auto-seal-consensus/optimism",
|
||||||
"reth-rpc-eth-types/optimism"
|
"reth-rpc-eth-types/optimism",
|
||||||
|
"reth-optimism-rpc/optimism"
|
||||||
]
|
]
|
||||||
test-utils = ["reth-node-builder/test-utils"]
|
test-utils = ["reth-node-builder/test-utils"]
|
||||||
|
|||||||
@ -1,14 +1,12 @@
|
|||||||
//! Optimism Node types config.
|
//! Optimism Node types config.
|
||||||
|
|
||||||
use crate::{
|
use std::sync::Arc;
|
||||||
args::RollupArgs,
|
|
||||||
txpool::{OpTransactionPool, OpTransactionValidator},
|
|
||||||
OptimismEngineTypes,
|
|
||||||
};
|
|
||||||
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
|
use reth_basic_payload_builder::{BasicPayloadJobGenerator, BasicPayloadJobGeneratorConfig};
|
||||||
use reth_evm::ConfigureEvm;
|
use reth_evm::ConfigureEvm;
|
||||||
use reth_evm_optimism::{OpExecutorProvider, OptimismEvmConfig};
|
use reth_evm_optimism::{OpExecutorProvider, OptimismEvmConfig};
|
||||||
use reth_network::{NetworkHandle, NetworkManager};
|
use reth_network::{NetworkHandle, NetworkManager};
|
||||||
|
use reth_node_api::{FullNodeComponents, NodeAddOns};
|
||||||
use reth_node_builder::{
|
use reth_node_builder::{
|
||||||
components::{
|
components::{
|
||||||
ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder,
|
ComponentsBuilder, ConsensusBuilder, ExecutorBuilder, NetworkBuilder,
|
||||||
@ -18,14 +16,21 @@ use reth_node_builder::{
|
|||||||
BuilderContext, Node, PayloadBuilderConfig,
|
BuilderContext, Node, PayloadBuilderConfig,
|
||||||
};
|
};
|
||||||
use reth_optimism_consensus::OptimismBeaconConsensus;
|
use reth_optimism_consensus::OptimismBeaconConsensus;
|
||||||
|
use reth_optimism_rpc::OpEthApi;
|
||||||
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
|
use reth_payload_builder::{PayloadBuilderHandle, PayloadBuilderService};
|
||||||
use reth_provider::CanonStateSubscriptions;
|
use reth_provider::CanonStateSubscriptions;
|
||||||
|
use reth_rpc::EthApi;
|
||||||
use reth_tracing::tracing::{debug, info};
|
use reth_tracing::tracing::{debug, info};
|
||||||
use reth_transaction_pool::{
|
use reth_transaction_pool::{
|
||||||
blobstore::DiskFileBlobStore, CoinbaseTipOrdering, TransactionPool,
|
blobstore::DiskFileBlobStore, CoinbaseTipOrdering, TransactionPool,
|
||||||
TransactionValidationTaskExecutor,
|
TransactionValidationTaskExecutor,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
|
||||||
|
use crate::{
|
||||||
|
args::RollupArgs,
|
||||||
|
txpool::{OpTransactionPool, OpTransactionValidator},
|
||||||
|
OptimismEngineTypes,
|
||||||
|
};
|
||||||
|
|
||||||
/// Type configuration for a regular Optimism node.
|
/// Type configuration for a regular Optimism node.
|
||||||
#[derive(Debug, Default, Clone)]
|
#[derive(Debug, Default, Clone)]
|
||||||
@ -82,9 +87,11 @@ where
|
|||||||
OptimismConsensusBuilder,
|
OptimismConsensusBuilder,
|
||||||
>;
|
>;
|
||||||
|
|
||||||
fn components_builder(self) -> Self::ComponentsBuilder {
|
type AddOns = OptimismAddOns;
|
||||||
|
|
||||||
|
fn components_builder(&self) -> Self::ComponentsBuilder {
|
||||||
let Self { args } = self;
|
let Self { args } = self;
|
||||||
Self::components(args)
|
Self::components(args.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +100,14 @@ impl NodeTypes for OptimismNode {
|
|||||||
type Engine = OptimismEngineTypes;
|
type Engine = OptimismEngineTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add-ons w.r.t. optimism.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct OptimismAddOns;
|
||||||
|
|
||||||
|
impl<N: FullNodeComponents> NodeAddOns<N> for OptimismAddOns {
|
||||||
|
type EthApi = OpEthApi<EthApi<N::Provider, N::Pool, NetworkHandle, N::Evm>>;
|
||||||
|
}
|
||||||
|
|
||||||
/// A regular optimism evm and executor builder.
|
/// A regular optimism evm and executor builder.
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
|
|||||||
@ -1,15 +1,18 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use alloy_genesis::Genesis;
|
use alloy_genesis::Genesis;
|
||||||
use reth::{rpc::types::engine::PayloadAttributes, tasks::TaskManager};
|
use reth::{rpc::types::engine::PayloadAttributes, tasks::TaskManager};
|
||||||
use reth_chainspec::{ChainSpecBuilder, BASE_MAINNET};
|
use reth_chainspec::{ChainSpecBuilder, BASE_MAINNET};
|
||||||
use reth_e2e_test_utils::{transaction::TransactionTestContext, wallet::Wallet, NodeHelperType};
|
use reth_e2e_test_utils::{transaction::TransactionTestContext, wallet::Wallet, NodeHelperType};
|
||||||
use reth_node_optimism::{OptimismBuiltPayload, OptimismNode, OptimismPayloadBuilderAttributes};
|
use reth_node_optimism::{
|
||||||
|
node::OptimismAddOns, OptimismBuiltPayload, OptimismNode, OptimismPayloadBuilderAttributes,
|
||||||
|
};
|
||||||
use reth_payload_builder::EthPayloadBuilderAttributes;
|
use reth_payload_builder::EthPayloadBuilderAttributes;
|
||||||
use reth_primitives::{Address, B256};
|
use reth_primitives::{Address, B256};
|
||||||
use std::sync::Arc;
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
/// Optimism Node Helper type
|
/// Optimism Node Helper type
|
||||||
pub(crate) type OpNode = NodeHelperType<OptimismNode>;
|
pub(crate) type OpNode = NodeHelperType<OptimismNode, OptimismAddOns>;
|
||||||
|
|
||||||
pub(crate) async fn setup(num_nodes: usize) -> eyre::Result<(Vec<OpNode>, TaskManager, Wallet)> {
|
pub(crate) async fn setup(num_nodes: usize) -> eyre::Result<(Vec<OpNode>, TaskManager, Wallet)> {
|
||||||
let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap();
|
let genesis: Genesis = serde_json::from_str(include_str!("../assets/genesis.json")).unwrap();
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
use reth_db::test_utils::create_test_rw_db;
|
use reth_db::test_utils::create_test_rw_db;
|
||||||
use reth_node_api::FullNodeComponents;
|
use reth_node_api::FullNodeComponents;
|
||||||
use reth_node_builder::{NodeBuilder, NodeConfig};
|
use reth_node_builder::{NodeBuilder, NodeConfig};
|
||||||
use reth_node_optimism::node::OptimismNode;
|
use reth_node_optimism::node::{OptimismAddOns, OptimismNode};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic_setup() {
|
fn test_basic_setup() {
|
||||||
@ -14,6 +14,7 @@ fn test_basic_setup() {
|
|||||||
.with_database(db)
|
.with_database(db)
|
||||||
.with_types::<OptimismNode>()
|
.with_types::<OptimismNode>()
|
||||||
.with_components(OptimismNode::components(Default::default()))
|
.with_components(OptimismNode::components(Default::default()))
|
||||||
|
.with_add_ons::<OptimismAddOns>()
|
||||||
.on_component_initialized(move |ctx| {
|
.on_component_initialized(move |ctx| {
|
||||||
let _provider = ctx.provider();
|
let _provider = ctx.provider();
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -25,6 +25,8 @@ reth-rpc-server-types.workspace = true
|
|||||||
reth-rpc-types.workspace = true
|
reth-rpc-types.workspace = true
|
||||||
reth-tasks = { workspace = true, features = ["rayon"] }
|
reth-tasks = { workspace = true, features = ["rayon"] }
|
||||||
reth-transaction-pool.workspace = true
|
reth-transaction-pool.workspace = true
|
||||||
|
reth-rpc.workspace = true
|
||||||
|
reth-node-api.workspace = true
|
||||||
|
|
||||||
# ethereum
|
# ethereum
|
||||||
alloy-primitives.workspace = true
|
alloy-primitives.workspace = true
|
||||||
|
|||||||
@ -12,9 +12,15 @@ use alloy_primitives::{Address, U64};
|
|||||||
use reth_chainspec::{ChainInfo, ChainSpec};
|
use reth_chainspec::{ChainInfo, ChainSpec};
|
||||||
use reth_errors::RethResult;
|
use reth_errors::RethResult;
|
||||||
use reth_evm::ConfigureEvm;
|
use reth_evm::ConfigureEvm;
|
||||||
|
use reth_node_api::{BuilderProvider, FullNodeComponents};
|
||||||
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProviderFactory};
|
use reth_provider::{BlockReaderIdExt, ChainSpecProvider, HeaderProvider, StateProviderFactory};
|
||||||
use reth_rpc_eth_api::helpers::{
|
use reth_rpc::eth::DevSigner;
|
||||||
Call, EthApiSpec, EthCall, EthFees, EthState, LoadFee, LoadState, SpawnBlocking, Trace,
|
use reth_rpc_eth_api::{
|
||||||
|
helpers::{
|
||||||
|
AddDevSigners, Call, EthApiSpec, EthCall, EthFees, EthSigner, EthState, LoadFee, LoadState,
|
||||||
|
SpawnBlocking, Trace, UpdateRawTxForwarder,
|
||||||
|
},
|
||||||
|
RawTransactionForwarder,
|
||||||
};
|
};
|
||||||
use reth_rpc_eth_types::EthStateCache;
|
use reth_rpc_eth_types::EthStateCache;
|
||||||
use reth_rpc_types::SyncStatus;
|
use reth_rpc_types::SyncStatus;
|
||||||
@ -154,3 +160,31 @@ impl<Eth: Trace> Trace for OpEthApi<Eth> {
|
|||||||
self.inner.evm_config()
|
self.inner.evm_config()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Eth: AddDevSigners> AddDevSigners for OpEthApi<Eth> {
|
||||||
|
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner>>> {
|
||||||
|
self.inner.signers()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_dev_accounts(&self) {
|
||||||
|
*self.signers().write() = DevSigner::random_signers(20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Eth: UpdateRawTxForwarder> UpdateRawTxForwarder for OpEthApi<Eth> {
|
||||||
|
fn set_eth_raw_transaction_forwarder(&self, forwarder: Arc<dyn RawTransactionForwarder>) {
|
||||||
|
self.inner.set_eth_raw_transaction_forwarder(forwarder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<N, Eth> BuilderProvider<N> for OpEthApi<Eth>
|
||||||
|
where
|
||||||
|
Eth: BuilderProvider<N>,
|
||||||
|
N: FullNodeComponents,
|
||||||
|
{
|
||||||
|
type Ctx<'a> = <Eth as BuilderProvider<N>>::Ctx<'a>;
|
||||||
|
|
||||||
|
fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send> {
|
||||||
|
Box::new(|ctx| Self { inner: Eth::builder()(ctx) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -61,6 +61,7 @@ reth-rpc-types-compat.workspace = true
|
|||||||
reth-tracing.workspace = true
|
reth-tracing.workspace = true
|
||||||
reth-transaction-pool = { workspace = true, features = ["test-utils"] }
|
reth-transaction-pool = { workspace = true, features = ["test-utils"] }
|
||||||
reth-tokio-util.workspace = true
|
reth-tokio-util.workspace = true
|
||||||
|
reth-node-api.workspace = true
|
||||||
|
|
||||||
tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }
|
tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|||||||
@ -1,16 +1,18 @@
|
|||||||
use crate::{
|
use std::{net::SocketAddr, path::PathBuf};
|
||||||
auth::AuthServerConfig, error::RpcError, EthConfig, IpcServerBuilder, RpcModuleConfig,
|
|
||||||
RpcServerConfig, TransportRpcModuleConfig,
|
|
||||||
};
|
|
||||||
use jsonrpsee::server::ServerBuilder;
|
use jsonrpsee::server::ServerBuilder;
|
||||||
use reth_node_core::{args::RpcServerArgs, utils::get_or_create_jwt_secret_from_path};
|
use reth_node_core::{args::RpcServerArgs, utils::get_or_create_jwt_secret_from_path};
|
||||||
use reth_rpc_eth_types::{EthStateCacheConfig, GasPriceOracleConfig};
|
use reth_rpc_eth_types::{EthConfig, EthStateCacheConfig, GasPriceOracleConfig};
|
||||||
use reth_rpc_layer::{JwtError, JwtSecret};
|
use reth_rpc_layer::{JwtError, JwtSecret};
|
||||||
use reth_rpc_server_types::RpcModuleSelection;
|
use reth_rpc_server_types::RpcModuleSelection;
|
||||||
use std::{net::SocketAddr, path::PathBuf};
|
|
||||||
use tower::layer::util::Identity;
|
use tower::layer::util::Identity;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
auth::AuthServerConfig, error::RpcError, IpcServerBuilder, RpcModuleConfig, RpcServerConfig,
|
||||||
|
TransportRpcModuleConfig,
|
||||||
|
};
|
||||||
|
|
||||||
/// A trait that provides a configured RPC server.
|
/// A trait that provides a configured RPC server.
|
||||||
///
|
///
|
||||||
/// This provides all basic config values for the RPC server and is implemented by the
|
/// This provides all basic config values for the RPC server and is implemented by the
|
||||||
|
|||||||
@ -1,31 +1,14 @@
|
|||||||
use std::{fmt::Debug, time::Duration};
|
|
||||||
|
|
||||||
use reth_evm::ConfigureEvm;
|
use reth_evm::ConfigureEvm;
|
||||||
use reth_network_api::NetworkInfo;
|
use reth_provider::{BlockReader, CanonStateSubscriptions, EvmEnvProvider, StateProviderFactory};
|
||||||
use reth_provider::{
|
use reth_rpc::{EthFilter, EthPubSub};
|
||||||
BlockReader, BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, EvmEnvProvider,
|
|
||||||
FullRpcProvider, StateProviderFactory,
|
|
||||||
};
|
|
||||||
use reth_rpc::{eth::EthFilterConfig, EthApi, EthFilter, EthPubSub};
|
|
||||||
use reth_rpc_eth_types::{
|
use reth_rpc_eth_types::{
|
||||||
cache::cache_new_blocks_task, fee_history::fee_history_cache_new_blocks_task, EthStateCache,
|
cache::cache_new_blocks_task, EthApiBuilderCtx, EthConfig, EthStateCache,
|
||||||
EthStateCacheConfig, FeeHistoryCache, FeeHistoryCacheConfig, GasPriceOracle,
|
|
||||||
GasPriceOracleConfig, RPC_DEFAULT_GAS_CAP,
|
|
||||||
};
|
};
|
||||||
use reth_rpc_server_types::constants::{
|
use reth_tasks::TaskSpawner;
|
||||||
default_max_tracing_requests, DEFAULT_ETH_PROOF_WINDOW, DEFAULT_MAX_BLOCKS_PER_FILTER,
|
|
||||||
DEFAULT_MAX_LOGS_PER_RESPONSE, DEFAULT_PROOF_PERMITS,
|
|
||||||
};
|
|
||||||
use reth_tasks::{pool::BlockingTaskPool, TaskSpawner};
|
|
||||||
use reth_transaction_pool::TransactionPool;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
/// Default value for stale filter ttl
|
/// Alias for `eth` namespace API builder.
|
||||||
const DEFAULT_STALE_FILTER_TTL: Duration = Duration::from_secs(5 * 60);
|
pub type DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi> =
|
||||||
|
Box<dyn Fn(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi>;
|
||||||
/// Alias for function that builds the core `eth` namespace API.
|
|
||||||
pub type EthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi> =
|
|
||||||
Box<dyn FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi>;
|
|
||||||
|
|
||||||
/// Handlers for core, filter and pubsub `eth` namespace APIs.
|
/// Handlers for core, filter and pubsub `eth` namespace APIs.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -43,7 +26,7 @@ pub struct EthHandlers<Provider, Pool, Network, Events, EthApi> {
|
|||||||
impl<Provider, Pool, Network, Events, EthApi> EthHandlers<Provider, Pool, Network, Events, EthApi> {
|
impl<Provider, Pool, Network, Events, EthApi> EthHandlers<Provider, Pool, Network, Events, EthApi> {
|
||||||
/// Returns a new [`EthHandlers`] builder.
|
/// Returns a new [`EthHandlers`] builder.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn builder<EvmConfig, Tasks, EthApiB>(
|
pub fn builder<EvmConfig, Tasks>(
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
pool: Pool,
|
pool: Pool,
|
||||||
network: Network,
|
network: Network,
|
||||||
@ -51,12 +34,16 @@ impl<Provider, Pool, Network, Events, EthApi> EthHandlers<Provider, Pool, Networ
|
|||||||
config: EthConfig,
|
config: EthConfig,
|
||||||
executor: Tasks,
|
executor: Tasks,
|
||||||
events: Events,
|
events: Events,
|
||||||
eth_api_builder: EthApiB,
|
eth_api_builder: DynEthApiBuilder<
|
||||||
) -> EthHandlersBuilder<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi>
|
Provider,
|
||||||
where
|
Pool,
|
||||||
EthApiB: FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi
|
EvmConfig,
|
||||||
+ 'static,
|
Network,
|
||||||
{
|
Tasks,
|
||||||
|
Events,
|
||||||
|
EthApi,
|
||||||
|
>,
|
||||||
|
) -> EthHandlersBuilder<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi> {
|
||||||
EthHandlersBuilder {
|
EthHandlersBuilder {
|
||||||
provider,
|
provider,
|
||||||
pool,
|
pool,
|
||||||
@ -65,7 +52,7 @@ impl<Provider, Pool, Network, Events, EthApi> EthHandlers<Provider, Pool, Networ
|
|||||||
config,
|
config,
|
||||||
executor,
|
executor,
|
||||||
events,
|
events,
|
||||||
eth_api_builder: Box::new(eth_api_builder),
|
eth_api_builder,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,7 +67,7 @@ pub struct EthHandlersBuilder<Provider, Pool, Network, Tasks, Events, EvmConfig,
|
|||||||
config: EthConfig,
|
config: EthConfig,
|
||||||
executor: Tasks,
|
executor: Tasks,
|
||||||
events: Events,
|
events: Events,
|
||||||
eth_api_builder: EthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
|
eth_api_builder: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi>
|
impl<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi>
|
||||||
@ -89,9 +76,10 @@ where
|
|||||||
Provider: StateProviderFactory + BlockReader + EvmEnvProvider + Clone + Unpin + 'static,
|
Provider: StateProviderFactory + BlockReader + EvmEnvProvider + Clone + Unpin + 'static,
|
||||||
Pool: Send + Sync + Clone + 'static,
|
Pool: Send + Sync + Clone + 'static,
|
||||||
EvmConfig: ConfigureEvm,
|
EvmConfig: ConfigureEvm,
|
||||||
Network: Clone,
|
Network: Clone + 'static,
|
||||||
Tasks: TaskSpawner + Clone + 'static,
|
Tasks: TaskSpawner + Clone + 'static,
|
||||||
Events: CanonStateSubscriptions + Clone,
|
Events: CanonStateSubscriptions + Clone + 'static,
|
||||||
|
EthApi: 'static,
|
||||||
{
|
{
|
||||||
/// Returns a new instance with handlers for `eth` namespace.
|
/// Returns a new instance with handlers for `eth` namespace.
|
||||||
pub fn build(self) -> EthHandlers<Provider, Pool, Network, Events, EthApi> {
|
pub fn build(self) -> EthHandlers<Provider, Pool, Network, Events, EthApi> {
|
||||||
@ -135,170 +123,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional config values for the eth namespace.
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
|
||||||
pub struct EthConfig {
|
|
||||||
/// Settings for the caching layer
|
|
||||||
pub cache: EthStateCacheConfig,
|
|
||||||
/// Settings for the gas price oracle
|
|
||||||
pub gas_oracle: GasPriceOracleConfig,
|
|
||||||
/// The maximum number of blocks into the past for generating state proofs.
|
|
||||||
pub eth_proof_window: u64,
|
|
||||||
/// The maximum number of tracing calls that can be executed in concurrently.
|
|
||||||
pub max_tracing_requests: usize,
|
|
||||||
/// Maximum number of blocks that could be scanned per filter request in `eth_getLogs` calls.
|
|
||||||
pub max_blocks_per_filter: u64,
|
|
||||||
/// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
|
|
||||||
pub max_logs_per_response: usize,
|
|
||||||
/// Gas limit for `eth_call` and call tracing RPC methods.
|
|
||||||
///
|
|
||||||
/// Defaults to [`RPC_DEFAULT_GAS_CAP`]
|
|
||||||
pub rpc_gas_cap: u64,
|
|
||||||
///
|
|
||||||
/// Sets TTL for stale filters
|
|
||||||
pub stale_filter_ttl: Duration,
|
|
||||||
/// Settings for the fee history cache
|
|
||||||
pub fee_history_cache: FeeHistoryCacheConfig,
|
|
||||||
/// The maximum number of getproof calls that can be executed concurrently.
|
|
||||||
pub proof_permits: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EthConfig {
|
|
||||||
/// Returns the filter config for the `eth_filter` handler.
|
|
||||||
pub fn filter_config(&self) -> EthFilterConfig {
|
|
||||||
EthFilterConfig::default()
|
|
||||||
.max_blocks_per_filter(self.max_blocks_per_filter)
|
|
||||||
.max_logs_per_response(self.max_logs_per_response)
|
|
||||||
.stale_filter_ttl(self.stale_filter_ttl)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for EthConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
cache: EthStateCacheConfig::default(),
|
|
||||||
gas_oracle: GasPriceOracleConfig::default(),
|
|
||||||
eth_proof_window: DEFAULT_ETH_PROOF_WINDOW,
|
|
||||||
max_tracing_requests: default_max_tracing_requests(),
|
|
||||||
max_blocks_per_filter: DEFAULT_MAX_BLOCKS_PER_FILTER,
|
|
||||||
max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE,
|
|
||||||
rpc_gas_cap: RPC_DEFAULT_GAS_CAP.into(),
|
|
||||||
stale_filter_ttl: DEFAULT_STALE_FILTER_TTL,
|
|
||||||
fee_history_cache: FeeHistoryCacheConfig::default(),
|
|
||||||
proof_permits: DEFAULT_PROOF_PERMITS,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EthConfig {
|
|
||||||
/// Configures the caching layer settings
|
|
||||||
pub const fn state_cache(mut self, cache: EthStateCacheConfig) -> Self {
|
|
||||||
self.cache = cache;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the gas price oracle settings
|
|
||||||
pub const fn gpo_config(mut self, gas_oracle_config: GasPriceOracleConfig) -> Self {
|
|
||||||
self.gas_oracle = gas_oracle_config;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the maximum number of tracing requests
|
|
||||||
pub const fn max_tracing_requests(mut self, max_requests: usize) -> Self {
|
|
||||||
self.max_tracing_requests = max_requests;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the maximum block length to scan per `eth_getLogs` request
|
|
||||||
pub const fn max_blocks_per_filter(mut self, max_blocks: u64) -> Self {
|
|
||||||
self.max_blocks_per_filter = max_blocks;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the maximum number of logs per response
|
|
||||||
pub const fn max_logs_per_response(mut self, max_logs: usize) -> Self {
|
|
||||||
self.max_logs_per_response = max_logs;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the maximum gas limit for `eth_call` and call tracing RPC methods
|
|
||||||
pub const fn rpc_gas_cap(mut self, rpc_gas_cap: u64) -> Self {
|
|
||||||
self.rpc_gas_cap = rpc_gas_cap;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the maximum proof window for historical proof generation.
|
|
||||||
pub const fn eth_proof_window(mut self, window: u64) -> Self {
|
|
||||||
self.eth_proof_window = window;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the number of getproof requests
|
|
||||||
pub const fn proof_permits(mut self, permits: usize) -> Self {
|
|
||||||
self.proof_permits = permits;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Context for building the `eth` namespace API.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events> {
|
|
||||||
/// Database handle.
|
|
||||||
pub provider: Provider,
|
|
||||||
/// Mempool handle.
|
|
||||||
pub pool: Pool,
|
|
||||||
/// Network handle.
|
|
||||||
pub network: Network,
|
|
||||||
/// EVM configuration.
|
|
||||||
pub evm_config: EvmConfig,
|
|
||||||
/// RPC config for `eth` namespace.
|
|
||||||
pub config: EthConfig,
|
|
||||||
/// Runtime handle.
|
|
||||||
pub executor: Tasks,
|
|
||||||
/// Events handle.
|
|
||||||
pub events: Events,
|
|
||||||
/// RPC cache handle.
|
|
||||||
pub cache: EthStateCache,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ethereum layer one `eth` RPC server builder.
|
|
||||||
#[derive(Default, Debug, Clone, Copy)]
|
|
||||||
pub struct EthApiBuild;
|
|
||||||
|
|
||||||
impl EthApiBuild {
|
|
||||||
/// Builds the [`EthApiServer`](reth_rpc_eth_api::EthApiServer), for given context.
|
|
||||||
pub fn build<Provider, Pool, EvmConfig, Network, Tasks, Events>(
|
|
||||||
ctx: &EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>,
|
|
||||||
) -> EthApi<Provider, Pool, Network, EvmConfig>
|
|
||||||
where
|
|
||||||
Provider: FullRpcProvider,
|
|
||||||
Pool: TransactionPool,
|
|
||||||
Network: NetworkInfo + Clone,
|
|
||||||
Tasks: TaskSpawner + Clone + 'static,
|
|
||||||
Events: CanonStateSubscriptions,
|
|
||||||
EvmConfig: ConfigureEvm,
|
|
||||||
{
|
|
||||||
let gas_oracle = GasPriceOracleBuilder::build(ctx);
|
|
||||||
let fee_history_cache = FeeHistoryCacheBuilder::build(ctx);
|
|
||||||
|
|
||||||
EthApi::with_spawner(
|
|
||||||
ctx.provider.clone(),
|
|
||||||
ctx.pool.clone(),
|
|
||||||
ctx.network.clone(),
|
|
||||||
ctx.cache.clone(),
|
|
||||||
gas_oracle,
|
|
||||||
ctx.config.rpc_gas_cap,
|
|
||||||
ctx.config.eth_proof_window,
|
|
||||||
Box::new(ctx.executor.clone()),
|
|
||||||
BlockingTaskPool::build().expect("failed to build blocking task pool"),
|
|
||||||
fee_history_cache,
|
|
||||||
ctx.evm_config.clone(),
|
|
||||||
None,
|
|
||||||
ctx.config.proof_permits,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds the `eth_` namespace API [`EthFilterApiServer`](reth_rpc_eth_api::EthFilterApiServer).
|
/// Builds the `eth_` namespace API [`EthFilterApiServer`](reth_rpc_eth_api::EthFilterApiServer).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EthFilterApiBuilder;
|
pub struct EthFilterApiBuilder;
|
||||||
@ -348,50 +172,3 @@ impl EthPubSubApiBuilder {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds `eth_` core api component [`GasPriceOracle`], for given context.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct GasPriceOracleBuilder;
|
|
||||||
|
|
||||||
impl GasPriceOracleBuilder {
|
|
||||||
/// Builds a [`GasPriceOracle`], for given context.
|
|
||||||
pub fn build<Provider, Pool, EvmConfig, Network, Tasks, Events>(
|
|
||||||
ctx: &EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>,
|
|
||||||
) -> GasPriceOracle<Provider>
|
|
||||||
where
|
|
||||||
Provider: BlockReaderIdExt + Clone,
|
|
||||||
{
|
|
||||||
GasPriceOracle::new(ctx.provider.clone(), ctx.config.gas_oracle, ctx.cache.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds `eth_` core api component [`FeeHistoryCache`], for given context.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct FeeHistoryCacheBuilder;
|
|
||||||
|
|
||||||
impl FeeHistoryCacheBuilder {
|
|
||||||
/// Builds a [`FeeHistoryCache`], for given context.
|
|
||||||
pub fn build<Provider, Pool, EvmConfig, Network, Tasks, Events>(
|
|
||||||
ctx: &EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>,
|
|
||||||
) -> FeeHistoryCache
|
|
||||||
where
|
|
||||||
Provider: ChainSpecProvider + BlockReaderIdExt + Clone + 'static,
|
|
||||||
Tasks: TaskSpawner,
|
|
||||||
Events: CanonStateSubscriptions,
|
|
||||||
{
|
|
||||||
let fee_history_cache =
|
|
||||||
FeeHistoryCache::new(ctx.cache.clone(), ctx.config.fee_history_cache);
|
|
||||||
|
|
||||||
let new_canonical_blocks = ctx.events.canonical_state_stream();
|
|
||||||
let fhc = fee_history_cache.clone();
|
|
||||||
let provider = ctx.provider.clone();
|
|
||||||
ctx.executor.spawn_critical(
|
|
||||||
"cache canonical blocks for fee history task",
|
|
||||||
Box::pin(async move {
|
|
||||||
fee_history_cache_new_blocks_task(fhc, new_canonical_blocks, provider).await;
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
fee_history_cache
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -19,13 +19,13 @@
|
|||||||
//! use reth_evm::ConfigureEvm;
|
//! use reth_evm::ConfigureEvm;
|
||||||
//! use reth_network_api::{NetworkInfo, Peers};
|
//! use reth_network_api::{NetworkInfo, Peers};
|
||||||
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
||||||
|
//! use reth_rpc::EthApi;
|
||||||
//! use reth_rpc_builder::{
|
//! use reth_rpc_builder::{
|
||||||
//! EthApiBuild, RethRpcModule, RpcModuleBuilder, RpcServerConfig, ServerBuilder,
|
//! RethRpcModule, RpcModuleBuilder, RpcServerConfig, ServerBuilder, TransportRpcModuleConfig,
|
||||||
//! TransportRpcModuleConfig,
|
|
||||||
//! };
|
//! };
|
||||||
//!
|
|
||||||
//! use reth_tasks::TokioTaskExecutor;
|
//! use reth_tasks::TokioTaskExecutor;
|
||||||
//! use reth_transaction_pool::TransactionPool;
|
//! use reth_transaction_pool::TransactionPool;
|
||||||
|
//!
|
||||||
//! pub async fn launch<Provider, Pool, Network, Events, EvmConfig>(
|
//! pub async fn launch<Provider, Pool, Network, Events, EvmConfig>(
|
||||||
//! provider: Provider,
|
//! provider: Provider,
|
||||||
//! pool: Pool,
|
//! pool: Pool,
|
||||||
@ -54,7 +54,7 @@
|
|||||||
//! events,
|
//! events,
|
||||||
//! evm_config,
|
//! evm_config,
|
||||||
//! )
|
//! )
|
||||||
//! .build(transports, EthApiBuild::build);
|
//! .build(transports, Box::new(EthApi::with_spawner));
|
||||||
//! let handle = RpcServerConfig::default()
|
//! let handle = RpcServerConfig::default()
|
||||||
//! .with_http(ServerBuilder::default())
|
//! .with_http(ServerBuilder::default())
|
||||||
//! .start(&transport_modules)
|
//! .start(&transport_modules)
|
||||||
@ -70,9 +70,10 @@
|
|||||||
//! use reth_evm::ConfigureEvm;
|
//! use reth_evm::ConfigureEvm;
|
||||||
//! use reth_network_api::{NetworkInfo, Peers};
|
//! use reth_network_api::{NetworkInfo, Peers};
|
||||||
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
|
||||||
|
//! use reth_rpc::EthApi;
|
||||||
//! use reth_rpc_api::EngineApiServer;
|
//! use reth_rpc_api::EngineApiServer;
|
||||||
//! use reth_rpc_builder::{
|
//! use reth_rpc_builder::{
|
||||||
//! auth::AuthServerConfig, EthApiBuild, RethRpcModule, RpcModuleBuilder, RpcServerConfig,
|
//! auth::AuthServerConfig, RethRpcModule, RpcModuleBuilder, RpcServerConfig,
|
||||||
//! TransportRpcModuleConfig,
|
//! TransportRpcModuleConfig,
|
||||||
//! };
|
//! };
|
||||||
//! use reth_rpc_layer::JwtSecret;
|
//! use reth_rpc_layer::JwtSecret;
|
||||||
@ -113,7 +114,7 @@
|
|||||||
//!
|
//!
|
||||||
//! // configure the server modules
|
//! // configure the server modules
|
||||||
//! let (modules, auth_module, _registry) =
|
//! let (modules, auth_module, _registry) =
|
||||||
//! builder.build_with_auth_server(transports, engine_api, EthApiBuild::build);
|
//! builder.build_with_auth_server(transports, engine_api, Box::new(EthApi::with_spawner));
|
||||||
//!
|
//!
|
||||||
//! // start the servers
|
//! // start the servers
|
||||||
//! let auth_config = AuthServerConfig::builder(JwtSecret::random()).build();
|
//! let auth_config = AuthServerConfig::builder(JwtSecret::random()).build();
|
||||||
@ -140,6 +141,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use error::{ConflictingModules, RpcError, ServerKind};
|
use error::{ConflictingModules, RpcError, ServerKind};
|
||||||
|
use eth::DynEthApiBuilder;
|
||||||
use http::{header::AUTHORIZATION, HeaderMap};
|
use http::{header::AUTHORIZATION, HeaderMap};
|
||||||
use jsonrpsee::{
|
use jsonrpsee::{
|
||||||
core::RegisterMethodError,
|
core::RegisterMethodError,
|
||||||
@ -167,7 +169,7 @@ use reth_rpc_eth_api::{
|
|||||||
},
|
},
|
||||||
EthApiServer, FullEthApiServer, RawTransactionForwarder,
|
EthApiServer, FullEthApiServer, RawTransactionForwarder,
|
||||||
};
|
};
|
||||||
use reth_rpc_eth_types::{EthStateCache, EthSubscriptionIdProvider};
|
use reth_rpc_eth_types::{EthConfig, EthStateCache, EthSubscriptionIdProvider};
|
||||||
use reth_rpc_layer::{AuthLayer, Claims, JwtAuthValidator, JwtSecret};
|
use reth_rpc_layer::{AuthLayer, Claims, JwtAuthValidator, JwtSecret};
|
||||||
use reth_tasks::{pool::BlockingTaskGuard, TaskSpawner, TokioTaskExecutor};
|
use reth_tasks::{pool::BlockingTaskGuard, TaskSpawner, TokioTaskExecutor};
|
||||||
use reth_transaction_pool::{noop::NoopTransactionPool, TransactionPool};
|
use reth_transaction_pool::{noop::NoopTransactionPool, TransactionPool};
|
||||||
@ -202,17 +204,14 @@ pub mod error;
|
|||||||
|
|
||||||
/// Eth utils
|
/// Eth utils
|
||||||
pub mod eth;
|
pub mod eth;
|
||||||
pub use eth::{
|
pub use eth::EthHandlers;
|
||||||
EthApiBuild, EthApiBuilderCtx, EthConfig, EthHandlers, FeeHistoryCacheBuilder,
|
|
||||||
GasPriceOracleBuilder,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Rpc server metrics
|
// Rpc server metrics
|
||||||
mod metrics;
|
mod metrics;
|
||||||
|
|
||||||
/// Convenience function for starting a server in one step.
|
/// Convenience function for starting a server in one step.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub async fn launch<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi, EthApiB>(
|
pub async fn launch<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi>(
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
pool: Pool,
|
pool: Pool,
|
||||||
network: Network,
|
network: Network,
|
||||||
@ -221,7 +220,7 @@ pub async fn launch<Provider, Pool, Network, Tasks, Events, EvmConfig, EthApi, E
|
|||||||
executor: Tasks,
|
executor: Tasks,
|
||||||
events: Events,
|
events: Events,
|
||||||
evm_config: EvmConfig,
|
evm_config: EvmConfig,
|
||||||
eth: EthApiB,
|
eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
|
||||||
) -> Result<RpcServerHandle, RpcError>
|
) -> Result<RpcServerHandle, RpcError>
|
||||||
where
|
where
|
||||||
Provider: FullRpcProvider + AccountReader + ChangeSetReader,
|
Provider: FullRpcProvider + AccountReader + ChangeSetReader,
|
||||||
@ -230,8 +229,6 @@ where
|
|||||||
Tasks: TaskSpawner + Clone + 'static,
|
Tasks: TaskSpawner + Clone + 'static,
|
||||||
Events: CanonStateSubscriptions + Clone + 'static,
|
Events: CanonStateSubscriptions + Clone + 'static,
|
||||||
EvmConfig: ConfigureEvm,
|
EvmConfig: ConfigureEvm,
|
||||||
EthApiB: FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi
|
|
||||||
+ 'static,
|
|
||||||
EthApi: FullEthApiServer,
|
EthApi: FullEthApiServer,
|
||||||
{
|
{
|
||||||
let module_config = module_config.into();
|
let module_config = module_config.into();
|
||||||
@ -426,11 +423,11 @@ where
|
|||||||
/// also configures the auth (engine api) server, which exposes a subset of the `eth_`
|
/// also configures the auth (engine api) server, which exposes a subset of the `eth_`
|
||||||
/// namespace.
|
/// namespace.
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
pub fn build_with_auth_server<EngineApi, EngineT, EthApi, EthApiB>(
|
pub fn build_with_auth_server<EngineApi, EngineT, EthApi>(
|
||||||
self,
|
self,
|
||||||
module_config: TransportRpcModuleConfig,
|
module_config: TransportRpcModuleConfig,
|
||||||
engine: EngineApi,
|
engine: EngineApi,
|
||||||
eth: EthApiB,
|
eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
|
||||||
) -> (
|
) -> (
|
||||||
TransportRpcModules,
|
TransportRpcModules,
|
||||||
AuthRpcModule,
|
AuthRpcModule,
|
||||||
@ -439,8 +436,6 @@ where
|
|||||||
where
|
where
|
||||||
EngineT: EngineTypes + 'static,
|
EngineT: EngineTypes + 'static,
|
||||||
EngineApi: EngineApiServer<EngineT>,
|
EngineApi: EngineApiServer<EngineT>,
|
||||||
EthApiB: FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi
|
|
||||||
+ 'static,
|
|
||||||
EthApi: FullEthApiServer,
|
EthApi: FullEthApiServer,
|
||||||
{
|
{
|
||||||
let Self { provider, pool, network, executor, events, evm_config } = self;
|
let Self { provider, pool, network, executor, events, evm_config } = self;
|
||||||
@ -469,7 +464,8 @@ where
|
|||||||
/// use reth_evm::ConfigureEvm;
|
/// use reth_evm::ConfigureEvm;
|
||||||
/// use reth_network_api::noop::NoopNetwork;
|
/// use reth_network_api::noop::NoopNetwork;
|
||||||
/// use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions};
|
/// use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions};
|
||||||
/// use reth_rpc_builder::{EthApiBuild, RpcModuleBuilder};
|
/// use reth_rpc::EthApi;
|
||||||
|
/// use reth_rpc_builder::RpcModuleBuilder;
|
||||||
/// use reth_tasks::TokioTaskExecutor;
|
/// use reth_tasks::TokioTaskExecutor;
|
||||||
/// use reth_transaction_pool::noop::NoopTransactionPool;
|
/// use reth_transaction_pool::noop::NoopTransactionPool;
|
||||||
///
|
///
|
||||||
@ -481,19 +477,18 @@ where
|
|||||||
/// .with_executor(TokioTaskExecutor::default())
|
/// .with_executor(TokioTaskExecutor::default())
|
||||||
/// .with_events(TestCanonStateSubscriptions::default())
|
/// .with_events(TestCanonStateSubscriptions::default())
|
||||||
/// .with_evm_config(evm)
|
/// .with_evm_config(evm)
|
||||||
/// .into_registry(Default::default(), EthApiBuild::build);
|
/// .into_registry(Default::default(), Box::new(EthApi::with_spawner));
|
||||||
///
|
///
|
||||||
/// let eth_api = registry.eth_api();
|
/// let eth_api = registry.eth_api();
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn into_registry<EthApi, EthApiB>(
|
pub fn into_registry<EthApi>(
|
||||||
self,
|
self,
|
||||||
config: RpcModuleConfig,
|
config: RpcModuleConfig,
|
||||||
eth: EthApiB,
|
eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
|
||||||
) -> RpcRegistryInner<Provider, Pool, Network, Tasks, Events, EthApi>
|
) -> RpcRegistryInner<Provider, Pool, Network, Tasks, Events, EthApi>
|
||||||
where
|
where
|
||||||
EthApiB: FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi
|
EthApi: 'static,
|
||||||
+ 'static,
|
|
||||||
{
|
{
|
||||||
let Self { provider, pool, network, executor, events, evm_config } = self;
|
let Self { provider, pool, network, executor, events, evm_config } = self;
|
||||||
RpcRegistryInner::new(provider, pool, network, executor, events, config, evm_config, eth)
|
RpcRegistryInner::new(provider, pool, network, executor, events, config, evm_config, eth)
|
||||||
@ -501,14 +496,12 @@ where
|
|||||||
|
|
||||||
/// Configures all [`RpcModule`]s specific to the given [`TransportRpcModuleConfig`] which can
|
/// Configures all [`RpcModule`]s specific to the given [`TransportRpcModuleConfig`] which can
|
||||||
/// be used to start the transport server(s).
|
/// be used to start the transport server(s).
|
||||||
pub fn build<EthApi, EthApiB>(
|
pub fn build<EthApi>(
|
||||||
self,
|
self,
|
||||||
module_config: TransportRpcModuleConfig,
|
module_config: TransportRpcModuleConfig,
|
||||||
eth: EthApiB,
|
eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, Events, EthApi>,
|
||||||
) -> TransportRpcModules<()>
|
) -> TransportRpcModules<()>
|
||||||
where
|
where
|
||||||
EthApiB: FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi
|
|
||||||
+ 'static,
|
|
||||||
EthApi: FullEthApiServer,
|
EthApi: FullEthApiServer,
|
||||||
{
|
{
|
||||||
let mut modules = TransportRpcModules::default();
|
let mut modules = TransportRpcModules::default();
|
||||||
@ -636,13 +629,14 @@ impl<Provider, Pool, Network, Tasks, Events, EthApi>
|
|||||||
where
|
where
|
||||||
Provider: StateProviderFactory + BlockReader + EvmEnvProvider + Clone + Unpin + 'static,
|
Provider: StateProviderFactory + BlockReader + EvmEnvProvider + Clone + Unpin + 'static,
|
||||||
Pool: Send + Sync + Clone + 'static,
|
Pool: Send + Sync + Clone + 'static,
|
||||||
Network: Clone,
|
Network: Clone + 'static,
|
||||||
Events: CanonStateSubscriptions + Clone,
|
Events: CanonStateSubscriptions + Clone + 'static,
|
||||||
Tasks: TaskSpawner + Clone + 'static,
|
Tasks: TaskSpawner + Clone + 'static,
|
||||||
|
EthApi: 'static,
|
||||||
{
|
{
|
||||||
/// Creates a new, empty instance.
|
/// Creates a new, empty instance.
|
||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn new<EvmConfig, EthApiB>(
|
pub fn new<EvmConfig>(
|
||||||
provider: Provider,
|
provider: Provider,
|
||||||
pool: Pool,
|
pool: Pool,
|
||||||
network: Network,
|
network: Network,
|
||||||
@ -650,12 +644,18 @@ where
|
|||||||
events: Events,
|
events: Events,
|
||||||
config: RpcModuleConfig,
|
config: RpcModuleConfig,
|
||||||
evm_config: EvmConfig,
|
evm_config: EvmConfig,
|
||||||
eth_api_builder: EthApiB,
|
eth_api_builder: DynEthApiBuilder<
|
||||||
|
Provider,
|
||||||
|
Pool,
|
||||||
|
EvmConfig,
|
||||||
|
Network,
|
||||||
|
Tasks,
|
||||||
|
Events,
|
||||||
|
EthApi,
|
||||||
|
>,
|
||||||
) -> Self
|
) -> Self
|
||||||
where
|
where
|
||||||
EvmConfig: ConfigureEvm,
|
EvmConfig: ConfigureEvm,
|
||||||
EthApiB: FnOnce(&EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>) -> EthApi
|
|
||||||
+ 'static,
|
|
||||||
{
|
{
|
||||||
let blocking_pool_guard = BlockingTaskGuard::new(config.eth.max_tracing_requests);
|
let blocking_pool_guard = BlockingTaskGuard::new(config.eth.max_tracing_requests);
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
use reth_rpc::EthApi;
|
||||||
use reth_rpc_builder::{
|
use reth_rpc_builder::{
|
||||||
error::{RpcError, ServerKind, WsHttpSamePortError},
|
error::{RpcError, ServerKind, WsHttpSamePortError},
|
||||||
EthApiBuild, RpcServerConfig, TransportRpcModuleConfig,
|
RpcServerConfig, TransportRpcModuleConfig,
|
||||||
};
|
};
|
||||||
use reth_rpc_server_types::RethRpcModule;
|
use reth_rpc_server_types::RethRpcModule;
|
||||||
|
|
||||||
@ -26,8 +27,10 @@ async fn test_http_addr_in_use() {
|
|||||||
let handle = launch_http(vec![RethRpcModule::Admin]).await;
|
let handle = launch_http(vec![RethRpcModule::Admin]).await;
|
||||||
let addr = handle.http_local_addr().unwrap();
|
let addr = handle.http_local_addr().unwrap();
|
||||||
let builder = test_rpc_builder();
|
let builder = test_rpc_builder();
|
||||||
let server = builder
|
let server = builder.build(
|
||||||
.build(TransportRpcModuleConfig::set_http(vec![RethRpcModule::Admin]), EthApiBuild::build);
|
TransportRpcModuleConfig::set_http(vec![RethRpcModule::Admin]),
|
||||||
|
Box::new(EthApi::with_spawner),
|
||||||
|
);
|
||||||
let result =
|
let result =
|
||||||
RpcServerConfig::http(Default::default()).with_http_address(addr).start(&server).await;
|
RpcServerConfig::http(Default::default()).with_http_address(addr).start(&server).await;
|
||||||
let err = result.unwrap_err();
|
let err = result.unwrap_err();
|
||||||
@ -39,8 +42,10 @@ async fn test_ws_addr_in_use() {
|
|||||||
let handle = launch_ws(vec![RethRpcModule::Admin]).await;
|
let handle = launch_ws(vec![RethRpcModule::Admin]).await;
|
||||||
let addr = handle.ws_local_addr().unwrap();
|
let addr = handle.ws_local_addr().unwrap();
|
||||||
let builder = test_rpc_builder();
|
let builder = test_rpc_builder();
|
||||||
let server = builder
|
let server = builder.build(
|
||||||
.build(TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Admin]), EthApiBuild::build);
|
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Admin]),
|
||||||
|
Box::new(EthApi::with_spawner),
|
||||||
|
);
|
||||||
let result = RpcServerConfig::ws(Default::default()).with_ws_address(addr).start(&server).await;
|
let result = RpcServerConfig::ws(Default::default()).with_ws_address(addr).start(&server).await;
|
||||||
let err = result.unwrap_err();
|
let err = result.unwrap_err();
|
||||||
assert!(is_addr_in_use_kind(&err, ServerKind::WS(addr)), "{err}");
|
assert!(is_addr_in_use_kind(&err, ServerKind::WS(addr)), "{err}");
|
||||||
@ -60,7 +65,7 @@ async fn test_launch_same_port_different_modules() {
|
|||||||
let server = builder.build(
|
let server = builder.build(
|
||||||
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Admin])
|
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Admin])
|
||||||
.with_http(vec![RethRpcModule::Eth]),
|
.with_http(vec![RethRpcModule::Eth]),
|
||||||
EthApiBuild::build,
|
Box::new(EthApi::with_spawner),
|
||||||
);
|
);
|
||||||
let addr = test_address();
|
let addr = test_address();
|
||||||
let res = RpcServerConfig::ws(Default::default())
|
let res = RpcServerConfig::ws(Default::default())
|
||||||
@ -82,7 +87,7 @@ async fn test_launch_same_port_same_cors() {
|
|||||||
let server = builder.build(
|
let server = builder.build(
|
||||||
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Eth])
|
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Eth])
|
||||||
.with_http(vec![RethRpcModule::Eth]),
|
.with_http(vec![RethRpcModule::Eth]),
|
||||||
EthApiBuild::build,
|
Box::new(EthApi::with_spawner),
|
||||||
);
|
);
|
||||||
let addr = test_address();
|
let addr = test_address();
|
||||||
let res = RpcServerConfig::ws(Default::default())
|
let res = RpcServerConfig::ws(Default::default())
|
||||||
@ -102,7 +107,7 @@ async fn test_launch_same_port_different_cors() {
|
|||||||
let server = builder.build(
|
let server = builder.build(
|
||||||
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Eth])
|
TransportRpcModuleConfig::set_ws(vec![RethRpcModule::Eth])
|
||||||
.with_http(vec![RethRpcModule::Eth]),
|
.with_http(vec![RethRpcModule::Eth]),
|
||||||
EthApiBuild::build,
|
Box::new(EthApi::with_spawner),
|
||||||
);
|
);
|
||||||
let addr = test_address();
|
let addr = test_address();
|
||||||
let res = RpcServerConfig::ws(Default::default())
|
let res = RpcServerConfig::ws(Default::default())
|
||||||
|
|||||||
@ -7,9 +7,10 @@ use reth_evm_ethereum::EthEvmConfig;
|
|||||||
use reth_network_api::noop::NoopNetwork;
|
use reth_network_api::noop::NoopNetwork;
|
||||||
use reth_payload_builder::test_utils::spawn_test_payload_service;
|
use reth_payload_builder::test_utils::spawn_test_payload_service;
|
||||||
use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions};
|
use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions};
|
||||||
|
use reth_rpc::EthApi;
|
||||||
use reth_rpc_builder::{
|
use reth_rpc_builder::{
|
||||||
auth::{AuthRpcModule, AuthServerConfig, AuthServerHandle},
|
auth::{AuthRpcModule, AuthServerConfig, AuthServerHandle},
|
||||||
EthApiBuild, RpcModuleBuilder, RpcServerConfig, RpcServerHandle, TransportRpcModuleConfig,
|
RpcModuleBuilder, RpcServerConfig, RpcServerHandle, TransportRpcModuleConfig,
|
||||||
};
|
};
|
||||||
use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi};
|
use reth_rpc_engine_api::{capabilities::EngineCapabilities, EngineApi};
|
||||||
use reth_rpc_layer::JwtSecret;
|
use reth_rpc_layer::JwtSecret;
|
||||||
@ -53,7 +54,8 @@ pub async fn launch_auth(secret: JwtSecret) -> AuthServerHandle {
|
|||||||
/// Launches a new server with http only with the given modules
|
/// Launches a new server with http only with the given modules
|
||||||
pub async fn launch_http(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle {
|
pub async fn launch_http(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle {
|
||||||
let builder = test_rpc_builder();
|
let builder = test_rpc_builder();
|
||||||
let server = builder.build(TransportRpcModuleConfig::set_http(modules), EthApiBuild::build);
|
let server =
|
||||||
|
builder.build(TransportRpcModuleConfig::set_http(modules), Box::new(EthApi::with_spawner));
|
||||||
RpcServerConfig::http(Default::default())
|
RpcServerConfig::http(Default::default())
|
||||||
.with_http_address(test_address())
|
.with_http_address(test_address())
|
||||||
.start(&server)
|
.start(&server)
|
||||||
@ -64,7 +66,8 @@ pub async fn launch_http(modules: impl Into<RpcModuleSelection>) -> RpcServerHan
|
|||||||
/// Launches a new server with ws only with the given modules
|
/// Launches a new server with ws only with the given modules
|
||||||
pub async fn launch_ws(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle {
|
pub async fn launch_ws(modules: impl Into<RpcModuleSelection>) -> RpcServerHandle {
|
||||||
let builder = test_rpc_builder();
|
let builder = test_rpc_builder();
|
||||||
let server = builder.build(TransportRpcModuleConfig::set_ws(modules), EthApiBuild::build);
|
let server =
|
||||||
|
builder.build(TransportRpcModuleConfig::set_ws(modules), Box::new(EthApi::with_spawner));
|
||||||
RpcServerConfig::ws(Default::default())
|
RpcServerConfig::ws(Default::default())
|
||||||
.with_http_address(test_address())
|
.with_http_address(test_address())
|
||||||
.start(&server)
|
.start(&server)
|
||||||
@ -78,7 +81,7 @@ pub async fn launch_http_ws(modules: impl Into<RpcModuleSelection>) -> RpcServer
|
|||||||
let modules = modules.into();
|
let modules = modules.into();
|
||||||
let server = builder.build(
|
let server = builder.build(
|
||||||
TransportRpcModuleConfig::set_ws(modules.clone()).with_http(modules),
|
TransportRpcModuleConfig::set_ws(modules.clone()).with_http(modules),
|
||||||
EthApiBuild::build,
|
Box::new(EthApi::with_spawner),
|
||||||
);
|
);
|
||||||
RpcServerConfig::ws(Default::default())
|
RpcServerConfig::ws(Default::default())
|
||||||
.with_ws_address(test_address())
|
.with_ws_address(test_address())
|
||||||
@ -95,7 +98,7 @@ pub async fn launch_http_ws_same_port(modules: impl Into<RpcModuleSelection>) ->
|
|||||||
let modules = modules.into();
|
let modules = modules.into();
|
||||||
let server = builder.build(
|
let server = builder.build(
|
||||||
TransportRpcModuleConfig::set_ws(modules.clone()).with_http(modules),
|
TransportRpcModuleConfig::set_ws(modules.clone()).with_http(modules),
|
||||||
EthApiBuild::build,
|
Box::new(EthApi::with_spawner),
|
||||||
);
|
);
|
||||||
let addr = test_address();
|
let addr = test_address();
|
||||||
RpcServerConfig::ws(Default::default())
|
RpcServerConfig::ws(Default::default())
|
||||||
|
|||||||
@ -32,7 +32,7 @@ pub use call::{Call, EthCall};
|
|||||||
pub use fee::{EthFees, LoadFee};
|
pub use fee::{EthFees, LoadFee};
|
||||||
pub use pending_block::LoadPendingBlock;
|
pub use pending_block::LoadPendingBlock;
|
||||||
pub use receipt::LoadReceipt;
|
pub use receipt::LoadReceipt;
|
||||||
pub use signer::EthSigner;
|
pub use signer::{AddDevSigners, EthSigner};
|
||||||
pub use spec::EthApiSpec;
|
pub use spec::EthApiSpec;
|
||||||
pub use state::{EthState, LoadState};
|
pub use state::{EthState, LoadState};
|
||||||
pub use trace::Trace;
|
pub use trace::Trace;
|
||||||
|
|||||||
@ -37,3 +37,14 @@ pub trait EthSigner: Send + Sync + DynClone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dyn_clone::clone_trait_object!(EthSigner);
|
dyn_clone::clone_trait_object!(EthSigner);
|
||||||
|
|
||||||
|
/// Adds 20 random dev signers for access via the API. Used in dev mode.
|
||||||
|
#[auto_impl::auto_impl(&)]
|
||||||
|
pub trait AddDevSigners {
|
||||||
|
/// Returns a handle to the signers.
|
||||||
|
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner>>>;
|
||||||
|
|
||||||
|
/// Generates 20 random developer accounts.
|
||||||
|
/// Used in DEV mode.
|
||||||
|
fn with_dev_accounts(&self);
|
||||||
|
}
|
||||||
|
|||||||
170
crates/rpc/rpc-eth-types/src/builder/config.rs
Normal file
170
crates/rpc/rpc-eth-types/src/builder/config.rs
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
//! Configuration for `eth` namespace APIs.
|
||||||
|
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
EthStateCacheConfig, FeeHistoryCacheConfig, GasPriceOracleConfig, RPC_DEFAULT_GAS_CAP,
|
||||||
|
};
|
||||||
|
use reth_rpc_server_types::constants::{
|
||||||
|
default_max_tracing_requests, DEFAULT_ETH_PROOF_WINDOW, DEFAULT_MAX_BLOCKS_PER_FILTER,
|
||||||
|
DEFAULT_MAX_LOGS_PER_RESPONSE, DEFAULT_PROOF_PERMITS,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
/// Default value for stale filter ttl
|
||||||
|
pub const DEFAULT_STALE_FILTER_TTL: Duration = Duration::from_secs(5 * 60);
|
||||||
|
|
||||||
|
/// Additional config values for the eth namespace.
|
||||||
|
#[derive(Debug, Clone, Eq, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct EthConfig {
|
||||||
|
/// Settings for the caching layer
|
||||||
|
pub cache: EthStateCacheConfig,
|
||||||
|
/// Settings for the gas price oracle
|
||||||
|
pub gas_oracle: GasPriceOracleConfig,
|
||||||
|
/// The maximum number of blocks into the past for generating state proofs.
|
||||||
|
pub eth_proof_window: u64,
|
||||||
|
/// The maximum number of tracing calls that can be executed in concurrently.
|
||||||
|
pub max_tracing_requests: usize,
|
||||||
|
/// Maximum number of blocks that could be scanned per filter request in `eth_getLogs` calls.
|
||||||
|
pub max_blocks_per_filter: u64,
|
||||||
|
/// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
|
||||||
|
pub max_logs_per_response: usize,
|
||||||
|
/// Gas limit for `eth_call` and call tracing RPC methods.
|
||||||
|
///
|
||||||
|
/// Defaults to [`RPC_DEFAULT_GAS_CAP`]
|
||||||
|
pub rpc_gas_cap: u64,
|
||||||
|
///
|
||||||
|
/// Sets TTL for stale filters
|
||||||
|
pub stale_filter_ttl: Duration,
|
||||||
|
/// Settings for the fee history cache
|
||||||
|
pub fee_history_cache: FeeHistoryCacheConfig,
|
||||||
|
/// The maximum number of getproof calls that can be executed concurrently.
|
||||||
|
pub proof_permits: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EthConfig {
|
||||||
|
/// Returns the filter config for the `eth_filter` handler.
|
||||||
|
pub fn filter_config(&self) -> EthFilterConfig {
|
||||||
|
EthFilterConfig::default()
|
||||||
|
.max_blocks_per_filter(self.max_blocks_per_filter)
|
||||||
|
.max_logs_per_response(self.max_logs_per_response)
|
||||||
|
.stale_filter_ttl(self.stale_filter_ttl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for EthConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
cache: EthStateCacheConfig::default(),
|
||||||
|
gas_oracle: GasPriceOracleConfig::default(),
|
||||||
|
eth_proof_window: DEFAULT_ETH_PROOF_WINDOW,
|
||||||
|
max_tracing_requests: default_max_tracing_requests(),
|
||||||
|
max_blocks_per_filter: DEFAULT_MAX_BLOCKS_PER_FILTER,
|
||||||
|
max_logs_per_response: DEFAULT_MAX_LOGS_PER_RESPONSE,
|
||||||
|
rpc_gas_cap: RPC_DEFAULT_GAS_CAP.into(),
|
||||||
|
stale_filter_ttl: DEFAULT_STALE_FILTER_TTL,
|
||||||
|
fee_history_cache: FeeHistoryCacheConfig::default(),
|
||||||
|
proof_permits: DEFAULT_PROOF_PERMITS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EthConfig {
|
||||||
|
/// Configures the caching layer settings
|
||||||
|
pub const fn state_cache(mut self, cache: EthStateCacheConfig) -> Self {
|
||||||
|
self.cache = cache;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the gas price oracle settings
|
||||||
|
pub const fn gpo_config(mut self, gas_oracle_config: GasPriceOracleConfig) -> Self {
|
||||||
|
self.gas_oracle = gas_oracle_config;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the maximum number of tracing requests
|
||||||
|
pub const fn max_tracing_requests(mut self, max_requests: usize) -> Self {
|
||||||
|
self.max_tracing_requests = max_requests;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the maximum block length to scan per `eth_getLogs` request
|
||||||
|
pub const fn max_blocks_per_filter(mut self, max_blocks: u64) -> Self {
|
||||||
|
self.max_blocks_per_filter = max_blocks;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the maximum number of logs per response
|
||||||
|
pub const fn max_logs_per_response(mut self, max_logs: usize) -> Self {
|
||||||
|
self.max_logs_per_response = max_logs;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the maximum gas limit for `eth_call` and call tracing RPC methods
|
||||||
|
pub const fn rpc_gas_cap(mut self, rpc_gas_cap: u64) -> Self {
|
||||||
|
self.rpc_gas_cap = rpc_gas_cap;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the maximum proof window for historical proof generation.
|
||||||
|
pub const fn eth_proof_window(mut self, window: u64) -> Self {
|
||||||
|
self.eth_proof_window = window;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Configures the number of getproof requests
|
||||||
|
pub const fn proof_permits(mut self, permits: usize) -> Self {
|
||||||
|
self.proof_permits = permits;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Config for the filter
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct EthFilterConfig {
|
||||||
|
/// Maximum number of blocks that a filter can scan for logs.
|
||||||
|
///
|
||||||
|
/// If `None` then no limit is enforced.
|
||||||
|
pub max_blocks_per_filter: Option<u64>,
|
||||||
|
/// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
|
||||||
|
///
|
||||||
|
/// If `None` then no limit is enforced.
|
||||||
|
pub max_logs_per_response: Option<usize>,
|
||||||
|
/// How long a filter remains valid after the last poll.
|
||||||
|
///
|
||||||
|
/// A filter is considered stale if it has not been polled for longer than this duration and
|
||||||
|
/// will be removed.
|
||||||
|
pub stale_filter_ttl: Duration,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EthFilterConfig {
|
||||||
|
/// Sets the maximum number of blocks that a filter can scan for logs.
|
||||||
|
pub const fn max_blocks_per_filter(mut self, num: u64) -> Self {
|
||||||
|
self.max_blocks_per_filter = Some(num);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the maximum number of logs that can be returned in a single response in `eth_getLogs`
|
||||||
|
/// calls.
|
||||||
|
pub const fn max_logs_per_response(mut self, num: usize) -> Self {
|
||||||
|
self.max_logs_per_response = Some(num);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets how long a filter remains valid after the last poll before it will be removed.
|
||||||
|
pub const fn stale_filter_ttl(mut self, duration: Duration) -> Self {
|
||||||
|
self.stale_filter_ttl = duration;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for EthFilterConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
max_blocks_per_filter: None,
|
||||||
|
max_logs_per_response: None,
|
||||||
|
// 5min
|
||||||
|
stale_filter_ttl: Duration::from_secs(5 * 60),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
98
crates/rpc/rpc-eth-types/src/builder/ctx.rs
Normal file
98
crates/rpc/rpc-eth-types/src/builder/ctx.rs
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
//! Context required for building `eth` namespace APIs.
|
||||||
|
|
||||||
|
use reth_provider::{BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider};
|
||||||
|
use reth_tasks::TaskSpawner;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
fee_history::fee_history_cache_new_blocks_task, EthConfig, EthStateCache, FeeHistoryCache,
|
||||||
|
GasPriceOracle,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Context for building the `eth` namespace API.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events> {
|
||||||
|
/// Database handle.
|
||||||
|
pub provider: Provider,
|
||||||
|
/// Mempool handle.
|
||||||
|
pub pool: Pool,
|
||||||
|
/// Network handle.
|
||||||
|
pub network: Network,
|
||||||
|
/// EVM configuration.
|
||||||
|
pub evm_config: EvmConfig,
|
||||||
|
/// RPC config for `eth` namespace.
|
||||||
|
pub config: EthConfig,
|
||||||
|
/// Runtime handle.
|
||||||
|
pub executor: Tasks,
|
||||||
|
/// Events handle.
|
||||||
|
pub events: Events,
|
||||||
|
/// RPC cache handle.
|
||||||
|
pub cache: EthStateCache,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Provider, Pool, EvmConfig, Network, Tasks, Events>
|
||||||
|
EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>
|
||||||
|
where
|
||||||
|
Provider: BlockReaderIdExt + Clone,
|
||||||
|
{
|
||||||
|
/// Returns a new [`FeeHistoryCache`] for the context.
|
||||||
|
pub fn new_fee_history_cache(&self) -> FeeHistoryCache
|
||||||
|
where
|
||||||
|
Provider: ChainSpecProvider + 'static,
|
||||||
|
Tasks: TaskSpawner,
|
||||||
|
Events: CanonStateSubscriptions,
|
||||||
|
{
|
||||||
|
FeeHistoryCacheBuilder::build(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a new [`GasPriceOracle`] for the context.
|
||||||
|
pub fn new_gas_price_oracle(&self) -> GasPriceOracle<Provider> {
|
||||||
|
GasPriceOracleBuilder::build(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds `eth_` core api component [`GasPriceOracle`], for given context.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GasPriceOracleBuilder;
|
||||||
|
|
||||||
|
impl GasPriceOracleBuilder {
|
||||||
|
/// Builds a [`GasPriceOracle`], for given context.
|
||||||
|
pub fn build<Provider, Pool, EvmConfig, Network, Tasks, Events>(
|
||||||
|
ctx: &EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>,
|
||||||
|
) -> GasPriceOracle<Provider>
|
||||||
|
where
|
||||||
|
Provider: BlockReaderIdExt + Clone,
|
||||||
|
{
|
||||||
|
GasPriceOracle::new(ctx.provider.clone(), ctx.config.gas_oracle, ctx.cache.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builds `eth_` core api component [`FeeHistoryCache`], for given context.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FeeHistoryCacheBuilder;
|
||||||
|
|
||||||
|
impl FeeHistoryCacheBuilder {
|
||||||
|
/// Builds a [`FeeHistoryCache`], for given context.
|
||||||
|
pub fn build<Provider, Pool, EvmConfig, Network, Tasks, Events>(
|
||||||
|
ctx: &EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>,
|
||||||
|
) -> FeeHistoryCache
|
||||||
|
where
|
||||||
|
Provider: ChainSpecProvider + BlockReaderIdExt + Clone + 'static,
|
||||||
|
Tasks: TaskSpawner,
|
||||||
|
Events: CanonStateSubscriptions,
|
||||||
|
{
|
||||||
|
let fee_history_cache =
|
||||||
|
FeeHistoryCache::new(ctx.cache.clone(), ctx.config.fee_history_cache);
|
||||||
|
|
||||||
|
let new_canonical_blocks = ctx.events.canonical_state_stream();
|
||||||
|
let fhc = fee_history_cache.clone();
|
||||||
|
let provider = ctx.provider.clone();
|
||||||
|
ctx.executor.spawn_critical(
|
||||||
|
"cache canonical blocks for fee history task",
|
||||||
|
Box::pin(async move {
|
||||||
|
fee_history_cache_new_blocks_task(fhc, new_canonical_blocks, provider).await;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
fee_history_cache
|
||||||
|
}
|
||||||
|
}
|
||||||
4
crates/rpc/rpc-eth-types/src/builder/mod.rs
Normal file
4
crates/rpc/rpc-eth-types/src/builder/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
//! `eth` namespace API builder types.
|
||||||
|
|
||||||
|
pub mod config;
|
||||||
|
pub mod ctx;
|
||||||
@ -8,6 +8,7 @@
|
|||||||
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
|
||||||
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
|
#![cfg_attr(not(test), warn(unused_crate_dependencies))]
|
||||||
|
|
||||||
|
pub mod builder;
|
||||||
pub mod cache;
|
pub mod cache;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod fee_history;
|
pub mod fee_history;
|
||||||
@ -20,6 +21,10 @@ pub mod revm_utils;
|
|||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
|
pub use builder::{
|
||||||
|
config::{EthConfig, EthFilterConfig},
|
||||||
|
ctx::EthApiBuilderCtx,
|
||||||
|
};
|
||||||
pub use cache::{
|
pub use cache::{
|
||||||
config::EthStateCacheConfig, db::StateCacheDb, multi_consumer::MultiConsumerLruCache,
|
config::EthStateCacheConfig, db::StateCacheDb, multi_consumer::MultiConsumerLruCache,
|
||||||
EthStateCache,
|
EthStateCache,
|
||||||
|
|||||||
@ -33,6 +33,7 @@ reth-evm.workspace = true
|
|||||||
reth-rpc-eth-types.workspace = true
|
reth-rpc-eth-types.workspace = true
|
||||||
reth-rpc-server-types.workspace = true
|
reth-rpc-server-types.workspace = true
|
||||||
reth-evm-optimism = { workspace = true, optional = true }
|
reth-evm-optimism = { workspace = true, optional = true }
|
||||||
|
reth-node-api.workspace = true
|
||||||
|
|
||||||
# eth
|
# eth
|
||||||
alloy-dyn-abi.workspace = true
|
alloy-dyn-abi.workspace = true
|
||||||
|
|||||||
@ -1,25 +1,26 @@
|
|||||||
//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`](crate::EthApi) trait
|
//! Implementation of the [`jsonrpsee`] generated [`EthApiServer`](crate::EthApi) trait
|
||||||
//! Handles RPC requests for the `eth_` namespace.
|
//! Handles RPC requests for the `eth_` namespace.
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use derive_more::Deref;
|
use derive_more::Deref;
|
||||||
|
use futures::Future;
|
||||||
|
use reth_node_api::{BuilderProvider, FullNodeComponents};
|
||||||
use reth_primitives::{BlockNumberOrTag, U256};
|
use reth_primitives::{BlockNumberOrTag, U256};
|
||||||
use reth_provider::BlockReaderIdExt;
|
use reth_provider::{BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider};
|
||||||
use reth_rpc_eth_api::{
|
use reth_rpc_eth_api::{
|
||||||
helpers::{transaction::UpdateRawTxForwarder, EthSigner, SpawnBlocking},
|
helpers::{transaction::UpdateRawTxForwarder, EthSigner, SpawnBlocking},
|
||||||
RawTransactionForwarder,
|
RawTransactionForwarder,
|
||||||
};
|
};
|
||||||
use reth_rpc_eth_types::{EthStateCache, FeeHistoryCache, GasCap, GasPriceOracle, PendingBlock};
|
use reth_rpc_eth_types::{
|
||||||
|
EthApiBuilderCtx, EthStateCache, FeeHistoryCache, GasCap, GasPriceOracle, PendingBlock,
|
||||||
|
};
|
||||||
use reth_tasks::{
|
use reth_tasks::{
|
||||||
pool::{BlockingTaskGuard, BlockingTaskPool},
|
pool::{BlockingTaskGuard, BlockingTaskPool},
|
||||||
TaskSpawner, TokioTaskExecutor,
|
TaskExecutor, TaskSpawner, TokioTaskExecutor,
|
||||||
};
|
};
|
||||||
use tokio::sync::{AcquireError, Mutex, OwnedSemaphorePermit};
|
use tokio::sync::{AcquireError, Mutex, OwnedSemaphorePermit};
|
||||||
|
|
||||||
use crate::eth::DevSigner;
|
|
||||||
|
|
||||||
/// `Eth` API implementation.
|
/// `Eth` API implementation.
|
||||||
///
|
///
|
||||||
/// This type provides the functionality for handling `eth_` related requests.
|
/// This type provides the functionality for handling `eth_` related requests.
|
||||||
@ -55,66 +56,59 @@ where
|
|||||||
raw_transaction_forwarder: Option<Arc<dyn RawTransactionForwarder>>,
|
raw_transaction_forwarder: Option<Arc<dyn RawTransactionForwarder>>,
|
||||||
proof_permits: usize,
|
proof_permits: usize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self::with_spawner(
|
let inner = EthApiInner::new(
|
||||||
provider,
|
provider,
|
||||||
pool,
|
pool,
|
||||||
network,
|
network,
|
||||||
eth_cache,
|
eth_cache,
|
||||||
gas_oracle,
|
gas_oracle,
|
||||||
gas_cap.into().into(),
|
|
||||||
eth_proof_window,
|
|
||||||
Box::<TokioTaskExecutor>::default(),
|
|
||||||
blocking_task_pool,
|
|
||||||
fee_history_cache,
|
|
||||||
evm_config,
|
|
||||||
raw_transaction_forwarder,
|
|
||||||
proof_permits,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a new, shareable instance.
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub fn with_spawner(
|
|
||||||
provider: Provider,
|
|
||||||
pool: Pool,
|
|
||||||
network: Network,
|
|
||||||
eth_cache: EthStateCache,
|
|
||||||
gas_oracle: GasPriceOracle<Provider>,
|
|
||||||
gas_cap: u64,
|
|
||||||
eth_proof_window: u64,
|
|
||||||
task_spawner: Box<dyn TaskSpawner>,
|
|
||||||
blocking_task_pool: BlockingTaskPool,
|
|
||||||
fee_history_cache: FeeHistoryCache,
|
|
||||||
evm_config: EvmConfig,
|
|
||||||
raw_transaction_forwarder: Option<Arc<dyn RawTransactionForwarder>>,
|
|
||||||
proof_permits: usize,
|
|
||||||
) -> Self {
|
|
||||||
// get the block number of the latest block
|
|
||||||
let latest_block = provider
|
|
||||||
.header_by_number_or_tag(BlockNumberOrTag::Latest)
|
|
||||||
.ok()
|
|
||||||
.flatten()
|
|
||||||
.map(|header| header.number)
|
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let inner = EthApiInner {
|
|
||||||
provider,
|
|
||||||
pool,
|
|
||||||
network,
|
|
||||||
signers: parking_lot::RwLock::new(Default::default()),
|
|
||||||
eth_cache,
|
|
||||||
gas_oracle,
|
|
||||||
gas_cap,
|
gas_cap,
|
||||||
eth_proof_window,
|
eth_proof_window,
|
||||||
starting_block: U256::from(latest_block),
|
|
||||||
task_spawner,
|
|
||||||
pending_block: Default::default(),
|
|
||||||
blocking_task_pool,
|
blocking_task_pool,
|
||||||
fee_history_cache,
|
fee_history_cache,
|
||||||
evm_config,
|
evm_config,
|
||||||
raw_transaction_forwarder: parking_lot::RwLock::new(raw_transaction_forwarder),
|
TokioTaskExecutor::default(),
|
||||||
blocking_task_guard: BlockingTaskGuard::new(proof_permits),
|
raw_transaction_forwarder,
|
||||||
};
|
proof_permits,
|
||||||
|
);
|
||||||
|
|
||||||
|
Self { inner: Arc::new(inner) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Provider, Pool, EvmConfig, Network> EthApi<Provider, Pool, Network, EvmConfig>
|
||||||
|
where
|
||||||
|
Provider: ChainSpecProvider + BlockReaderIdExt + Clone + 'static,
|
||||||
|
Pool: Clone,
|
||||||
|
EvmConfig: Clone,
|
||||||
|
Network: Clone,
|
||||||
|
{
|
||||||
|
/// Creates a new, shareable instance.
|
||||||
|
pub fn with_spawner<Tasks, Events>(
|
||||||
|
ctx: &EthApiBuilderCtx<Provider, Pool, EvmConfig, Network, Tasks, Events>,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Tasks: TaskSpawner + Clone + 'static,
|
||||||
|
Events: CanonStateSubscriptions,
|
||||||
|
{
|
||||||
|
let blocking_task_pool =
|
||||||
|
BlockingTaskPool::build().expect("failed to build blocking task pool");
|
||||||
|
|
||||||
|
let inner = EthApiInner::new(
|
||||||
|
ctx.provider.clone(),
|
||||||
|
ctx.pool.clone(),
|
||||||
|
ctx.network.clone(),
|
||||||
|
ctx.cache.clone(),
|
||||||
|
ctx.new_gas_price_oracle(),
|
||||||
|
ctx.config.rpc_gas_cap,
|
||||||
|
ctx.config.eth_proof_window,
|
||||||
|
blocking_task_pool,
|
||||||
|
ctx.new_fee_history_cache(),
|
||||||
|
ctx.evm_config.clone(),
|
||||||
|
ctx.executor.clone(),
|
||||||
|
None,
|
||||||
|
ctx.config.proof_permits,
|
||||||
|
);
|
||||||
|
|
||||||
Self { inner: Arc::new(inner) }
|
Self { inner: Arc::new(inner) }
|
||||||
}
|
}
|
||||||
@ -163,12 +157,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Provider, Pool, Network, EvmConfig> EthApi<Provider, Pool, Network, EvmConfig> {
|
impl<N, Network> BuilderProvider<N> for EthApi<N::Provider, N::Pool, Network, N::Evm>
|
||||||
/// Generates 20 random developer accounts.
|
where
|
||||||
/// Used in DEV mode.
|
N: FullNodeComponents,
|
||||||
pub fn with_dev_accounts(&self) {
|
Network: Send + Sync + Clone + 'static,
|
||||||
let mut signers = self.inner.signers.write();
|
{
|
||||||
*signers = DevSigner::random_signers(20);
|
type Ctx<'a> =
|
||||||
|
&'a EthApiBuilderCtx<N::Provider, N::Pool, N::Evm, Network, TaskExecutor, N::Provider>;
|
||||||
|
|
||||||
|
fn builder() -> Box<dyn for<'a> Fn(Self::Ctx<'a>) -> Self + Send> {
|
||||||
|
Box::new(|ctx| Self::with_spawner(ctx))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,6 +207,59 @@ pub struct EthApiInner<Provider, Pool, Network, EvmConfig> {
|
|||||||
blocking_task_guard: BlockingTaskGuard,
|
blocking_task_guard: BlockingTaskGuard,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<Provider, Pool, Network, EvmConfig> EthApiInner<Provider, Pool, Network, EvmConfig>
|
||||||
|
where
|
||||||
|
Provider: BlockReaderIdExt,
|
||||||
|
{
|
||||||
|
/// Creates a new, shareable instance using the default tokio task spawner.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn new(
|
||||||
|
provider: Provider,
|
||||||
|
pool: Pool,
|
||||||
|
network: Network,
|
||||||
|
eth_cache: EthStateCache,
|
||||||
|
gas_oracle: GasPriceOracle<Provider>,
|
||||||
|
gas_cap: impl Into<GasCap>,
|
||||||
|
eth_proof_window: u64,
|
||||||
|
blocking_task_pool: BlockingTaskPool,
|
||||||
|
fee_history_cache: FeeHistoryCache,
|
||||||
|
evm_config: EvmConfig,
|
||||||
|
task_spawner: impl TaskSpawner + 'static,
|
||||||
|
raw_transaction_forwarder: Option<Arc<dyn RawTransactionForwarder>>,
|
||||||
|
proof_permits: usize,
|
||||||
|
) -> Self {
|
||||||
|
let signers = parking_lot::RwLock::new(Default::default());
|
||||||
|
// get the block number of the latest block
|
||||||
|
let starting_block = U256::from(
|
||||||
|
provider
|
||||||
|
.header_by_number_or_tag(BlockNumberOrTag::Latest)
|
||||||
|
.ok()
|
||||||
|
.flatten()
|
||||||
|
.map(|header| header.number)
|
||||||
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
provider,
|
||||||
|
pool,
|
||||||
|
network,
|
||||||
|
signers,
|
||||||
|
eth_cache,
|
||||||
|
gas_oracle,
|
||||||
|
gas_cap: gas_cap.into().into(),
|
||||||
|
eth_proof_window,
|
||||||
|
starting_block,
|
||||||
|
task_spawner: Box::new(task_spawner),
|
||||||
|
pending_block: Default::default(),
|
||||||
|
blocking_task_pool,
|
||||||
|
fee_history_cache,
|
||||||
|
evm_config,
|
||||||
|
raw_transaction_forwarder: parking_lot::RwLock::new(raw_transaction_forwarder),
|
||||||
|
blocking_task_guard: BlockingTaskGuard::new(proof_permits),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<Provider, Pool, Network, EvmConfig> EthApiInner<Provider, Pool, Network, EvmConfig> {
|
impl<Provider, Pool, Network, EvmConfig> EthApiInner<Provider, Pool, Network, EvmConfig> {
|
||||||
/// Returns a handle to data on disk.
|
/// Returns a handle to data on disk.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
@ -17,7 +17,7 @@ use reth_provider::{BlockIdReader, BlockReader, EvmEnvProvider, ProviderError};
|
|||||||
use reth_rpc_eth_api::EthFilterApiServer;
|
use reth_rpc_eth_api::EthFilterApiServer;
|
||||||
use reth_rpc_eth_types::{
|
use reth_rpc_eth_types::{
|
||||||
logs_utils::{self, append_matching_block_logs},
|
logs_utils::{self, append_matching_block_logs},
|
||||||
EthApiError, EthFilterError, EthStateCache, EthSubscriptionIdProvider,
|
EthApiError, EthFilterConfig, EthFilterError, EthStateCache, EthSubscriptionIdProvider,
|
||||||
};
|
};
|
||||||
use reth_rpc_server_types::ToRpcResult;
|
use reth_rpc_server_types::ToRpcResult;
|
||||||
use reth_rpc_types::{
|
use reth_rpc_types::{
|
||||||
@ -515,56 +515,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Config for the filter
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
||||||
pub struct EthFilterConfig {
|
|
||||||
/// Maximum number of blocks that a filter can scan for logs.
|
|
||||||
///
|
|
||||||
/// If `None` then no limit is enforced.
|
|
||||||
pub max_blocks_per_filter: Option<u64>,
|
|
||||||
/// Maximum number of logs that can be returned in a single response in `eth_getLogs` calls.
|
|
||||||
///
|
|
||||||
/// If `None` then no limit is enforced.
|
|
||||||
pub max_logs_per_response: Option<usize>,
|
|
||||||
/// How long a filter remains valid after the last poll.
|
|
||||||
///
|
|
||||||
/// A filter is considered stale if it has not been polled for longer than this duration and
|
|
||||||
/// will be removed.
|
|
||||||
pub stale_filter_ttl: Duration,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EthFilterConfig {
|
|
||||||
/// Sets the maximum number of blocks that a filter can scan for logs.
|
|
||||||
pub const fn max_blocks_per_filter(mut self, num: u64) -> Self {
|
|
||||||
self.max_blocks_per_filter = Some(num);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the maximum number of logs that can be returned in a single response in `eth_getLogs`
|
|
||||||
/// calls.
|
|
||||||
pub const fn max_logs_per_response(mut self, num: usize) -> Self {
|
|
||||||
self.max_logs_per_response = Some(num);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets how long a filter remains valid after the last poll before it will be removed.
|
|
||||||
pub const fn stale_filter_ttl(mut self, duration: Duration) -> Self {
|
|
||||||
self.stale_filter_ttl = duration;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for EthFilterConfig {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
max_blocks_per_filter: None,
|
|
||||||
max_logs_per_response: None,
|
|
||||||
// 5min
|
|
||||||
stale_filter_ttl: Duration::from_secs(5 * 60),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// All active filters
|
/// All active filters
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct ActiveFilters {
|
pub struct ActiveFilters {
|
||||||
|
|||||||
@ -6,12 +6,26 @@ use alloy_dyn_abi::TypedData;
|
|||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
eip191_hash_message, sign_message, Address, Signature, TransactionSigned, B256,
|
eip191_hash_message, sign_message, Address, Signature, TransactionSigned, B256,
|
||||||
};
|
};
|
||||||
use reth_rpc_eth_api::helpers::{signer::Result, EthSigner};
|
use reth_rpc_eth_api::helpers::{signer::Result, AddDevSigners, EthSigner};
|
||||||
use reth_rpc_eth_types::SignError;
|
use reth_rpc_eth_types::SignError;
|
||||||
use reth_rpc_types::TypedTransactionRequest;
|
use reth_rpc_types::TypedTransactionRequest;
|
||||||
use reth_rpc_types_compat::transaction::to_primitive_transaction;
|
use reth_rpc_types_compat::transaction::to_primitive_transaction;
|
||||||
use secp256k1::SecretKey;
|
use secp256k1::SecretKey;
|
||||||
|
|
||||||
|
use crate::EthApi;
|
||||||
|
|
||||||
|
impl<Provider, Pool, Network, EvmConfig> AddDevSigners
|
||||||
|
for EthApi<Provider, Pool, Network, EvmConfig>
|
||||||
|
{
|
||||||
|
fn signers(&self) -> &parking_lot::RwLock<Vec<Box<dyn EthSigner>>> {
|
||||||
|
self.inner.signers()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_dev_accounts(&self) {
|
||||||
|
*self.signers().write() = DevSigner::random_signers(20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Holds developer keys
|
/// Holds developer keys
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DevSigner {
|
pub struct DevSigner {
|
||||||
@ -22,14 +36,14 @@ pub struct DevSigner {
|
|||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
impl DevSigner {
|
impl DevSigner {
|
||||||
/// Generates a random dev signer which satisfies [`EthSigner`] trait
|
/// Generates a random dev signer which satisfies [`EthSigner`] trait
|
||||||
pub(crate) fn random() -> Box<dyn EthSigner> {
|
pub fn random() -> Box<dyn EthSigner> {
|
||||||
let mut signers = Self::random_signers(1);
|
let mut signers = Self::random_signers(1);
|
||||||
signers.pop().expect("expect to generate at least one signer")
|
signers.pop().expect("expect to generate at least one signer")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates provided number of random dev signers
|
/// Generates provided number of random dev signers
|
||||||
/// which satisfy [`EthSigner`] trait
|
/// which satisfy [`EthSigner`] trait
|
||||||
pub(crate) fn random_signers(num: u32) -> Vec<Box<dyn EthSigner + 'static>> {
|
pub fn random_signers(num: u32) -> Vec<Box<dyn EthSigner + 'static>> {
|
||||||
let mut signers = Vec::new();
|
let mut signers = Vec::new();
|
||||||
for _ in 0..num {
|
for _ in 0..num {
|
||||||
let (sk, pk) = secp256k1::generate_keypair(&mut rand::thread_rng());
|
let (sk, pk) = secp256k1::generate_keypair(&mut rand::thread_rng());
|
||||||
|
|||||||
@ -9,9 +9,9 @@ pub mod pubsub;
|
|||||||
/// Implementation of `eth` namespace API.
|
/// Implementation of `eth` namespace API.
|
||||||
pub use bundle::EthBundle;
|
pub use bundle::EthBundle;
|
||||||
pub use core::EthApi;
|
pub use core::EthApi;
|
||||||
pub use filter::{EthFilter, EthFilterConfig};
|
pub use filter::EthFilter;
|
||||||
pub use pubsub::EthPubSub;
|
pub use pubsub::EthPubSub;
|
||||||
|
|
||||||
pub use helpers::signer::DevSigner;
|
pub use helpers::signer::DevSigner;
|
||||||
|
|
||||||
pub use reth_rpc_eth_api::RawTransactionForwarder;
|
pub use reth_rpc_eth_api::{EthApiServer, RawTransactionForwarder};
|
||||||
|
|||||||
@ -46,7 +46,8 @@ use reth_node_api::{
|
|||||||
};
|
};
|
||||||
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
||||||
use reth_node_ethereum::node::{
|
use reth_node_ethereum::node::{
|
||||||
EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder, EthereumPoolBuilder,
|
EthereumAddOns, EthereumConsensusBuilder, EthereumExecutorBuilder, EthereumNetworkBuilder,
|
||||||
|
EthereumPoolBuilder,
|
||||||
};
|
};
|
||||||
use reth_payload_builder::{
|
use reth_payload_builder::{
|
||||||
error::PayloadBuilderError, EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderHandle,
|
error::PayloadBuilderError, EthBuiltPayload, EthPayloadBuilderAttributes, PayloadBuilderHandle,
|
||||||
@ -212,8 +213,9 @@ where
|
|||||||
EthereumExecutorBuilder,
|
EthereumExecutorBuilder,
|
||||||
EthereumConsensusBuilder,
|
EthereumConsensusBuilder,
|
||||||
>;
|
>;
|
||||||
|
type AddOns = EthereumAddOns;
|
||||||
|
|
||||||
fn components_builder(self) -> Self::ComponentsBuilder {
|
fn components_builder(&self) -> Self::ComponentsBuilder {
|
||||||
ComponentsBuilder::default()
|
ComponentsBuilder::default()
|
||||||
.node_types::<N>()
|
.node_types::<N>()
|
||||||
.pool(EthereumPoolBuilder::default())
|
.pool(EthereumPoolBuilder::default())
|
||||||
|
|||||||
@ -22,7 +22,7 @@ use reth_chainspec::{Chain, ChainSpec, Head};
|
|||||||
use reth_evm_ethereum::EthEvmConfig;
|
use reth_evm_ethereum::EthEvmConfig;
|
||||||
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes};
|
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes};
|
||||||
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
||||||
use reth_node_ethereum::{EthExecutorProvider, EthereumNode};
|
use reth_node_ethereum::{node::EthereumAddOns, EthExecutorProvider, EthereumNode};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
revm_primitives::{AnalysisKind, CfgEnvWithHandlerCfg, TxEnv},
|
||||||
Address, Header, TransactionSigned, U256,
|
Address, Header, TransactionSigned, U256,
|
||||||
@ -180,6 +180,7 @@ async fn main() -> eyre::Result<()> {
|
|||||||
.with_types::<EthereumNode>()
|
.with_types::<EthereumNode>()
|
||||||
// use default ethereum components but with our executor
|
// use default ethereum components but with our executor
|
||||||
.with_components(EthereumNode::components().executor(MyExecutorBuilder::default()))
|
.with_components(EthereumNode::components().executor(MyExecutorBuilder::default()))
|
||||||
|
.with_add_ons::<EthereumAddOns>()
|
||||||
.launch()
|
.launch()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@ -10,7 +10,7 @@ use reth::{
|
|||||||
blobstore::InMemoryBlobStore, EthTransactionPool, TransactionValidationTaskExecutor,
|
blobstore::InMemoryBlobStore, EthTransactionPool, TransactionValidationTaskExecutor,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use reth_node_ethereum::EthereumNode;
|
use reth_node_ethereum::{node::EthereumAddOns, EthereumNode};
|
||||||
use reth_tracing::tracing::{debug, info};
|
use reth_tracing::tracing::{debug, info};
|
||||||
use reth_transaction_pool::PoolConfig;
|
use reth_transaction_pool::PoolConfig;
|
||||||
|
|
||||||
@ -23,6 +23,7 @@ fn main() {
|
|||||||
// Configure the components of the node
|
// Configure the components of the node
|
||||||
// use default ethereum components but use our custom pool
|
// use default ethereum components but use our custom pool
|
||||||
.with_components(EthereumNode::components().pool(CustomPoolBuilder::default()))
|
.with_components(EthereumNode::components().pool(CustomPoolBuilder::default()))
|
||||||
|
.with_add_ons::<EthereumAddOns>()
|
||||||
.launch()
|
.launch()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -20,7 +20,7 @@ use reth::{
|
|||||||
transaction_pool::TransactionPool,
|
transaction_pool::TransactionPool,
|
||||||
};
|
};
|
||||||
use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig;
|
use reth_basic_payload_builder::BasicPayloadJobGeneratorConfig;
|
||||||
use reth_node_ethereum::{EthEngineTypes, EthereumNode};
|
use reth_node_ethereum::{node::EthereumAddOns, EthEngineTypes, EthereumNode};
|
||||||
use reth_payload_builder::PayloadBuilderService;
|
use reth_payload_builder::PayloadBuilderService;
|
||||||
|
|
||||||
pub mod generator;
|
pub mod generator;
|
||||||
@ -78,6 +78,7 @@ fn main() {
|
|||||||
.with_components(
|
.with_components(
|
||||||
EthereumNode::components().payload(CustomPayloadBuilder::default()),
|
EthereumNode::components().payload(CustomPayloadBuilder::default()),
|
||||||
)
|
)
|
||||||
|
.with_add_ons::<EthereumAddOns>()
|
||||||
.launch()
|
.launch()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,7 @@ use reth::{
|
|||||||
providers::{BlockchainProvider, StaticFileProvider},
|
providers::{BlockchainProvider, StaticFileProvider},
|
||||||
ProviderFactory,
|
ProviderFactory,
|
||||||
},
|
},
|
||||||
|
rpc::eth::EthApi,
|
||||||
utils::open_db_read_only,
|
utils::open_db_read_only,
|
||||||
};
|
};
|
||||||
use reth_chainspec::ChainSpecBuilder;
|
use reth_chainspec::ChainSpecBuilder;
|
||||||
@ -27,7 +28,7 @@ use reth_db_api::models::ClientVersion;
|
|||||||
|
|
||||||
// Bringing up the RPC
|
// Bringing up the RPC
|
||||||
use reth::rpc::builder::{
|
use reth::rpc::builder::{
|
||||||
EthApiBuild, RethRpcModule, RpcModuleBuilder, RpcServerConfig, TransportRpcModuleConfig,
|
RethRpcModule, RpcModuleBuilder, RpcServerConfig, TransportRpcModuleConfig,
|
||||||
};
|
};
|
||||||
// Configuring the network parts, ideally also wouldn't need to think about this.
|
// Configuring the network parts, ideally also wouldn't need to think about this.
|
||||||
use myrpc_ext::{MyRpcExt, MyRpcExtApiServer};
|
use myrpc_ext::{MyRpcExt, MyRpcExtApiServer};
|
||||||
@ -70,7 +71,7 @@ async fn main() -> eyre::Result<()> {
|
|||||||
|
|
||||||
// Pick which namespaces to expose.
|
// Pick which namespaces to expose.
|
||||||
let config = TransportRpcModuleConfig::default().with_http([RethRpcModule::Eth]);
|
let config = TransportRpcModuleConfig::default().with_http([RethRpcModule::Eth]);
|
||||||
let mut server = rpc_builder.build(config, EthApiBuild::build);
|
let mut server = rpc_builder.build(config, Box::new(EthApi::with_spawner));
|
||||||
|
|
||||||
// Add a custom rpc namespace
|
// Add a custom rpc namespace
|
||||||
let custom_rpc = MyRpcExt { provider };
|
let custom_rpc = MyRpcExt { provider };
|
||||||
|
|||||||
@ -21,7 +21,7 @@ use reth::{
|
|||||||
use reth_chainspec::{Chain, ChainSpec};
|
use reth_chainspec::{Chain, ChainSpec};
|
||||||
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes};
|
use reth_node_api::{ConfigureEvm, ConfigureEvmEnv, FullNodeTypes};
|
||||||
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
use reth_node_core::{args::RpcServerArgs, node_config::NodeConfig};
|
||||||
use reth_node_ethereum::{EthEvmConfig, EthExecutorProvider, EthereumNode};
|
use reth_node_ethereum::{node::EthereumAddOns, EthEvmConfig, EthExecutorProvider, EthereumNode};
|
||||||
use reth_primitives::{
|
use reth_primitives::{
|
||||||
revm_primitives::{SpecId, StatefulPrecompileMut},
|
revm_primitives::{SpecId, StatefulPrecompileMut},
|
||||||
Header, TransactionSigned,
|
Header, TransactionSigned,
|
||||||
@ -244,6 +244,7 @@ async fn main() -> eyre::Result<()> {
|
|||||||
.with_types::<EthereumNode>()
|
.with_types::<EthereumNode>()
|
||||||
// use default ethereum components but with our executor
|
// use default ethereum components but with our executor
|
||||||
.with_components(EthereumNode::components().executor(MyExecutorBuilder::default()))
|
.with_components(EthereumNode::components().executor(MyExecutorBuilder::default()))
|
||||||
|
.with_add_ons::<EthereumAddOns>()
|
||||||
.launch()
|
.launch()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
Reference in New Issue
Block a user