Skip to content

Commit

Permalink
Splitting Reth Node Command Ext (paradigmxyz#4158)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Seitz <[email protected]>
  • Loading branch information
i-m-aditya and mattsse authored Aug 15, 2023
1 parent 92361ad commit 0846d85
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 13 deletions.
10 changes: 5 additions & 5 deletions bin/reth/src/args/rpc_server_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use crate::{
args::GasPriceOracleArgs,
cli::{config::RethRpcConfig, ext::RethNodeCommandExt},
cli::{config::RethRpcConfig, ext::RethNodeCommandConfig},
};
use clap::{
builder::{PossibleValue, RangedU64ValueParser, TypedValueParser},
Expand Down Expand Up @@ -223,7 +223,7 @@ impl RpcServerArgs {
/// for the auth server that handles the `engine_` API that's accessed by the consensus
/// layer.
#[allow(clippy::too_many_arguments)]
pub async fn start_servers<Provider, Pool, Network, Tasks, Events, Engine, Ext>(
pub async fn start_servers<Provider, Pool, Network, Tasks, Events, Engine, Conf>(
&self,
provider: Provider,
pool: Pool,
Expand All @@ -232,7 +232,7 @@ impl RpcServerArgs {
events: Events,
engine_api: Engine,
jwt_secret: JwtSecret,
ext: &mut Ext,
conf: &mut Conf,
) -> eyre::Result<(RpcServerHandle, AuthServerHandle)>
where
Provider: BlockReaderIdExt
Expand All @@ -249,7 +249,7 @@ impl RpcServerArgs {
Tasks: TaskSpawner + Clone + 'static,
Events: CanonStateSubscriptions + Clone + 'static,
Engine: EngineApiServer,
Ext: RethNodeCommandExt,
Conf: RethNodeCommandConfig,
{
let auth_config = self.auth_server_config(jwt_secret)?;

Expand All @@ -265,7 +265,7 @@ impl RpcServerArgs {
.build_with_auth_server(module_config, engine_api);

// apply configured customization
ext.extend_rpc_modules(self, &mut registry, &mut rpc_modules)?;
conf.extend_rpc_modules(self, &mut registry, &mut rpc_modules)?;

let server_config = self.rpc_server_config();
let launch_rpc = rpc_modules.start_server(server_config).map_ok(|handle| {
Expand Down
126 changes: 121 additions & 5 deletions bin/reth/src/cli/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ pub trait RethCliExt {
/// Provides additional configuration for the node CLI command.
///
/// This supports additional CLI arguments that can be used to modify the node configuration.
///
/// If no additional CLI arguments are required, the [NoArgs] wrapper type can be used.
type Node: RethNodeCommandExt;
}

Expand All @@ -31,8 +33,9 @@ impl RethCliExt for () {
type Node = DefaultRethNodeCommandConfig;
}

/// A trait that allows for extending parts of the CLI with additional functionality.
pub trait RethNodeCommandExt: fmt::Debug + clap::Args {
/// A trait that allows for extending and customizing parts of the node command
/// [NodeCommand](crate::node::NodeCommand).
pub trait RethNodeCommandConfig: fmt::Debug {
/// Allows for registering additional RPC modules for the transports.
///
/// This is expected to call the merge functions of [TransportRpcModules], for example
Expand Down Expand Up @@ -98,12 +101,125 @@ pub trait RethNodeCommandExt: fmt::Debug + clap::Args {

Ok(payload_builder)
}

// TODO move network related functions here
}

/// A trait that allows for extending parts of the CLI with additional functionality.
pub trait RethNodeCommandExt: RethNodeCommandConfig + fmt::Debug + clap::Args {}

// blanket impl for all types that implement the required traits.
impl<T> RethNodeCommandExt for T where T: RethNodeCommandConfig + fmt::Debug + clap::Args {}

/// The default configuration for the reth node command [Command](crate::node::NodeCommand).
///
/// This is a convenience type for [NoArgs<()>].
#[derive(Debug, Clone, Copy, Default, Args)]
pub struct DefaultRethNodeCommandConfig;

impl RethNodeCommandExt for DefaultRethNodeCommandConfig {}
impl RethNodeCommandConfig for DefaultRethNodeCommandConfig {}

impl RethNodeCommandConfig for () {}

/// A helper struct that allows for wrapping a [RethNodeCommandConfig] value without providing
/// additional CLI arguments.
///
/// Note: This type must be manually filled with a [RethNodeCommandConfig] manually before executing
/// the [NodeCommand](crate::node::NodeCommand).
#[derive(Debug, Clone, Copy, Default, Args)]
pub struct NoArgs<T> {
#[clap(skip)]
inner: Option<T>,
}

impl<T> NoArgs<T> {
/// Creates a new instance of the wrapper type.
pub fn with(inner: T) -> Self {
Self { inner: Some(inner) }
}

/// Sets the inner value.
pub fn set(&mut self, inner: T) {
self.inner = Some(inner)
}

/// Transforms the configured value.
pub fn map<U>(self, inner: U) -> NoArgs<U> {
NoArgs::with(inner)
}

/// Returns the inner value if it exists.
pub fn inner(&self) -> Option<&T> {
self.inner.as_ref()
}

/// Returns a mutable reference to the inner value if it exists.
pub fn inner_mut(&mut self) -> Option<&mut T> {
self.inner.as_mut()
}

/// Consumes the wrapper and returns the inner value if it exists.
pub fn into_inner(self) -> Option<T> {
self.inner
}
}

impl<T: RethNodeCommandConfig> RethNodeCommandConfig for NoArgs<T> {
fn extend_rpc_modules<Conf, Provider, Pool, Network, Tasks, Events>(
&mut self,
config: &Conf,
registry: &mut RethModuleRegistry<Provider, Pool, Network, Tasks, Events>,
modules: &mut TransportRpcModules<()>,
) -> eyre::Result<()>
where
Conf: RethRpcConfig,
Provider: BlockReaderIdExt
+ StateProviderFactory
+ EvmEnvProvider
+ ChainSpecProvider
+ ChangeSetReader
+ Clone
+ Unpin
+ 'static,
Pool: TransactionPool + Clone + 'static,
Network: NetworkInfo + Peers + Clone + 'static,
Tasks: TaskSpawner + Clone + 'static,
Events: CanonStateSubscriptions + Clone + 'static,
{
if let Some(conf) = self.inner_mut() {
conf.extend_rpc_modules(config, registry, modules)
} else {
Ok(())
}
}

fn spawn_payload_builder_service<Conf, Provider, Pool, Tasks>(
&mut self,
conf: &Conf,
provider: Provider,
pool: Pool,
executor: Tasks,
chain_spec: Arc<ChainSpec>,
) -> eyre::Result<PayloadBuilderHandle>
where
Conf: PayloadBuilderConfig,
Provider: StateProviderFactory + BlockReaderIdExt + Clone + Unpin + 'static,
Pool: TransactionPool + Unpin + 'static,
Tasks: TaskSpawner + Clone + Unpin + 'static,
{
self.inner_mut()
.ok_or_else(|| eyre::eyre!("config value must be set"))?
.spawn_payload_builder_service(conf, provider, pool, executor, chain_spec)
}
}

#[cfg(test)]
mod tests {
use super::*;

fn assert_ext<T: RethNodeCommandExt>() {}

#[test]
fn ensure_ext() {
assert_ext::<DefaultRethNodeCommandConfig>();
assert_ext::<NoArgs<()>>();
}
}
2 changes: 1 addition & 1 deletion bin/reth/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
DatabaseArgs, DebugArgs, DevArgs, NetworkArgs, PayloadBuilderArgs, PruningArgs,
RpcServerArgs, TxPoolArgs,
},
cli::ext::{RethCliExt, RethNodeCommandExt},
cli::ext::{RethCliExt, RethNodeCommandConfig},
dirs::{DataDirPath, MaybePlatformPath},
init::init_genesis,
node::cl_events::ConsensusLayerHealthEvents,
Expand Down
4 changes: 2 additions & 2 deletions examples/additional-rpc-namespace-in-cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use reth::{
cli::{
config::RethRpcConfig,
ext::{RethCliExt, RethNodeCommandExt},
ext::{RethCliExt, RethNodeCommandConfig},
Cli,
},
network::{NetworkInfo, Peers},
Expand Down Expand Up @@ -49,7 +49,7 @@ struct RethCliTxpoolExt {
pub enable_ext: bool,
}

impl RethNodeCommandExt for RethCliTxpoolExt {
impl RethNodeCommandConfig for RethCliTxpoolExt {
// This is the entrypoint for the CLI to extend the RPC server with custom rpc namespaces.
fn extend_rpc_modules<Conf, Provider, Pool, Network, Tasks, Events>(
&mut self,
Expand Down

0 comments on commit 0846d85

Please sign in to comment.