Skip to content

Commit

Permalink
feature(rpc): add an rpc component
Browse files Browse the repository at this point in the history
  • Loading branch information
oxarbitrage committed Feb 19, 2022
1 parent 137ae4e commit b51e994
Show file tree
Hide file tree
Showing 10 changed files with 335 additions and 26 deletions.
237 changes: 213 additions & 24 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions zebra-rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

jsonrpc-core = "18.0.0"
jsonrpc-core-client = "18.0.0"
jsonrpc-derive = "18.0.0"

serde = { version = "1", features = ["serde_derive"] }
4 changes: 3 additions & 1 deletion zebra-rpc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! A Zebra remote procedure call interface
//! A Zebra Remote Procedure Call (RPC) interface
#![doc(html_favicon_url = "https://www.zfnd.org/images/zebra-favicon-128.png")]
#![doc(html_logo_url = "https://www.zfnd.org/images/zebra-icon.png")]
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_rpc")]

pub mod rpc;
35 changes: 35 additions & 0 deletions zebra-rpc/src/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//! Zebra supported RPC methods.
use jsonrpc_core;

use jsonrpc_core::Result;
use jsonrpc_derive::rpc;

#[rpc]
/// RPC method signatures.
pub trait Rpc {
/// getinfo
#[rpc(name = "getinfo")]
fn getinfo(&self) -> Result<GetInfo>;
}

/// RPC method implementations.
pub struct RpcImpl;
impl Rpc for RpcImpl {
fn getinfo(&self) -> Result<GetInfo> {
// TODO: dummy output data, fix in the context of #3142
let info = GetInfo {
build: "Zebra v1.0.0 ...".into(),
subversion: "/Zebra:1.0.0-beta.4/".into(),
};

Ok(info)
}
}

#[derive(serde::Serialize, serde::Deserialize)]
/// Return structure of a `getinfo` RPC method.
pub struct GetInfo {
build: String,
subversion: String,
}
4 changes: 4 additions & 0 deletions zebrad/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ default-run = "zebrad"
zebra-chain = { path = "../zebra-chain" }
zebra-consensus = { path = "../zebra-consensus/" }
zebra-network = { path = "../zebra-network" }
zebra-rpc = { path = "../zebra-rpc" }
zebra-state = { path = "../zebra-state" }

abscissa_core = "0.5"
Expand Down Expand Up @@ -50,6 +51,9 @@ sentry-tracing = "0.23.0"

rand = "0.8.5"

jsonrpc-core = "18.0.0"
jsonrpc-http-server = "18.0.0"

[build-dependencies]
vergen = { version = "6.0.2", default-features = false, features = ["cargo", "git"] }

Expand Down
5 changes: 5 additions & 0 deletions zebrad/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use crate::{
components::{
inbound::{self, InboundSetupData},
mempool::{self, Mempool},
rpc::RpcServer,
sync::{self, SyncStatus},
tokio::{RuntimeRun, TokioComponent},
ChainSync, Inbound,
Expand Down Expand Up @@ -188,6 +189,8 @@ impl StartCmd {
.in_current_span(),
);

let rpc_task_handle = tokio::spawn(RpcServer::new(config.rpc).in_current_span());

info!("spawned initial Zebra tasks");

// TODO: put tasks into an ongoing FuturesUnordered and a startup FuturesUnordered?
Expand All @@ -198,6 +201,7 @@ impl StartCmd {
pin!(mempool_queue_checker_task_handle);
pin!(tx_gossip_task_handle);
pin!(progress_task_handle);
pin!(rpc_task_handle);

// startup tasks
let groth16_download_handle_fused = (&mut groth16_download_handle).fuse();
Expand Down Expand Up @@ -271,6 +275,7 @@ impl StartCmd {
mempool_crawler_task_handle.abort();
mempool_queue_checker_task_handle.abort();
tx_gossip_task_handle.abort();
rpc_task_handle.abort();

// startup tasks
groth16_download_handle.abort();
Expand Down
1 change: 1 addition & 0 deletions zebrad/src/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod inbound;
#[allow(missing_docs)]
pub mod mempool;
pub mod metrics;
pub mod rpc;
#[allow(missing_docs)]
pub mod sync;
#[allow(missing_docs)]
Expand Down
37 changes: 37 additions & 0 deletions zebrad/src/components/rpc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//! An RPC endpoint.
use jsonrpc_core;

use jsonrpc_http_server::ServerBuilder;

use zebra_rpc::rpc::{Rpc, RpcImpl};

pub mod config;
pub use config::Config;

/// Zebra RPC Server
pub struct RpcServer {}

impl RpcServer {
/// Start a new RPC server endpoint
pub async fn new(config: Config) -> Self {
if config.listen {
info!("Trying to open RPC endpoint at {}...", config.listen_addr);

// Create handler compatible with V1 and V2 RPC protocols
let mut io =
jsonrpc_core::IoHandler::with_compatibility(jsonrpc_core::Compatibility::Both);
io.extend_with(RpcImpl.to_delegate());

let server = ServerBuilder::new(io)
.threads(1)
.start_http(&config.listen_addr)
.expect("Unable to start RPC server");

info!("Opened RPC endpoint at {}", server.address());

server.wait();
}
RpcServer {}
}
}
27 changes: 27 additions & 0 deletions zebrad/src/components/rpc/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//! User-configurable RPC parameters.
use std::net::SocketAddr;

use serde::{Deserialize, Serialize};

/// RPC configuration section.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields, default)]
pub struct Config {
/// Turn on/off the RPC server
pub listen: bool,

/// IP address and port for the RPC server
pub listen_addr: SocketAddr,
}

impl Default for Config {
fn default() -> Self {
Self {
listen: false,
listen_addr: "127.0.0.1:8232"
.parse()
.expect("Hardcoded address should be parseable"),
}
}
}
5 changes: 4 additions & 1 deletion zebrad/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use zebra_consensus::Config as ConsensusSection;
use zebra_network::Config as NetworkSection;
use zebra_state::Config as StateSection;

use crate::components::{mempool::Config as MempoolSection, sync};
use crate::components::{mempool::Config as MempoolSection, rpc::Config as RpcSection, sync};

/// Configuration for `zebrad`.
///
Expand Down Expand Up @@ -42,6 +42,9 @@ pub struct ZebradConfig {

/// Mempool configuration
pub mempool: MempoolSection,

/// RPC configuration
pub rpc: RpcSection,
}

/// Tracing configuration section.
Expand Down

0 comments on commit b51e994

Please sign in to comment.