fix: rpc-builder crate compilation (#6371)

This commit is contained in:
Matthias Seitz
2024-02-03 20:58:42 +01:00
committed by GitHub
parent 4dc6aeefa9
commit 10f4434373
11 changed files with 59 additions and 49 deletions

2
Cargo.lock generated
View File

@ -6763,7 +6763,6 @@ dependencies = [
"reth-network-api",
"reth-node-api",
"reth-node-ethereum",
"reth-node-optimism",
"reth-payload-builder",
"reth-primitives",
"reth-provider",
@ -7192,6 +7191,7 @@ dependencies = [
"futures",
"jsonrpsee",
"reth",
"reth-node-ethereum",
"tokio",
]

View File

@ -115,7 +115,7 @@
//!
//! /// Custom engine types - uses a custom payload attributes RPC type, but uses the default
//! /// payload builder attributes type.
//! #[derive(Clone, Debug, Default)]
//! #[derive(Clone, Debug, Default, serde::Deserialize)]
//! #[non_exhaustive]
//! pub struct CustomEngineTypes;
//!
@ -150,7 +150,7 @@ pub mod payload;
pub use payload::PayloadOrAttributes;
/// The types that are used by the engine.
pub trait EngineTypes: Send + Sync {
pub trait EngineTypes: serde::de::DeserializeOwned + Send + Sync {
/// The RPC payload attributes type the CL node emits via the engine API.
type PayloadAttributes: PayloadAttributes + Unpin;

View File

@ -273,7 +273,7 @@ impl RpcServerArgs {
/// Returns the handles for the launched regular RPC server(s) (if any) and the server handle
/// for the auth server that handles the `engine_` API that's accessed by the consensus
/// layer.
pub async fn start_servers<Reth, Engine, Conf, EngineT: EngineTypes>(
pub async fn start_servers<Reth, Engine, Conf, EngineT>(
&self,
components: &Reth,
engine_api: Engine,
@ -281,8 +281,9 @@ impl RpcServerArgs {
conf: &mut Conf,
) -> eyre::Result<RethRpcServerHandles>
where
Reth: RethNodeComponents,
EngineT: EngineTypes + 'static,
Engine: EngineApiServer<EngineT>,
Reth: RethNodeComponents,
Conf: RethNodeCommandConfig,
{
let auth_config = self.auth_server_config(jwt_secret)?;

View File

@ -7,7 +7,7 @@ use reth_primitives::ChainSpec;
use reth_rpc_types::engine::PayloadAttributes as EthPayloadAttributes;
/// The types used in the default mainnet ethereum beacon consensus engine.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[non_exhaustive]
pub struct EthEngineTypes;

View File

@ -7,7 +7,7 @@ use reth_primitives::{ChainSpec, Hardfork};
use reth_rpc_types::engine::OptimismPayloadAttributes;
/// The types used in the optimism beacon consensus engine.
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, serde::Deserialize)]
#[non_exhaustive]
pub struct OptimismEngineTypes;

View File

@ -1,3 +1,8 @@
//! Server traits for the engine API
//!
//! This contains the `engine_` namespace and the subset of the `eth_` namespace that is exposed to
//! the consensus client.
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use reth_node_api::EngineTypes;
use reth_primitives::{Address, BlockHash, BlockId, BlockNumberOrTag, Bytes, B256, U256, U64};
@ -11,6 +16,13 @@ use reth_rpc_types::{
BlockOverrides, CallRequest, Filter, Log, RichBlock, SyncStatus,
};
// 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.
// By default, if the trait has a generic, the rpc macro will add e.g. `Engine: DeserializeOwned` to
// the trait bounds, which is not what we want, because `Types` is not used directly in any of the
// trait methods. Instead, we have to add the bounds manually. This would be disastrous if we had
// more than one associated type used in the trait methods.
#[cfg_attr(not(feature = "client"), rpc(server, namespace = "engine"), server_bounds(Engine::PayloadAttributes: jsonrpsee::core::DeserializeOwned))]
#[cfg_attr(feature = "client", rpc(server, client, namespace = "engine", client_bounds(Engine::PayloadAttributes: jsonrpsee::core::Serialize + Clone), server_bounds(Engine::PayloadAttributes: jsonrpsee::core::DeserializeOwned)))]
pub trait EngineApi<Engine: EngineTypes> {
@ -148,13 +160,6 @@ pub trait EngineApi<Engine: EngineTypes> {
async fn exchange_capabilities(&self, capabilities: Vec<String>) -> RpcResult<Vec<String>>;
}
// 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.
// By default, if the trait has a generic, the rpc macro will add e.g. `Engine: DeserializeOwned` to
// the trait bounds, which is not what we want, because `Types` is not used directly in any of the
// trait methods. Instead, we have to add the bounds manually. This would be disastrous if we had
// more than one associated type used in the trait methods.
/// A subset of the ETH rpc interface: <https://ethereum.github.io/execution-apis/api-documentation/>
///
/// Specifically for the engine auth server: <https://github.com/ethereum/execution-apis/blob/main/src/engine/common.md#underlying-protocol>

View File

@ -13,21 +13,14 @@ workspace = true
[dependencies]
# reth
reth-primitives.workspace = true
reth-ipc.workspace = true
reth-interfaces.workspace = true
reth-network-api.workspace = true
reth-provider.workspace = true
reth-rpc.workspace = true
reth-rpc-api.workspace = true
reth-rpc-engine-api.workspace = true
reth-rpc-types.workspace = true
reth-tasks.workspace = true
reth-transaction-pool.workspace = true
reth-rpc-types-compat.workspace = true
reth-node-api.workspace = true
reth-node-optimism = { workspace = true, optional = true }
reth-node-ethereum.workspace = true
# rpc/net
jsonrpsee = { workspace = true, features = ["server"] }
@ -46,14 +39,19 @@ thiserror.workspace = true
tracing.workspace = true
[dev-dependencies]
reth-tracing.workspace = true
reth-rpc-api = { workspace = true, features = ["client"] }
reth-transaction-pool = { workspace = true, features = ["test-utils"] }
reth-provider = { workspace = true, features = ["test-utils"] }
reth-network-api.workspace = true
reth-interfaces = { workspace = true, features = ["test-utils"] }
reth-beacon-consensus.workspace = true
reth-interfaces = { workspace = true, features = ["test-utils"] }
reth-network-api.workspace = true
reth-node-ethereum.workspace = true
reth-payload-builder = { workspace = true, features = ["test-utils"] }
reth-primitives.workspace = true
reth-provider = { workspace = true, features = ["test-utils"] }
reth-rpc-api = { workspace = true, features = ["client"] }
reth-rpc-engine-api.workspace = true
reth-rpc-types.workspace = true
reth-rpc-types-compat.workspace = true
reth-tracing.workspace = true
reth-transaction-pool = { workspace = true, features = ["test-utils"] }
tokio = { workspace = true, features = ["rt", "rt-multi-thread"] }
serde_json.workspace = true

View File

@ -58,7 +58,7 @@ where
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
EngineT: EngineTypes,
EngineT: EngineTypes + 'static,
EngineApi: EngineApiServer<EngineT>,
EvmConfig: EvmEnvConfig + 'static,
{
@ -113,7 +113,7 @@ where
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
EngineT: EngineTypes,
EngineT: EngineTypes + 'static,
EngineApi: EngineApiServer<EngineT>,
EvmConfig: EvmEnvConfig + 'static,
{
@ -267,7 +267,7 @@ impl AuthRpcModule {
/// Create a new `AuthRpcModule` with the given `engine_api`.
pub fn new<EngineApi, EngineT>(engine: EngineApi) -> Self
where
EngineT: EngineTypes,
EngineT: EngineTypes + 'static,
EngineApi: EngineApiServer<EngineT>,
{
let mut module = RpcModule::new(());

View File

@ -113,7 +113,7 @@
//! Network: NetworkInfo + Peers + Clone + 'static,
//! Events: CanonStateSubscriptions + Clone + 'static,
//! EngineApi: EngineApiServer<EngineT>,
//! EngineT: EngineTypes,
//! EngineT: EngineTypes + 'static,
//! EvmConfig: EvmEnvConfig + 'static,
//! {
//! // configure the rpc module per transport
@ -168,13 +168,16 @@ use jsonrpsee::{
Methods, RpcModule,
};
use reth_node_api::{EngineTypes, EvmEnvConfig};
use reth_node_ethereum::EthEvmConfig;
use serde::{Deserialize, Serialize, Serializer};
use strum::{AsRefStr, EnumIter, EnumVariantNames, IntoStaticStr, ParseError, VariantNames};
use tower::layer::util::{Identity, Stack};
use tower_http::cors::CorsLayer;
use tracing::{instrument, trace};
use crate::{
auth::AuthRpcModule, error::WsHttpSamePortError, metrics::RpcServerMetrics,
RpcModuleSelection::Selection,
};
use constants::*;
use error::{RpcError, ServerKind};
use reth_ipc::server::IpcServer;
@ -198,11 +201,6 @@ use reth_rpc::{
use reth_rpc_api::{servers::*, EngineApiServer};
use reth_tasks::{TaskSpawner, TokioTaskExecutor};
use reth_transaction_pool::{noop::NoopTransactionPool, TransactionPool};
use crate::{
auth::AuthRpcModule, error::WsHttpSamePortError, metrics::RpcServerMetrics,
RpcModuleSelection::Selection,
};
// re-export for convenience
pub use crate::eth::{EthConfig, EthHandlers};
@ -448,7 +446,7 @@ where
///
/// This behaves exactly as [RpcModuleBuilder::build] for the [TransportRpcModules], but also
/// configures the auth (engine api) server, which exposes a subset of the `eth_` namespace.
pub fn build_with_auth_server<EngineApi, EngineT: EngineTypes>(
pub fn build_with_auth_server<EngineApi, EngineT>(
self,
module_config: TransportRpcModuleConfig,
engine: EngineApi,
@ -458,6 +456,7 @@ where
RethModuleRegistry<Provider, Pool, Network, Tasks, Events, EvmConfig>,
)
where
EngineT: EngineTypes + 'static,
EngineApi: EngineApiServer<EngineT>,
{
let mut modules = TransportRpcModules::default();
@ -494,20 +493,24 @@ where
///
/// ```no_run
/// use reth_network_api::noop::NoopNetwork;
/// use reth_node_api::EvmEnvConfig;
/// use reth_provider::test_utils::{NoopProvider, TestCanonStateSubscriptions};
/// use reth_rpc_builder::RpcModuleBuilder;
/// use reth_tasks::TokioTaskExecutor;
/// use reth_transaction_pool::noop::NoopTransactionPool;
///
/// fn init<Evm: EvmEnvConfig + 'static>(evm: Evm) {
/// let mut registry = RpcModuleBuilder::default()
/// .with_provider(NoopProvider::default())
/// .with_pool(NoopTransactionPool::default())
/// .with_network(NoopNetwork::default())
/// .with_executor(TokioTaskExecutor::default())
/// .with_events(TestCanonStateSubscriptions::default())
/// .with_evm_config(evm)
/// .into_registry(Default::default());
///
/// let eth_api = registry.eth_api();
/// }
/// ```
pub fn into_registry(
self,
@ -549,9 +552,9 @@ where
}
}
impl Default for RpcModuleBuilder<(), (), (), (), (), EthEvmConfig> {
impl Default for RpcModuleBuilder<(), (), (), (), (), ()> {
fn default() -> Self {
RpcModuleBuilder::new((), (), (), (), (), EthEvmConfig::default())
RpcModuleBuilder::new((), (), (), (), (), ())
}
}
@ -1101,7 +1104,7 @@ where
/// Note: This does _not_ register the `engine_` in this registry.
pub fn create_auth_module<EngineApi, EngineT>(&mut self, engine_api: EngineApi) -> AuthRpcModule
where
EngineT: EngineTypes,
EngineT: EngineTypes + 'static,
EngineApi: EngineApiServer<EngineT>,
{
let eth_handlers = self.eth_handlers();

View File

@ -9,5 +9,6 @@ license.workspace = true
futures.workspace = true
jsonrpsee.workspace = true
reth.workspace = true
reth-node-ethereum.workspace = true
tokio = { workspace = true, features = ["full"] }
eyre.workspace = true

View File

@ -27,6 +27,7 @@ use reth::{
blockchain_tree::noop::NoopBlockchainTree, providers::test_utils::TestCanonStateSubscriptions,
tasks::TokioTaskExecutor,
};
use reth_node_ethereum::EthEvmConfig;
use std::{path::Path, sync::Arc};
// Custom rpc extension
@ -53,6 +54,7 @@ async fn main() -> eyre::Result<()> {
.with_noop_pool()
.with_noop_network()
.with_executor(TokioTaskExecutor::default())
.with_evm_config(EthEvmConfig::default())
.with_events(TestCanonStateSubscriptions::default());
// Pick which namespaces to expose.