feat: type erase concrete engine server trait (#14204)

This commit is contained in:
Matthias Seitz
2025-02-04 13:58:11 +01:00
committed by GitHub
parent 07090b315c
commit 7fb74066b8
4 changed files with 34 additions and 22 deletions

View File

@ -16,8 +16,19 @@ use alloy_rpc_types_eth::{
EIP1186AccountProofResponse, Filter, Log, SyncStatus, EIP1186AccountProofResponse, Filter, Log, SyncStatus,
}; };
use alloy_serde::JsonStorageKey; use alloy_serde::JsonStorageKey;
use jsonrpsee::{core::RpcResult, proc_macros::rpc}; use jsonrpsee::{core::RpcResult, proc_macros::rpc, RpcModule};
use reth_engine_primitives::EngineTypes; use reth_engine_primitives::EngineTypes;
/// Helper trait for the engine api server.
///
/// This type-erases the concrete [`jsonrpsee`] server implementation and only returns the
/// [`RpcModule`] that contains all the endpoints of the server.
pub trait IntoEngineApiRpcModule {
/// Consumes the type and returns all the methods and subscriptions defined in the trait and
/// returns them as a single [`RpcModule`]
fn into_rpc_module(self) -> RpcModule<()>;
}
// NOTE: We can't use associated types in the `EngineApi` trait because of jsonrpsee, so we use a // NOTE: We can't use associated types in the `EngineApi` trait because of jsonrpsee, so we use a
// generic here. It would be nice if the rpc macro would understand which types need to have serde. // generic here. It would be nice if the rpc macro would understand which types need to have serde.
// By default, if the trait has a generic, the rpc macro will add e.g. `Engine: DeserializeOwned` to // By default, if the trait has a generic, the rpc macro will add e.g. `Engine: DeserializeOwned` to

View File

@ -39,7 +39,7 @@ pub mod servers {
pub use crate::{ pub use crate::{
admin::AdminApiServer, admin::AdminApiServer,
debug::{DebugApiServer, DebugExecutionWitnessApiServer}, debug::{DebugApiServer, DebugExecutionWitnessApiServer},
engine::{EngineApiServer, EngineEthApiServer}, engine::{EngineApiServer, EngineEthApiServer, IntoEngineApiRpcModule},
mev::{MevFullApiServer, MevSimApiServer}, mev::{MevFullApiServer, MevSimApiServer},
miner::MinerApiServer, miner::MinerApiServer,
net::NetApiServer, net::NetApiServer,

View File

@ -89,14 +89,14 @@
//! //!
//! ``` //! ```
//! use reth_consensus::{ConsensusError, FullConsensus}; //! use reth_consensus::{ConsensusError, FullConsensus};
//! use reth_engine_primitives::{EngineTypes, ExecutionData, PayloadValidator}; //! use reth_engine_primitives::{ExecutionData, PayloadValidator};
//! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; //! use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
//! use reth_evm_ethereum::EthEvmConfig; //! use reth_evm_ethereum::EthEvmConfig;
//! use reth_network_api::{NetworkInfo, Peers}; //! use reth_network_api::{NetworkInfo, Peers};
//! use reth_primitives::{Header, PooledTransaction, TransactionSigned}; //! use reth_primitives::{Header, PooledTransaction, TransactionSigned};
//! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider}; //! use reth_provider::{AccountReader, CanonStateSubscriptions, ChangeSetReader, FullRpcProvider};
//! use reth_rpc::EthApi; //! use reth_rpc::EthApi;
//! use reth_rpc_api::EngineApiServer; //! use reth_rpc_api::{EngineApiServer, IntoEngineApiRpcModule};
//! use reth_rpc_builder::{ //! use reth_rpc_builder::{
//! auth::AuthServerConfig, RethRpcModule, RpcModuleBuilder, RpcServerConfig, //! auth::AuthServerConfig, RethRpcModule, RpcModuleBuilder, RpcServerConfig,
//! TransportRpcModuleConfig, //! TransportRpcModuleConfig,
@ -120,7 +120,7 @@
//! provider: Provider, //! provider: Provider,
//! pool: Pool, //! pool: Pool,
//! network: Network, //! network: Network,
//! engine_api: EngineApi, //! engine_api: impl IntoEngineApiRpcModule,
//! evm_config: EthEvmConfig, //! evm_config: EthEvmConfig,
//! block_executor: BlockExecutor, //! block_executor: BlockExecutor,
//! consensus: Consensus, //! consensus: Consensus,
@ -142,8 +142,6 @@
//! > + Unpin //! > + Unpin
//! + 'static, //! + 'static,
//! Network: NetworkInfo + Peers + Clone + 'static, //! Network: NetworkInfo + Peers + Clone + 'static,
//! EngineApi: EngineApiServer<EngineT>,
//! EngineT: EngineTypes,
//! BlockExecutor: BlockExecutorProvider<Primitives = Provider::Primitives>, //! BlockExecutor: BlockExecutorProvider<Primitives = Provider::Primitives>,
//! Consensus: FullConsensus<Provider::Primitives, Error = ConsensusError> + Clone + 'static, //! Consensus: FullConsensus<Provider::Primitives, Error = ConsensusError> + Clone + 'static,
//! Validator: PayloadValidator<Block = reth_primitives::Block, ExecutionData = ExecutionData>, //! Validator: PayloadValidator<Block = reth_primitives::Block, ExecutionData = ExecutionData>,
@ -213,7 +211,7 @@ use jsonrpsee::{
}; };
use reth_chainspec::EthereumHardforks; use reth_chainspec::EthereumHardforks;
use reth_consensus::{ConsensusError, FullConsensus}; use reth_consensus::{ConsensusError, FullConsensus};
use reth_engine_primitives::{EngineTypes, ExecutionData, PayloadValidator}; use reth_engine_primitives::{ExecutionData, PayloadValidator};
use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm}; use reth_evm::{execute::BlockExecutorProvider, ConfigureEvm};
use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers}; use reth_network_api::{noop::NoopNetwork, NetworkInfo, Peers};
use reth_primitives::NodePrimitives; use reth_primitives::NodePrimitives;
@ -611,10 +609,10 @@ 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>( pub fn build_with_auth_server<EthApi>(
self, self,
module_config: TransportRpcModuleConfig, module_config: TransportRpcModuleConfig,
engine: EngineApi, engine: impl IntoEngineApiRpcModule,
eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, EthApi>, eth: DynEthApiBuilder<Provider, Pool, EvmConfig, Network, Tasks, EthApi>,
payload_validator: Arc< payload_validator: Arc<
dyn PayloadValidator<Block = Provider::Block, ExecutionData = ExecutionData>, dyn PayloadValidator<Block = Provider::Block, ExecutionData = ExecutionData>,
@ -625,8 +623,6 @@ where
RpcRegistryInner<Provider, Pool, Network, Tasks, EthApi, BlockExecutor, Consensus>, RpcRegistryInner<Provider, Pool, Network, Tasks, EthApi, BlockExecutor, Consensus>,
) )
where where
EngineT: EngineTypes,
EngineApi: EngineApiServer<EngineT>,
EthApi: FullEthApiServer< EthApi: FullEthApiServer<
Provider: BlockReader< Provider: BlockReader<
Block = <BlockExecutor::Primitives as NodePrimitives>::Block, Block = <BlockExecutor::Primitives as NodePrimitives>::Block,
@ -1268,14 +1264,8 @@ where
/// * `api_` namespace /// * `api_` namespace
/// ///
/// Note: This does _not_ register the `engine_` in this registry. /// Note: This does _not_ register the `engine_` in this registry.
pub fn create_auth_module<EngineApi, EngineT>(&self, engine_api: EngineApi) -> AuthRpcModule pub fn create_auth_module(&self, engine_api: impl IntoEngineApiRpcModule) -> AuthRpcModule {
where let mut module = engine_api.into_rpc_module();
EngineT: EngineTypes,
EngineApi: EngineApiServer<EngineT>,
{
let mut module = RpcModule::new(());
module.merge(engine_api.into_rpc()).expect("No conflicting methods");
// also merge a subset of `eth_` handlers // also merge a subset of `eth_` handlers
let eth_handlers = self.eth_handlers(); let eth_handlers = self.eth_handlers();

View File

@ -15,7 +15,7 @@ use alloy_rpc_types_engine::{
PraguePayloadFields, TransitionConfiguration, PraguePayloadFields, TransitionConfiguration,
}; };
use async_trait::async_trait; use async_trait::async_trait;
use jsonrpsee_core::RpcResult; use jsonrpsee_core::{server::RpcModule, RpcResult};
use parking_lot::Mutex; use parking_lot::Mutex;
use reth_chainspec::{EthereumHardfork, EthereumHardforks}; use reth_chainspec::{EthereumHardfork, EthereumHardforks};
use reth_engine_primitives::{ use reth_engine_primitives::{
@ -27,7 +27,7 @@ use reth_payload_primitives::{
PayloadOrAttributes, PayloadOrAttributes,
}; };
use reth_primitives_traits::{Block, BlockBody}; use reth_primitives_traits::{Block, BlockBody};
use reth_rpc_api::EngineApiServer; use reth_rpc_api::{EngineApiServer, IntoEngineApiRpcModule};
use reth_storage_api::{BlockReader, HeaderProvider, StateProviderFactory}; use reth_storage_api::{BlockReader, HeaderProvider, StateProviderFactory};
use reth_tasks::TaskSpawner; use reth_tasks::TaskSpawner;
use reth_transaction_pool::TransactionPool; use reth_transaction_pool::TransactionPool;
@ -1020,6 +1020,17 @@ where
} }
} }
impl<Provider, EngineT, Pool, Validator, ChainSpec> IntoEngineApiRpcModule
for EngineApi<Provider, EngineT, Pool, Validator, ChainSpec>
where
EngineT: EngineTypes,
Self: EngineApiServer<EngineT>,
{
fn into_rpc_module(self) -> RpcModule<()> {
self.into_rpc().remove_context()
}
}
impl<Provider, EngineT, Pool, Validator, ChainSpec> std::fmt::Debug impl<Provider, EngineT, Pool, Validator, ChainSpec> std::fmt::Debug
for EngineApi<Provider, EngineT, Pool, Validator, ChainSpec> for EngineApi<Provider, EngineT, Pool, Validator, ChainSpec>
where where