pd/cli.rs
1//! Command-line interface utilities for the `pd` daemon.
2
3use {
4 clap::{Parser, Subcommand},
5 std::{net::SocketAddr, path::PathBuf},
6 url::Url,
7};
8
9#[derive(Debug, Parser)]
10#[clap(name = "pd", about = "The Penumbra daemon.", version)]
11pub struct Opt {
12 /// Command to run.
13 #[clap(subcommand)]
14 pub cmd: RootCommand,
15}
16
17#[derive(Debug, Subcommand)]
18pub enum RootCommand {
19 /// Starts the Penumbra daemon.
20 Start {
21 /// The path used to store all `pd`-related data and configuration.
22 /// If unset, defaults to ~/.penumbra/network_data/node0/pd.
23 #[clap(long, env = "PENUMBRA_PD_HOME", display_order = 100)]
24 home: Option<PathBuf>,
25 /// Bind the ABCI server to this socket.
26 ///
27 /// The ABCI server is used by Tendermint to drive the application state.
28 #[clap(
29 short,
30 long,
31 env = "PENUMBRA_PD_ABCI_BIND",
32 default_value = "127.0.0.1:26658",
33 display_order = 400
34 )]
35 // TODO: Add support for Unix domain sockets, available in tower-abci >=0.10.0
36 abci_bind: SocketAddr,
37 /// Bind the gRPC server to this socket.
38 ///
39 /// The gRPC server supports both grpc (HTTP/2) and grpc-web (HTTP/1.1) clients.
40 ///
41 /// If `grpc_auto_https` is set, this defaults to `0.0.0.0:443` and uses HTTPS.
42 ///
43 /// If `grpc_auto_https` is not set, this defaults to `127.0.0.1:8080` without HTTPS.
44 #[clap(short, long, env = "PENUMBRA_PD_GRPC_BIND", display_order = 201)]
45 grpc_bind: Option<SocketAddr>,
46 /// If set, serve gRPC using auto-managed HTTPS with this domain name.
47 ///
48 /// NOTE: This option automatically provisions TLS certificates from
49 /// Let's Encrypt and caches them in the `home` directory. The
50 /// production LE CA has rate limits, so be careful using this option
51 /// with `pd network unsafe-reset-all`, which will delete the certificates
52 /// and force re-issuance, possibly hitting the rate limit. See the
53 /// `--acme-staging` option.
54 #[clap(long, value_name = "DOMAIN", display_order = 200)]
55 grpc_auto_https: Option<String>,
56 /// Enable use of the LetsEncrypt ACME staging API (https://letsencrypt.org/docs/staging-environment/),
57 /// which is more forgiving of ratelimits. Set this option to `true`
58 /// if you're trying out the `--grpc-auto-https` option for the first time,
59 /// to validate your configuration, before subjecting yourself to production
60 /// ratelimits. This option has no effect if `--grpc-auto-https` is not set.
61 #[clap(long, display_order = 201)]
62 acme_staging: bool,
63 /// Bind the metrics endpoint to this socket.
64 #[clap(
65 short,
66 long,
67 env = "PENUMBRA_PD_METRICS_BIND",
68 default_value = "127.0.0.1:9000",
69 display_order = 300
70 )]
71 metrics_bind: SocketAddr,
72 /// The JSON-RPC address of the CometBFT node driving this `pd`
73 /// instance.
74 ///
75 /// This is used to proxy requests from the gRPC server to CometBFT,
76 /// so clients only need to connect to one endpoint and don't need to
77 /// worry about the peculiarities of CometBFT's JSON-RPC encoding
78 /// format.
79 #[clap(
80 short,
81 long,
82 env = "PENUMBRA_PD_COMETBFT_PROXY_URL",
83 default_value = "http://127.0.0.1:26657",
84 display_order = 401,
85 // Support old arg name for a while, as we migrate Tendermint -> CometBFT.
86 alias = "tendermint-addr",
87 )]
88 cometbft_addr: Url,
89 /// Enable expensive RPCs, currently a no-op.
90 #[clap(short, long, display_order = 500)]
91 enable_expensive_rpc: bool,
92 },
93
94 /// Generate, join, or reset a network.
95 Network {
96 /// Path to directory to store output in. Must not exist. Defaults to
97 /// ~/.penumbra/network_data".
98 #[clap(long)]
99 network_dir: Option<PathBuf>,
100 #[clap(subcommand)]
101 net_cmd: NetworkCommand,
102 },
103
104 /// Export the storage state the full node.
105 Export {
106 /// The home directory of the full node.
107 #[clap(long, env = "PENUMBRA_PD_HOME", display_order = 100)]
108 home: PathBuf,
109 /// The directory where the exported node state will be written.
110 #[clap(long, display_order = 200, alias = "export-path")]
111 export_directory: PathBuf,
112 /// An optional filepath for a compressed archive containing the exported
113 /// node state, e.g. ~/pd-backup.tar.gz.
114 #[clap(long, display_order = 200)]
115 export_archive: Option<PathBuf>,
116 /// Whether to prune the JMT tree.
117 #[clap(long, display_order = 300)]
118 prune: bool,
119 },
120
121 /// Run a migration before resuming post-upgrade.
122 Migrate {
123 /// The home directory of the full node.
124 ///
125 /// Migration is performed in-place on the home directory.
126 #[clap(long, env = "PENUMBRA_PD_HOME", display_order = 100)]
127 home: Option<PathBuf>,
128 /// If set, also migrate the CometBFT state located in this home directory.
129 /// If both `--home` and `--comet-home` are unset, will attempt to migrate
130 /// CometBFT state alongside the auto-located `pd` state.
131 // Note: this does _NOT_ use an env var because we are trying to
132 // get explicit consent to muck around in another daemon's state.
133 #[clap(long, display_order = 200)]
134 comet_home: Option<PathBuf>,
135 /// If set, force a migration to occur even if the chain is not halted.
136 /// Will not override a detected mismatch in state versions, or on signs
137 /// of corruption. This is "expert mode" and potentially destructive.
138 #[clap(long, display_order = 1000)]
139 force: bool,
140 /// If set, edit local state to permit the node to start, despite
141 /// a pre-existing halt order, e.g. via governance. This option
142 /// can be useful for relayer operators, to run a temporary archive node
143 /// across upgrade boundaries.
144 #[clap(long, display_order = 1000)]
145 ready_to_start: bool,
146 },
147}
148
149#[derive(Debug, Subcommand)]
150pub enum NetworkCommand {
151 /// Generates a directory structure containing necessary files to create a new
152 /// network config from genesis, based on input configuration.
153 Generate {
154 /// The `timeout_commit` parameter (block interval) to configure Tendermint with.
155 #[clap(long)]
156 timeout_commit: Option<tendermint::Timeout>,
157 /// Number of blocks per epoch.
158 #[clap(long)]
159 epoch_duration: Option<u64>,
160 /// Number of blocks that must elapse before unbonding stake is released.
161 #[clap(long)]
162 unbonding_delay: Option<u64>,
163 /// Maximum number of validators in the consensus set.
164 #[clap(long)]
165 active_validator_limit: Option<u64>,
166 /// Whether to preserve the chain ID (useful for public networks) or append a random suffix (useful for dev/testing).
167 #[clap(long)]
168 preserve_chain_id: bool,
169 /// Path to CSV file containing initial allocations [default: latest testnet].
170 #[clap(long, parse(from_os_str))]
171 allocations_input_file: Option<PathBuf>,
172 /// Penumbra wallet address to include in genesis allocations.
173 /// Intended to make dev experience nicer on first run:
174 /// generate a wallet, view its address, then generate a devnet
175 /// with that address included in the base allocations.
176 #[clap(long)]
177 allocation_address: Option<penumbra_sdk_keys::Address>,
178 #[clap(long, parse(from_os_str))]
179 /// Path to JSON file containing initial validator configs [default: latest testnet].
180 validators_input_file: Option<PathBuf>,
181 /// Testnet name [default: latest testnet].
182 #[clap(long)]
183 chain_id: Option<String>,
184 /// The duration, in number of blocks, that a governance proposal
185 /// can be voted on.
186 #[clap(long)]
187 proposal_voting_blocks: Option<u64>,
188 /// The fixed gas price for all transactions on the network.
189 /// Described as "simple" because the single value will be reused
190 /// for all gas price types: block space, compact block space, verification, and execution.
191 /// The numeric value is one-thousandths of the base unit of the fee token,
192 /// so `--gas-price-simple=1000` means all resources will have a cost of 1upenumbra.
193 #[clap(long)]
194 gas_price_simple: Option<u64>,
195 /// Base hostname for a validator's p2p service. If multiple validators
196 /// exist in the genesis, e.g. via `--validators-input-file`, then
197 /// numeric suffixes are automatically added, e.g. "-0", "-1", etc.
198 /// Helpful for when you know the validator DNS names ahead of time,
199 /// e.g. in Kubernetes service addresses. These option is most useful
200 /// to provide peering on a private network setup. If you plan to expose
201 /// the validator P2P services to the internet, see the `--external-addresses` option.
202 #[clap(long)]
203 peer_address_template: Option<String>,
204 /// Public addresses and ports for the Tendermint P2P services of the genesis
205 /// validator. Accepts comma-separated values, to support multiple validators.
206 /// If `--validators-input-file` is used to increase the number
207 /// of validators, and the `--external-addresses` flag is set, then the number of
208 /// external addresses must equal the number of validators. See the
209 /// `--peer-address-template` flag if you don't plan to expose the network
210 /// to public peers.
211 #[clap(long)]
212 // TODO we should support DNS names here. However, there are complications:
213 // https://github.com/tendermint/tendermint/issues/1521
214 external_addresses: Option<String>,
215 },
216
217 /// Like `network generate`, but joins the network to which the specified node belongs.
218 /// Requires a URL for the CometBFT RPC for the bootstrap node.
219 Join {
220 /// URL of the remote CometBFT RPC endpoint for bootstrapping connection.
221 #[clap(env = "PENUMBRA_PD_JOIN_URL")]
222 node: Url,
223 /// Optional URL of archived node state in .tar.gz format. The archive will be
224 /// downloaded and extracted locally, allowing the node to join a network at a block height
225 /// higher than 0. Supports loading the archive from a local file, if set with file scheme
226 /// explicitly, e.g. `file:///path/to/archive.tar.gz`.
227 #[clap(long, env = "PENUMBRA_PD_ARCHIVE_URL")]
228 archive_url: Option<Url>,
229 /// Human-readable name to identify node on network
230 // Default: 'node-#'
231 #[clap(long, env = "PENUMBRA_PD_TM_EXTERNAL_ADDR")]
232 moniker: Option<String>,
233 /// Public URL to advertise for this node's Tendermint P2P service.
234 /// Setting this option will instruct other nodes on the network to connect
235 /// to yours. Must be in the form of a socket, e.g. "1.2.3.4:26656".
236 #[clap(long, env = "PENUMBRA_PD_TM_EXTERNAL_ADDR")]
237 external_address: Option<SocketAddr>,
238 /// When generating Tendermint config, use this socket to bind the Tendermint RPC service.
239 #[clap(long, env = "PENUMBRA_PD_TM_RPC_BIND", default_value = "0.0.0.0:26657")]
240 tendermint_rpc_bind: SocketAddr,
241 /// When generating Tendermint config, use this socket to bind the Tendermint P2P service.
242 #[clap(long, env = "PENUMBRA_PD_TM_P2P_BIND", default_value = "0.0.0.0:26656")]
243 tendermint_p2p_bind: SocketAddr,
244 /// Leave the downloaded archive file on disk after extraction.
245 #[clap(long, env = "PENUMBRA_PD_LEAVE_ARCHIVE", action)]
246 leave_archive: bool,
247 },
248
249 /// Reset all `pd` network state. This is a destructive action!
250 UnsafeResetAll {},
251}