zebra_checkpoints/
args.rs

1//! zebra-checkpoints arguments
2//!
3//! For usage please refer to the program help: `zebra-checkpoints --help`
4
5use std::{net::SocketAddr, str::FromStr};
6
7use structopt::StructOpt;
8use thiserror::Error;
9
10use zebra_chain::block::Height;
11
12/// The backend type the zebra-checkpoints utility will use to get data from.
13///
14/// This changes which RPCs the tool calls, and which fields it expects them to have.
15#[derive(Clone, Debug, PartialEq, Eq)]
16pub enum Backend {
17    /// Expect a Zebra-style backend with limited RPCs and fields.
18    ///
19    /// Calls these specific RPCs:
20    /// - `getblock` with `verbose=0`, manually calculating `hash`, `height`, and `size`
21    /// - `getblockchaininfo`, expecting a `blocks` field
22    ///
23    /// Supports both `zebrad` and `zcashd` nodes.
24    Zebrad,
25
26    /// Expect a `zcashd`-style backend with all available RPCs and fields.
27    ///
28    /// Calls these specific RPCs:
29    /// - `getblock` with `verbose=1`, expecting `hash`, `height`, and `size` fields
30    /// - `getblockchaininfo`, expecting a `blocks` field
31    ///
32    /// Currently only supported with `zcashd`.
33    Zcashd,
34}
35
36impl FromStr for Backend {
37    type Err = InvalidBackendError;
38
39    fn from_str(string: &str) -> Result<Self, Self::Err> {
40        match string.to_lowercase().as_str() {
41            "zebrad" => Ok(Backend::Zebrad),
42            "zcashd" => Ok(Backend::Zcashd),
43            _ => Err(InvalidBackendError(string.to_owned())),
44        }
45    }
46}
47
48/// An error indicating that the supplied string is not a valid [`Backend`] name.
49#[derive(Clone, Debug, Error, PartialEq, Eq)]
50#[error("Invalid backend: {0}")]
51pub struct InvalidBackendError(String);
52
53/// The transport used by the zebra-checkpoints utility to connect to the [`Backend`].
54///
55/// This changes how the tool makes RPC requests.
56#[derive(Clone, Debug, PartialEq, Eq)]
57pub enum Transport {
58    /// Launch the `zcash-cli` command in a subprocess, and read its output.
59    ///
60    /// The RPC name and parameters are sent as command-line arguments.
61    /// Responses are read from the command's standard output.
62    ///
63    /// Requires the `zcash-cli` command, which is part of `zcashd`'s tools.
64    /// Supports both `zebrad` and `zcashd` nodes.
65    Cli,
66
67    /// Connect directly to the node using TCP, and use the JSON-RPC protocol.
68    ///
69    /// Uses JSON-RPC over HTTP for sending the RPC name and parameters, and
70    /// receiving responses.
71    ///
72    /// Always supports the `zebrad` node.
73    /// Only supports `zcashd` nodes using a JSON-RPC TCP port with no authentication.
74    Direct,
75}
76
77impl FromStr for Transport {
78    type Err = InvalidTransportError;
79
80    fn from_str(string: &str) -> Result<Self, Self::Err> {
81        match string.to_lowercase().as_str() {
82            "cli" | "zcash-cli" | "zcashcli" | "zcli" | "z-cli" => Ok(Transport::Cli),
83            "direct" => Ok(Transport::Direct),
84            _ => Err(InvalidTransportError(string.to_owned())),
85        }
86    }
87}
88
89/// An error indicating that the supplied string is not a valid [`Transport`] name.
90#[derive(Clone, Debug, Error, PartialEq, Eq)]
91#[error("Invalid transport: {0}")]
92pub struct InvalidTransportError(String);
93
94/// zebra-checkpoints arguments
95#[derive(Clone, Debug, Eq, PartialEq, StructOpt)]
96pub struct Args {
97    /// Backend type: the node we're connecting to.
98    #[structopt(default_value = "zebrad", short, long)]
99    pub backend: Backend,
100
101    /// Transport type: the way we connect.
102    #[structopt(default_value = "cli", short, long)]
103    pub transport: Transport,
104
105    /// Path or name of zcash-cli command.
106    /// Only used if the transport is [`Cli`](Transport::Cli).
107    #[structopt(default_value = "zcash-cli", short, long)]
108    pub cli: String,
109
110    /// Address and port for RPC connections.
111    /// Used for all transports.
112    #[structopt(short, long)]
113    pub addr: Option<SocketAddr>,
114
115    /// Start looking for checkpoints after this height.
116    /// If there is no last checkpoint, we start looking at the Genesis block (height 0).
117    #[structopt(short, long)]
118    pub last_checkpoint: Option<Height>,
119
120    /// Passthrough args for `zcash-cli`.
121    /// Only used if the transport is [`Cli`](Transport::Cli).
122    #[structopt(last = true)]
123    pub zcli_args: Vec<String>,
124}