Skip to content

Commit

Permalink
#2511: extended reth-rpc example with custom rpc ext (#4508)
Browse files Browse the repository at this point in the history
Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
  • Loading branch information
loocapro and mattsse authored Sep 8, 2023
1 parent d0d50a0 commit 5f329e7
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 25 deletions.
11 changes: 11 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ members = [
"crates/rpc/rpc-types-compat",
"examples",
"examples/additional-rpc-namespace-in-cli",
"examples/rpc-db",
]
default-members = ["bin/reth"]

Expand Down
23 changes: 23 additions & 0 deletions bin/reth/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,25 @@ pub mod providers {
pub use reth_provider::*;
}

/// Re-exported from `reth_primitives`.
pub mod primitives {
pub use reth_primitives::*;
}

/// Re-exported from `reth_beacon_consensus`.
pub mod beacon_consensus {
pub use reth_beacon_consensus::*;
}
/// Re-exported from `reth_blockchain_tree`.
pub mod blockchain_tree {
pub use reth_blockchain_tree::*;
}

/// Re-exported from `reth_revm`.
pub mod revm {
pub use reth_revm::*;
}

/// Re-exported from `reth_tasks`.
pub mod tasks {
pub use reth_tasks::*;
Expand Down Expand Up @@ -79,6 +98,10 @@ pub mod rpc {
pub mod api {
pub use reth_rpc_api::*;
}
/// Re-exported from `reth_rpc::eth`.
pub mod eth {
pub use reth_rpc::eth::*;
}
}

#[cfg(all(feature = "jemalloc", unix))]
Expand Down
5 changes: 5 additions & 0 deletions bin/reth/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ use std::{
};
use tracing::info;

/// Exposing `open_db_read_only` function
pub mod db {
pub use reth_db::open_db_read_only;
}

/// Get a single header from network
pub async fn get_single_header<Client>(
client: Client,
Expand Down
4 changes: 0 additions & 4 deletions examples/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ futures.workspace = true
async-trait.workspace = true
tokio.workspace = true

[[example]]
name = "rpc-db"
path = "rpc-db.rs"

[[example]]
name = "db-access"
path = "db-access.rs"
Expand Down
13 changes: 13 additions & 0 deletions examples/rpc-db/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "rpc-db"
version = "0.0.0"
publish = false
edition.workspace = true
license.workspace = true

[dependencies]
futures.workspace = true
jsonrpsee.workspace = true
reth.workspace = true
tokio = { workspace = true, features = ["full"] }
eyre = "0.6.8"
60 changes: 39 additions & 21 deletions examples/rpc-db.rs → examples/rpc-db/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,45 @@
// Talking to the DB
use reth_db::open_db_read_only;
use reth_primitives::ChainSpecBuilder;
use reth_provider::{providers::BlockchainProvider, ProviderFactory};

//! Example illustrating how to run the ETH JSON RPC API as standalone over a DB file.
//!
//! Run with
//!
//! ```not_rust
//! cargo run -p rpc-db
//! ```
//!
//! This installs an additional RPC method `myrpcExt_customMethod` that can queried via [cast](https://github.com/foundry-rs/foundry)
//!
//! ```sh
//! cast rpc myrpcExt_customMethod
//! ```
use reth::{
primitives::ChainSpecBuilder,
providers::{providers::BlockchainProvider, ProviderFactory},
utils::db::open_db_read_only,
};
// Bringing up the RPC
use reth_rpc_builder::{
use reth::rpc::builder::{
RethRpcModule, RpcModuleBuilder, RpcServerConfig, TransportRpcModuleConfig,
};

// Code which we'd ideally like to not need to import if you're only spinning up
// read-only parts of the API and do not require access to pending state or to
// EVM sims
use reth_beacon_consensus::BeaconConsensus;
use reth_blockchain_tree::{
BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals,
use reth::{
beacon_consensus::BeaconConsensus,
blockchain_tree::{
BlockchainTree, BlockchainTreeConfig, ShareableBlockchainTree, TreeExternals,
},
revm::Factory as ExecutionFactory,
};
use reth_revm::Factory as ExecutionFactory;

// Configuring the network parts, ideally also wouldn't ned to think about this.
use reth_network_api::noop::NoopNetwork;
use reth_provider::test_utils::TestCanonStateSubscriptions;
use reth_tasks::TokioTaskExecutor;
use reth_transaction_pool::noop::NoopTransactionPool;
use reth::{providers::test_utils::TestCanonStateSubscriptions, tasks::TokioTaskExecutor};
use std::{path::Path, sync::Arc};

// Example illustrating how to run the ETH JSON RPC API as standalone over a DB file.
// TODO: Add example showing how to spin up your own custom RPC namespace alongside
// the other default name spaces.
use myrpc_ext::{MyRpcExt, MyRpcExtApiServer};
// Custom rpc extension
pub mod myrpc_ext;

#[tokio::main]
async fn main() -> eyre::Result<()> {
// 1. Setup the DB
Expand Down Expand Up @@ -55,16 +69,20 @@ async fn main() -> eyre::Result<()> {
};

let rpc_builder = RpcModuleBuilder::default()
.with_provider(provider)
.with_provider(provider.clone())
// Rest is just noops that do nothing
.with_pool(NoopTransactionPool::default())
.with_network(NoopNetwork::default())
.with_noop_pool()
.with_noop_network()
.with_executor(TokioTaskExecutor::default())
.with_events(TestCanonStateSubscriptions::default());

// Pick which namespaces to expose.
let config = TransportRpcModuleConfig::default().with_http([RethRpcModule::Eth]);
let server = rpc_builder.build(config);
let mut server = rpc_builder.build(config);

// Add a custom rpc namespace
let custom_rpc = MyRpcExt { provider };
server.merge_configured(custom_rpc.into_rpc())?;

// Start the server & keep it alive
let server_args =
Expand Down
33 changes: 33 additions & 0 deletions examples/rpc-db/src/myrpc_ext.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Reth block related imports
use reth::{primitives::Block, providers::BlockReaderIdExt};

// Rpc related imports
use jsonrpsee::proc_macros::rpc;
use reth::rpc::eth::error::EthResult;

/// trait interface for a custom rpc namespace: `MyRpc`
///
/// This defines an additional namespace where all methods are configured as trait functions.
#[rpc(server, namespace = "myrpcExt")]
pub trait MyRpcExtApi {
/// Returns block 0.
#[method(name = "customMethod")]
fn custom_method(&self) -> EthResult<Option<Block>>;
}

/// The type that implements `myRpc` rpc namespace trait
pub struct MyRpcExt<Provider> {
pub provider: Provider,
}

impl<Provider> MyRpcExtApiServer for MyRpcExt<Provider>
where
Provider: BlockReaderIdExt + 'static,
{
/// Showcasing how to implement a custom rpc method
/// using the provider.
fn custom_method(&self) -> EthResult<Option<Block>> {
let block = self.provider.block_by_number(0)?;
Ok(block)
}
}

0 comments on commit 5f329e7

Please sign in to comment.