agave_validator/commands/repair_shred_from_peer/
mod.rs1use {
2 crate::{
3 admin_rpc_service,
4 commands::{FromClapArgMatches, Result},
5 },
6 clap::{value_t, App, Arg, ArgMatches, SubCommand},
7 solana_clap_utils::input_validators::{is_parsable, is_pubkey},
8 solana_pubkey::Pubkey,
9 std::path::Path,
10};
11
12const COMMAND: &str = "repair-shred-from-peer";
13
14#[derive(Debug, PartialEq)]
15pub struct RepairShredFromPeerArgs {
16 pub pubkey: Option<Pubkey>,
17 pub slot: u64,
18 pub shred: u64,
19}
20
21impl FromClapArgMatches for RepairShredFromPeerArgs {
22 fn from_clap_arg_match(matches: &ArgMatches) -> Result<Self> {
23 Ok(RepairShredFromPeerArgs {
24 pubkey: value_t!(matches, "pubkey", Pubkey).ok(),
25 slot: value_t!(matches, "slot", u64)?,
26 shred: value_t!(matches, "shred", u64)?,
27 })
28 }
29}
30
31pub fn command<'a>() -> App<'a, 'a> {
32 SubCommand::with_name(COMMAND)
33 .about("Request a repair from the specified validator")
34 .arg(
35 Arg::with_name("pubkey")
36 .long("pubkey")
37 .value_name("PUBKEY")
38 .required(false)
39 .takes_value(true)
40 .validator(is_pubkey)
41 .help("Identity pubkey of the validator to repair from"),
42 )
43 .arg(
44 Arg::with_name("slot")
45 .long("slot")
46 .value_name("SLOT")
47 .required(true)
48 .takes_value(true)
49 .validator(is_parsable::<u64>)
50 .help("Slot to repair"),
51 )
52 .arg(
53 Arg::with_name("shred")
54 .long("shred")
55 .value_name("SHRED")
56 .required(true)
57 .takes_value(true)
58 .validator(is_parsable::<u64>)
59 .help("Shred to repair"),
60 )
61}
62
63pub fn execute(matches: &ArgMatches, ledger_path: &Path) -> Result<()> {
64 let RepairShredFromPeerArgs {
65 pubkey,
66 slot,
67 shred,
68 } = RepairShredFromPeerArgs::from_clap_arg_match(matches)?;
69
70 let admin_client = admin_rpc_service::connect(ledger_path);
71 admin_rpc_service::runtime().block_on(async move {
72 admin_client
73 .await?
74 .repair_shred_from_peer(pubkey, slot, shred)
75 .await
76 })?;
77
78 Ok(())
79}
80
81#[cfg(test)]
82mod tests {
83 use {
84 super::*,
85 crate::commands::tests::{
86 verify_args_struct_by_command, verify_args_struct_by_command_is_error,
87 },
88 std::str::FromStr,
89 };
90
91 #[test]
92 fn verify_args_struct_by_command_repair_shred_from_peer_missing_slot_and_shred() {
93 verify_args_struct_by_command_is_error::<RepairShredFromPeerArgs>(command(), vec![COMMAND]);
94 verify_args_struct_by_command_is_error::<RepairShredFromPeerArgs>(
95 command(),
96 vec![COMMAND, "--slot", "1"],
97 );
98 verify_args_struct_by_command_is_error::<RepairShredFromPeerArgs>(
99 command(),
100 vec![COMMAND, "--shred", "2"],
101 );
102 }
103
104 #[test]
105 fn verify_args_struct_by_command_repair_shred_from_peer_missing_pubkey() {
106 verify_args_struct_by_command(
107 command(),
108 vec![COMMAND, "--slot", "1", "--shred", "2"],
109 RepairShredFromPeerArgs {
110 pubkey: None,
111 slot: 1,
112 shred: 2,
113 },
114 );
115 }
116
117 #[test]
118 fn verify_args_struct_by_command_repair_shred_from_peer_with_pubkey() {
119 verify_args_struct_by_command(
120 command(),
121 vec![
122 COMMAND,
123 "--slot",
124 "1",
125 "--shred",
126 "2",
127 "--pubkey",
128 "ch1do11111111111111111111111111111111111111",
129 ],
130 RepairShredFromPeerArgs {
131 pubkey: Some(
132 Pubkey::from_str("ch1do11111111111111111111111111111111111111").unwrap(),
133 ),
134 slot: 1,
135 shred: 2,
136 },
137 );
138 }
139}