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:
Alfredo Garcia 2022-03-01 00:32:32 -03:00 committed by GitHub
parent a8a52125d0
commit b3eb38d279
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 71 additions and 11 deletions

2
Cargo.lock generated
View File

@ -5708,6 +5708,8 @@ dependencies = [
"tokio", "tokio",
"tracing", "tracing",
"tracing-futures", "tracing-futures",
"zebra-network",
"zebra-test",
] ]
[[package]] [[package]]

View File

@ -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/" }

View File

@ -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)

View File

@ -0,0 +1,2 @@
//! Test code for RPC methods
mod vectors;

View File

@ -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);
}

View File

@ -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.

View File

@ -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");