zebrad/commands/
tip_height.rs1use std::path::PathBuf;
7
8use abscissa_core::{Application, Command, Runnable};
9use clap::Parser;
10use color_eyre::eyre::{eyre, Result};
11
12use zebra_chain::{
13 block::{self},
14 parameters::Network,
15};
16
17use zebra_state::ReadStateService;
18
19use crate::prelude::APPLICATION;
20
21#[derive(Command, Debug, Default, Parser)]
23pub struct TipHeightCmd {
24 #[clap(long, short, help = "path to directory with the Zebra chain state")]
26 cache_dir: Option<PathBuf>,
27
28 #[clap(long, short, help = "the network of the chain to load")]
30 network: Network,
31}
32
33impl Runnable for TipHeightCmd {
34 #[allow(clippy::print_stdout)]
38 fn run(&self) {
39 match self.load_tip_height() {
40 Ok(height) => println!("{}", height.0),
41 Err(error) => tracing::error!("Failed to read chain tip height from state: {error}"),
42 }
43 }
44}
45
46impl TipHeightCmd {
47 fn load_tip_height(&self) -> Result<block::Height> {
49 self.load_read_state()
50 .best_tip()
51 .map(|(height, _hash)| height)
52 .ok_or_else(|| eyre!("State directory doesn't have a chain tip block"))
53 }
54
55 fn load_read_state(&self) -> ReadStateService {
57 let mut config = APPLICATION.config().state.clone();
58
59 if let Some(cache_dir) = self.cache_dir.clone() {
60 config.cache_dir = cache_dir;
61 }
62
63 zebra_state::init_read_only(config, &self.network).0
64 }
65}