feature(rpc): add real data to `getinfo` method (#3660)
* feature(rpc): add getinfo subversion field and getinfo docs * feature(rpc): add getinfo build field * refactor(rpc): replace the lazy_static * docs(rpc): fic typo, add link to zcashd ticket * tests(rpc): add getinfo unit test * docs(rpc): complete comment
This commit is contained in:
parent
a8a52125d0
commit
b3eb38d279
|
|
@ -5708,6 +5708,8 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-futures",
|
"tracing-futures",
|
||||||
|
"zebra-network",
|
||||||
|
"zebra-test",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
|
zebra-network = { path = "../zebra-network" }
|
||||||
|
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
|
||||||
# lightwalletd sends JSON-RPC requests over HTTP 1.1
|
# lightwalletd sends JSON-RPC requests over HTTP 1.1
|
||||||
|
|
@ -24,3 +26,7 @@ tracing = "0.1"
|
||||||
tracing-futures = "0.2"
|
tracing-futures = "0.2"
|
||||||
|
|
||||||
serde = { version = "1", features = ["serde_derive"] }
|
serde = { version = "1", features = ["serde_derive"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
|
||||||
|
zebra-test = { path = "../zebra-test/" }
|
||||||
|
|
|
||||||
|
|
@ -9,15 +9,34 @@
|
||||||
use jsonrpc_core::{self, Result};
|
use jsonrpc_core::{self, Result};
|
||||||
use jsonrpc_derive::rpc;
|
use jsonrpc_derive::rpc;
|
||||||
|
|
||||||
|
use zebra_network::constants::USER_AGENT;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
#[rpc(server)]
|
#[rpc(server)]
|
||||||
/// RPC method signatures.
|
/// RPC method signatures.
|
||||||
pub trait Rpc {
|
pub trait Rpc {
|
||||||
/// getinfo
|
/// getinfo
|
||||||
///
|
///
|
||||||
/// TODO: explain what the method does
|
/// Returns software information from the RPC server running Zebra.
|
||||||
/// link to the zcashd RPC reference
|
///
|
||||||
/// list the arguments and fields that lightwalletd uses
|
/// zcashd reference: <https://zcash.github.io/rpc/getinfo.html>
|
||||||
/// note any other lightwalletd changes
|
///
|
||||||
|
/// Result:
|
||||||
|
/// {
|
||||||
|
/// "build": String, // Full application version
|
||||||
|
/// "subversion", String, // Zebra user agent
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// Note 1: We only expose 2 fields as they are the only ones needed for
|
||||||
|
/// lightwalletd: <https://github.com/zcash/lightwalletd/blob/v0.4.9/common/common.go#L91-L95>
|
||||||
|
///
|
||||||
|
/// Note 2: <https://zcash.github.io/rpc/getinfo.html> is outdated so it does not
|
||||||
|
/// show the fields we are exposing. However, this fields are part of the output
|
||||||
|
/// as shown in the following zcashd code:
|
||||||
|
/// <https://github.com/zcash/zcash/blob/v4.6.0-1/src/rpc/misc.cpp#L86-L87>
|
||||||
|
/// Zcash open ticket to add this fields to the docs: <https://github.com/zcash/zcash/issues/5606>
|
||||||
#[rpc(name = "getinfo")]
|
#[rpc(name = "getinfo")]
|
||||||
fn get_info(&self) -> Result<GetInfo>;
|
fn get_info(&self) -> Result<GetInfo>;
|
||||||
|
|
||||||
|
|
@ -32,13 +51,16 @@ pub trait Rpc {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RPC method implementations.
|
/// RPC method implementations.
|
||||||
pub struct RpcImpl;
|
|
||||||
|
pub struct RpcImpl {
|
||||||
|
/// Zebra's application version.
|
||||||
|
pub app_version: String,
|
||||||
|
}
|
||||||
impl Rpc for RpcImpl {
|
impl Rpc for RpcImpl {
|
||||||
fn get_info(&self) -> Result<GetInfo> {
|
fn get_info(&self) -> Result<GetInfo> {
|
||||||
// TODO: dummy output data, fix in the context of #3142
|
|
||||||
let response = GetInfo {
|
let response = GetInfo {
|
||||||
build: "TODO: Zebra v1.0.0 ...".into(),
|
build: self.app_version.clone(),
|
||||||
subversion: "TODO: /Zebra:1.0.0-beta.../".into(),
|
subversion: USER_AGENT.into(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
//! Test code for RPC methods
|
||||||
|
mod vectors;
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
//! Fixed test vectors for RPC methods.
|
||||||
|
|
||||||
|
use super::super::*;
|
||||||
|
use zebra_network::constants::USER_AGENT;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rpc_getinfo() {
|
||||||
|
zebra_test::init();
|
||||||
|
|
||||||
|
let rpc = RpcImpl {
|
||||||
|
app_version: "Zebra version test".to_string(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let get_info = rpc.get_info().expect("We should have a GetInfo struct");
|
||||||
|
|
||||||
|
// make sure there is a `build` field in the response,
|
||||||
|
// and that is equal to the provided string.
|
||||||
|
assert_eq!(get_info.build, "Zebra version test");
|
||||||
|
|
||||||
|
// make sure there is a `subversion` field,
|
||||||
|
// and that is equal to the Zebra user agent.
|
||||||
|
assert_eq!(get_info.subversion, USER_AGENT);
|
||||||
|
}
|
||||||
|
|
@ -24,14 +24,17 @@ pub struct RpcServer;
|
||||||
|
|
||||||
impl RpcServer {
|
impl RpcServer {
|
||||||
/// Start a new RPC server endpoint
|
/// Start a new RPC server endpoint
|
||||||
pub fn spawn(config: Config) -> tokio::task::JoinHandle<()> {
|
pub fn spawn(config: Config, app_version: String) -> tokio::task::JoinHandle<()> {
|
||||||
if let Some(listen_addr) = config.listen_addr {
|
if let Some(listen_addr) = config.listen_addr {
|
||||||
info!("Trying to open RPC endpoint at {}...", listen_addr,);
|
info!("Trying to open RPC endpoint at {}...", listen_addr,);
|
||||||
|
|
||||||
|
// Initialize the rpc methods with the zebra version
|
||||||
|
let rpc_impl = RpcImpl { app_version };
|
||||||
|
|
||||||
// Create handler compatible with V1 and V2 RPC protocols
|
// Create handler compatible with V1 and V2 RPC protocols
|
||||||
let mut io =
|
let mut io =
|
||||||
jsonrpc_core::IoHandler::with_compatibility(jsonrpc_core::Compatibility::Both);
|
jsonrpc_core::IoHandler::with_compatibility(jsonrpc_core::Compatibility::Both);
|
||||||
io.extend_with(RpcImpl.to_delegate());
|
io.extend_with(rpc_impl.to_delegate());
|
||||||
|
|
||||||
let server = ServerBuilder::new(io)
|
let server = ServerBuilder::new(io)
|
||||||
// use the same tokio executor as the rest of Zebra
|
// use the same tokio executor as the rest of Zebra
|
||||||
|
|
@ -54,6 +57,7 @@ impl RpcServer {
|
||||||
info!("Stopping RPC endpoint");
|
info!("Stopping RPC endpoint");
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
tokio::task::spawn_blocking(server)
|
tokio::task::spawn_blocking(server)
|
||||||
} else {
|
} else {
|
||||||
// There is no RPC port, so the RPC task does nothing.
|
// There is no RPC port, so the RPC task does nothing.
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,7 @@ use zebra_consensus::CheckpointList;
|
||||||
use zebra_rpc::server::RpcServer;
|
use zebra_rpc::server::RpcServer;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
application::app_version,
|
||||||
components::{
|
components::{
|
||||||
inbound::{self, InboundSetupData},
|
inbound::{self, InboundSetupData},
|
||||||
mempool::{self, Mempool},
|
mempool::{self, Mempool},
|
||||||
|
|
@ -196,7 +197,7 @@ impl StartCmd {
|
||||||
.in_current_span(),
|
.in_current_span(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let rpc_task_handle = RpcServer::spawn(config.rpc);
|
let rpc_task_handle = RpcServer::spawn(config.rpc, app_version().to_string());
|
||||||
|
|
||||||
info!("spawned initial Zebra tasks");
|
info!("spawned initial Zebra tasks");
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue