feat(util): add a `zebra-tip-height` utility (#4289)
* Move `init_tracing` to `lib.rs` Allow it to be reused by other binaries. * Fix `hex` dependency inclusion in `zebra-chain` It would previously fail because `hex` was being included without the `serde` feature, even though we required that for `transparent::Script`. * Implement `FromStr` for `Network` Make it easy to receive it as a command-line parameter. * Add `zebra-tip-height` utility Obtains the chain tip height of a directory containing Zebra state. * Remove Tokio dependency from `zebra-utils` It wasn't actually used by the `zebra-tip-height` utility. * Remove `BoxStateService` type alias It's not needed if we don't return the unused state service. This also allows removing the `tower` dependency. * Remove unnecessary attribute Leftover from copied code. * Make `cache_dir` argument optional Fallback to the default Zebra state cache directory. * Remove added newline Minor formatting fix, to avoid adding an unnecessary newline. * Move `tip-height` command into `zebrad` Make it available as a sub-command in `zebrad`. * Make some zebrad sub-commands only log warnings Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
parent
f3f26ff85f
commit
9538ad29e5
|
@ -9,7 +9,7 @@ edition = "2021"
|
|||
|
||||
[features]
|
||||
default = []
|
||||
proptest-impl = ["proptest", "proptest-derive", "zebra-test", "rand", "rand_chacha", "tokio", "hex/serde"]
|
||||
proptest-impl = ["proptest", "proptest-derive", "zebra-test", "rand", "rand_chacha", "tokio"]
|
||||
bench = ["zebra-test"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -29,7 +29,7 @@ fpe = "0.5.1"
|
|||
futures = "0.3.21"
|
||||
group = "0.11.0"
|
||||
halo2 = { package = "halo2_proofs", version = "=0.1.0-beta.4" }
|
||||
hex = "0.4.3"
|
||||
hex = { version = "0.4.3", features = ["serde"] }
|
||||
incrementalmerkletree = "0.3.0-beta.2"
|
||||
itertools = "0.10.3"
|
||||
jubjub = "0.8.0"
|
||||
|
@ -77,8 +77,6 @@ itertools = "0.10.3"
|
|||
spandoc = "0.2.2"
|
||||
tracing = "0.1.31"
|
||||
|
||||
hex = { version = "0.4.3", features = ["serde"] }
|
||||
|
||||
proptest = "0.10.1"
|
||||
proptest-derive = "0.3.0"
|
||||
rand = { version = "0.8.5", package = "rand" }
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use std::{convert::From, fmt};
|
||||
use std::{convert::From, fmt, str::FromStr};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
use crate::{block::Height, parameters::NetworkUpgrade::Canopy};
|
||||
|
||||
|
@ -117,3 +119,19 @@ impl Default for Network {
|
|||
Network::Mainnet
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Network {
|
||||
type Err = InvalidNetworkError;
|
||||
|
||||
fn from_str(string: &str) -> Result<Self, Self::Err> {
|
||||
match string.to_lowercase().as_str() {
|
||||
"mainnet" => Ok(Network::Mainnet),
|
||||
"testnet" => Ok(Network::Testnet),
|
||||
_ => Err(InvalidNetworkError(string.to_owned())),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Error)]
|
||||
#[error("Invalid network: {0}")]
|
||||
pub struct InvalidNetworkError(String);
|
||||
|
|
|
@ -12,22 +12,15 @@ use color_eyre::eyre::{ensure, Result};
|
|||
use serde_json::Value;
|
||||
use std::process::Stdio;
|
||||
use structopt::StructOpt;
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
use zebra_chain::block;
|
||||
use zebra_utils::init_tracing;
|
||||
|
||||
#[cfg(unix)]
|
||||
use std::os::unix::process::ExitStatusExt;
|
||||
|
||||
mod args;
|
||||
|
||||
/// Initialise tracing using its defaults.
|
||||
fn init_tracing() {
|
||||
tracing_subscriber::Registry::default()
|
||||
.with(tracing_error::ErrorLayer::default())
|
||||
.init();
|
||||
}
|
||||
|
||||
/// Return a new `zcash-cli` command, including the `zebra-checkpoints`
|
||||
/// passthrough arguments.
|
||||
fn passthrough_cmd() -> std::process::Command {
|
||||
|
|
|
@ -4,3 +4,12 @@
|
|||
#![doc(html_favicon_url = "https://zfnd.org/wp-content/uploads/2022/03/zebra-favicon-128.png")]
|
||||
#![doc(html_logo_url = "https://zfnd.org/wp-content/uploads/2022/03/zebra-icon.png")]
|
||||
#![doc(html_root_url = "https://doc.zebra.zfnd.org/zebra_utils")]
|
||||
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
|
||||
/// Initialise tracing using its defaults.
|
||||
pub fn init_tracing() {
|
||||
tracing_subscriber::Registry::default()
|
||||
.with(tracing_error::ErrorLayer::default())
|
||||
.init();
|
||||
}
|
||||
|
|
|
@ -342,14 +342,18 @@ impl Application for ZebradApp {
|
|||
.as_ref()
|
||||
.expect("config is loaded before register_components");
|
||||
|
||||
let default_filter = if command.verbose { "debug" } else { "info" };
|
||||
let default_filter = command
|
||||
.command
|
||||
.as_ref()
|
||||
.map(|zcmd| zcmd.default_tracing_filter(command.verbose))
|
||||
.unwrap_or("warn");
|
||||
let is_server = command
|
||||
.command
|
||||
.as_ref()
|
||||
.map(ZebradCmd::is_server)
|
||||
.unwrap_or(false);
|
||||
|
||||
// Ignore the tracing filter for short-lived commands
|
||||
// Ignore the configured tracing filter for short-lived utility commands
|
||||
let mut tracing_config = cfg_ref.tracing.clone();
|
||||
if is_server {
|
||||
// Override the default tracing filter based on the command-line verbosity.
|
||||
|
|
|
@ -4,12 +4,13 @@ mod copy_state;
|
|||
mod download;
|
||||
mod generate;
|
||||
mod start;
|
||||
mod tip_height;
|
||||
mod version;
|
||||
|
||||
use self::ZebradCmd::*;
|
||||
use self::{
|
||||
copy_state::CopyStateCmd, download::DownloadCmd, generate::GenerateCmd, start::StartCmd,
|
||||
version::VersionCmd,
|
||||
tip_height::TipHeightCmd, version::VersionCmd,
|
||||
};
|
||||
|
||||
use crate::config::ZebradConfig;
|
||||
|
@ -46,6 +47,10 @@ pub enum ZebradCmd {
|
|||
#[options(help = "start the application")]
|
||||
Start(StartCmd),
|
||||
|
||||
/// The `tip-height` subcommand
|
||||
#[options(help = "get the block height of Zebra's persisted chain state")]
|
||||
TipHeight(TipHeightCmd),
|
||||
|
||||
/// The `version` subcommand
|
||||
#[options(help = "display version information")]
|
||||
Version(VersionCmd),
|
||||
|
@ -54,12 +59,41 @@ pub enum ZebradCmd {
|
|||
impl ZebradCmd {
|
||||
/// Returns true if this command is a server command.
|
||||
///
|
||||
/// Servers load extra components, and use the configured tracing filter.
|
||||
///
|
||||
/// For example, `Start` acts as a Zcash node.
|
||||
pub(crate) fn is_server(&self) -> bool {
|
||||
// List all the commands, so new commands have to make a choice here
|
||||
match self {
|
||||
// List all the commands, so new commands have to make a choice here
|
||||
// Commands that run as a configured server
|
||||
CopyState(_) | Start(_) => true,
|
||||
Download(_) | Generate(_) | Help(_) | Version(_) => false,
|
||||
|
||||
// Utility commands that don't use server components
|
||||
Download(_) | Generate(_) | Help(_) | TipHeight(_) | Version(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the default log level for this command, based on the `verbose` command line flag.
|
||||
///
|
||||
/// Some commands need to be quiet by default.
|
||||
pub(crate) fn default_tracing_filter(&self, verbose: bool) -> &'static str {
|
||||
let only_show_warnings = match self {
|
||||
// Commands that generate quiet output by default.
|
||||
// This output:
|
||||
// - is used by automated tools, or
|
||||
// - needs to be read easily.
|
||||
Generate(_) | TipHeight(_) | Help(_) | Version(_) => true,
|
||||
|
||||
// Commands that generate informative logging output by default.
|
||||
CopyState(_) | Download(_) | Start(_) => false,
|
||||
};
|
||||
|
||||
if only_show_warnings && !verbose {
|
||||
"warn"
|
||||
} else if only_show_warnings || !verbose {
|
||||
"info"
|
||||
} else {
|
||||
"debug"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -72,6 +106,7 @@ impl Runnable for ZebradCmd {
|
|||
Generate(cmd) => cmd.run(),
|
||||
ZebradCmd::Help(cmd) => cmd.run(),
|
||||
Start(cmd) => cmd.run(),
|
||||
TipHeight(cmd) => cmd.run(),
|
||||
Version(cmd) => cmd.run(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
//! `tip-height` subcommand - prints the block height of Zebra's persisted chain state.
|
||||
//!
|
||||
//! Prints the chain tip height stored in Zebra's state. This is useful for developers to inspect
|
||||
//! Zebra state directories.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use abscissa_core::{Command, Options, Runnable};
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
|
||||
use zebra_chain::{block, chain_tip::ChainTip, parameters::Network};
|
||||
use zebra_state::LatestChainTip;
|
||||
|
||||
use crate::prelude::app_config;
|
||||
|
||||
/// `zebra-tip-height` subcommand
|
||||
#[derive(Command, Debug, Options)]
|
||||
pub struct TipHeightCmd {
|
||||
/// Path to Zebra's cached state.
|
||||
#[options(help = "path to directory with the Zebra chain state")]
|
||||
cache_dir: Option<PathBuf>,
|
||||
|
||||
/// The network to obtain the chain tip.
|
||||
#[options(default = "mainnet", help = "the network of the chain to load")]
|
||||
network: Network,
|
||||
}
|
||||
|
||||
impl Runnable for TipHeightCmd {
|
||||
/// `tip-height` sub-command entrypoint.
|
||||
///
|
||||
/// Reads the chain tip height from a cache directory with Zebra's state.
|
||||
#[allow(clippy::print_stdout)]
|
||||
fn run(&self) {
|
||||
match self.load_tip_height() {
|
||||
Ok(height) => println!("{}", height.0),
|
||||
Err(error) => tracing::error!("Failed to read chain tip height from state: {error}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TipHeightCmd {
|
||||
/// Load the chain tip height from the state cache directory.
|
||||
fn load_tip_height(&self) -> Result<block::Height> {
|
||||
let latest_chain_tip = self.load_latest_chain_tip();
|
||||
|
||||
latest_chain_tip
|
||||
.best_tip_height()
|
||||
.ok_or_else(|| eyre!("State directory doesn't have a chain tip block"))
|
||||
}
|
||||
|
||||
/// Starts a state service using the `cache_dir` and `network` from the provided arguments.
|
||||
fn load_latest_chain_tip(&self) -> LatestChainTip {
|
||||
let mut config = app_config().state.clone();
|
||||
|
||||
if let Some(cache_dir) = self.cache_dir.clone() {
|
||||
config.cache_dir = cache_dir;
|
||||
}
|
||||
|
||||
let (_state_service, _read_state_service, latest_chain_tip, _chain_tip_change) =
|
||||
zebra_state::init(config, self.network);
|
||||
|
||||
latest_chain_tip
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue