decdn_common/cli/appeal.rs
1//! `decdn appeal` command surface — operator-facing slash-appeal filing
2//! (ADR 028). Currently one subcommand, `slash`, which posts the appeal bond
3//! and files an appeal against a slash via `SlashAppeal.openSlashAppeal`.
4//!
5//! The role-gated fast-track / grant / uphold actions (emergency multisig and
6//! Governor) are intentionally *not* exposed here — they are governance
7//! operations, not user-CLI surface.
8
9use clap::{Args, Subcommand};
10
11use crate::cli::common::CommonChainArgs;
12
13/// `decdn appeal` — file a slash appeal.
14#[derive(Args, Debug)]
15pub struct AppealArgs {
16 /// Appeal subcommand to execute.
17 #[command(subcommand)]
18 pub command: AppealCommand,
19}
20
21/// `decdn appeal` subcommands.
22#[derive(Subcommand, Debug)]
23pub enum AppealCommand {
24 /// File an appeal against a slash, posting the appeal bond
25 /// (`SlashAppeal.openSlashAppeal`). Must be run by the slashed operator,
26 /// within the 30-day filing window.
27 Slash(AppealSlashArgs),
28}
29
30/// Arguments for `decdn appeal slash <SLASH_ID> <EVIDENCE_BUNDLE_HASH>`.
31#[derive(Args, Debug)]
32pub struct AppealSlashArgs {
33 /// The on-chain slash id to appeal (surfaced by the daemon admin RPC
34 /// `admin_v1_slashes`, or the `Slashed` event's `slashId`). A `uint256`
35 /// decimal string — taken as text so an id above `u64::MAX` still parses.
36 #[arg(value_name = "SLASH_ID")]
37 pub slash_id: String,
38
39 /// Evidence bundle hash — a 0x-prefixed 32-byte hex reference to the
40 /// off-chain evidence bundle (ADR 028). Stored on-chain verbatim.
41 #[arg(value_name = "EVIDENCE_BUNDLE_HASH")]
42 pub evidence_bundle_hash: String,
43
44 /// `SlashAppeal` contract address. Overrides
45 /// `blockchain.slash_appeal_address`. The config-file value is read as
46 /// plain TOML (no `${VAR}` expansion); use this flag or the env var for
47 /// substitution.
48 #[arg(long, value_name = "ADDR", env = "DECDN_SLASH_APPEAL_ADDRESS")]
49 pub slash_appeal_address: Option<String>,
50
51 /// Shared chain coordinates (rpc, keystore, chain id, `--dry-run`,
52 /// `--json`). Only the [`CommonChainArgs`] subset is flattened here — the
53 /// appeal path reads nothing from the `CapacityBond` / swap flag group, so
54 /// exposing it would advertise flags this command silently ignores.
55 #[command(flatten)]
56 pub chain: CommonChainArgs,
57}