Skip to content

Commit

Permalink
chore: add example how to install additional rpc namespace (paradigmx…
Browse files Browse the repository at this point in the history
  • Loading branch information
mattsse authored Jul 31, 2023
1 parent e560b06 commit b28bc8d
Show file tree
Hide file tree
Showing 9 changed files with 203 additions and 5 deletions.
13 changes: 13 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ members = [
"testing/ef-tests",

"examples",
"examples/additional-rpc-namespace-in-cli",
]
default-members = ["bin/reth"]

Expand Down Expand Up @@ -84,6 +85,7 @@ revm-primitives = { git = "https://github.com/bluealloy/revm/", branch = "releas
## reth
revm = { version = "3" }
revm-primitives = "1.1"
reth = { path = "./bin/reth" }
reth-primitives = { path = "./crates/primitives" }
reth-interfaces = { path = "./crates/interfaces" }
reth-provider = { path = "./crates/storage/provider" }
Expand Down
2 changes: 2 additions & 0 deletions bin/reth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ reth-blockchain-tree = { path = "../../crates/blockchain-tree" }
reth-rpc-engine-api = { path = "../../crates/rpc/rpc-engine-api" }
reth-rpc-builder = { path = "../../crates/rpc/rpc-builder" }
reth-rpc = { path = "../../crates/rpc/rpc" }
reth-rpc-types = { path = "../../crates/rpc/rpc-types" }
reth-rpc-api = { path = "../../crates/rpc/rpc-api" }
reth-rlp.workspace = true
reth-network = { path = "../../crates/net/network", features = ["serde"] }
reth-network-api.workspace = true
Expand Down
4 changes: 2 additions & 2 deletions bin/reth/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub struct Cli<Ext: RethCliExt = ()> {
verbosity: Verbosity,
}

impl Cli {
impl<Ext: RethCliExt> Cli<Ext> {
/// Execute the configured cli command.
pub fn run(mut self) -> eyre::Result<()> {
// add network name to logs dir
Expand Down Expand Up @@ -98,7 +98,7 @@ impl Cli {
/// Convenience function for parsing CLI options, set up logging and run the chosen command.
#[inline]
pub fn run() -> eyre::Result<()> {
Cli::parse().run()
Cli::<()>::parse().run()
}

/// Commands to be executed
Expand Down
40 changes: 40 additions & 0 deletions bin/reth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,45 @@ pub mod test_vectors;
pub mod utils;
pub mod version;

/// Re-exported from `reth_provider`.
pub mod providers {
pub use reth_provider::*;
}

/// Re-exported from `reth_tasks`.
pub mod tasks {
pub use reth_tasks::*;
}

/// Re-exported from `reth_network`.
pub mod network {
pub use reth_network::*;
pub use reth_network_api::{noop, reputation, NetworkInfo, PeerKind, Peers, PeersInfo};
}

/// Re-exported from `reth_transaction_pool`.
pub mod transaction_pool {
pub use reth_transaction_pool::*;
}

/// Re-export of `reth_rpc_*` crates.
pub mod rpc {

/// Re-exported from `reth_rpc_builder`.
pub mod builder {
pub use reth_rpc_builder::*;
}

/// Re-exported from `reth_rpc_types`.
pub mod types {
pub use reth_rpc_types::*;
}

/// Re-exported from `reth_rpc_api`.
pub mod api {
pub use reth_rpc_api::*;
}
}

#[cfg(all(feature = "jemalloc", unix))]
use jemallocator as _;
2 changes: 1 addition & 1 deletion bin/reth/src/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ pub struct Command<Ext: RethCliExt = ()> {
pruning: PruningArgs,
}

impl Command {
impl<Ext: RethCliExt> Command<Ext> {
/// Execute `node` command
pub async fn execute(self, ctx: CliContext) -> eyre::Result<()> {
info!(target: "reth::cli", "reth {} starting", SHORT_VERSION);
Expand Down
19 changes: 17 additions & 2 deletions crates/rpc/rpc-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,21 @@ impl<Provider, Pool, Network, Tasks, Events>
}
}

/// Returns a reference to the provider
pub fn pool(&self) -> &Pool {
&self.pool
}

/// Returns a reference to the events type
pub fn events(&self) -> &Events {
&self.events
}

/// Returns a reference to the tasks type
pub fn tasks(&self) -> &Tasks {
&self.executor
}

/// Returns all installed methods
pub fn methods(&self) -> Vec<Methods> {
self.modules.values().cloned().collect()
Expand Down Expand Up @@ -1499,8 +1514,8 @@ impl TransportRpcModules<()> {
&mut self,
other: impl Into<Methods>,
) -> Result<bool, jsonrpsee::core::error::Error> {
if let Some(ref mut http) = self.http {
return http.merge(other.into()).map(|_| true)
if let Some(ref mut ipc) = self.ipc {
return ipc.merge(other.into()).map(|_| true)
}
Ok(false)
}
Expand Down
14 changes: 14 additions & 0 deletions examples/additional-rpc-namespace-in-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "additional-rpc-namespace-in-cli"
version = "0.0.0"
publish = false
edition.workspace = true
license.workspace = true

[dependencies]
reth.workspace = true
reth-transaction-pool.workspace = true

clap = { version = "4", features = ["derive"] }
jsonrpsee = { workspace = true, features = ["server", "macros"] }
eyre = "0.6"
112 changes: 112 additions & 0 deletions examples/additional-rpc-namespace-in-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//! Example of how to use additional rpc namespaces in the reth CLI
//!
//! Run with
//!
//! ```not_rust
//! cargo run -p additional-rpc-namespace-in-cli -- node --http --ws --enable-ext
//! ```
//!
//! This installs an additional RPC method `txpoolExt_transactionCount` that can queried via [cast](https://github.com/foundry-rs/foundry)
//!
//! ```sh
//! cast rpc txpoolExt_transactionCount
//! ```
use clap::Parser;
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use reth::{
cli::{
ext::{RethCliExt, RethRpcConfig, RethRpcServerArgsExt},
Cli,
},
network::{NetworkInfo, Peers},
providers::{
BlockReaderIdExt, CanonStateSubscriptions, ChainSpecProvider, ChangeSetReader,
EvmEnvProvider, StateProviderFactory,
},
rpc::builder::{RethModuleRegistry, TransportRpcModules},
tasks::TaskSpawner,
};
use reth_transaction_pool::TransactionPool;

fn main() {
Cli::<MyRethCliExt>::parse().run().unwrap();
}

/// The type that tells the reth CLI what extensions to use
struct MyRethCliExt;

impl RethCliExt for MyRethCliExt {
/// This tells the reth CLI to install the `txpool` rpc namespace via `RethCliTxpoolExt`
type RpcExt = RethCliTxpoolExt;
}

/// Our custom cli args extension that adds one flag to reth default CLI.
#[derive(Debug, Clone, Copy, Default, clap::Args)]
struct RethCliTxpoolExt {
/// CLI flag to enable the txpool extension namespace
#[clap(long)]
pub enable_ext: bool,
}

impl RethRpcServerArgsExt 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>(
&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 !self.enable_ext {
return Ok(())
}

// here we get the configured pool type from the CLI.
let pool = registry.pool().clone();
let ext = TxpoolExt { pool };

// now we merge our extension namespace into all configured transports
modules.merge_configured(ext.into_rpc())?;

println!("txpool extension enabled");
Ok(())
}
}

/// trait interface for a custom rpc namespace: `txpool`
///
/// This defines an additional namespace where all methods are configured as trait functions.
#[rpc(server, namespace = "txpoolExt")]
pub trait TxpoolExtApi {
/// Returns the number of transactions in the pool.
#[method(name = "transactionCount")]
fn transaction_count(&self) -> RpcResult<usize>;
}

/// The type that implements the `txpool` rpc namespace trait
pub struct TxpoolExt<Pool> {
pool: Pool,
}

impl<Pool> TxpoolExtApiServer for TxpoolExt<Pool>
where
Pool: TransactionPool + Clone + 'static,
{
fn transaction_count(&self) -> RpcResult<usize> {
Ok(self.pool.pool_size().total)
}
}

0 comments on commit b28bc8d

Please sign in to comment.