Add vote-update-validator subcommand

This commit is contained in:
Michael Vines 2019-12-12 16:04:03 -07:00
parent 75d1aa5135
commit f7a87d5e52
3 changed files with 172 additions and 18 deletions

View File

@ -190,7 +190,16 @@ pub enum CliCommand {
aggregate: bool,
span: Option<u64>,
},
VoteAuthorize(Pubkey, Pubkey, VoteAuthorize),
VoteAuthorize {
vote_account_pubkey: Pubkey,
new_authorized_pubkey: Pubkey,
vote_authorize: VoteAuthorize,
},
VoteUpdateValidator {
vote_account_pubkey: Pubkey,
new_identity_pubkey: Pubkey,
authorized_voter: KeypairEq,
},
// Wallet Commands
Address,
Airdrop {
@ -371,6 +380,7 @@ pub fn parse_command(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, Box<dyn
},
// Vote Commands
("create-vote-account", Some(matches)) => parse_vote_create_account(matches),
("vote-update-validator", Some(matches)) => parse_vote_update_validator(matches),
("vote-authorize-voter", Some(matches)) => {
parse_vote_authorize(matches, VoteAuthorize::Voter)
}
@ -1265,15 +1275,28 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
&vote_account_pubkey,
*use_lamports_unit,
),
CliCommand::VoteAuthorize(vote_account_pubkey, new_authorized_pubkey, vote_authorize) => {
process_vote_authorize(
&rpc_client,
config,
&vote_account_pubkey,
&new_authorized_pubkey,
*vote_authorize,
)
}
CliCommand::VoteAuthorize {
vote_account_pubkey,
new_authorized_pubkey,
vote_authorize,
} => process_vote_authorize(
&rpc_client,
config,
&vote_account_pubkey,
&new_authorized_pubkey,
*vote_authorize,
),
CliCommand::VoteUpdateValidator {
vote_account_pubkey,
new_identity_pubkey,
authorized_voter,
} => process_vote_update_validator(
&rpc_client,
config,
&vote_account_pubkey,
&new_identity_pubkey,
authorized_voter,
),
CliCommand::Uptime {
pubkey: vote_account_pubkey,
aggregate,
@ -2254,8 +2277,20 @@ mod tests {
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let new_authorized_pubkey = Pubkey::new_rand();
config.command =
CliCommand::VoteAuthorize(bob_pubkey, new_authorized_pubkey, VoteAuthorize::Voter);
config.command = CliCommand::VoteAuthorize {
vote_account_pubkey: bob_pubkey,
new_authorized_pubkey,
vote_authorize: VoteAuthorize::Voter,
};
let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let new_identity_pubkey = Pubkey::new_rand();
config.command = CliCommand::VoteUpdateValidator {
vote_account_pubkey: bob_pubkey,
new_identity_pubkey,
authorized_voter: Keypair::new().into(),
};
let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
@ -2438,7 +2473,18 @@ mod tests {
};
assert!(process_command(&config).is_err());
config.command = CliCommand::VoteAuthorize(bob_pubkey, bob_pubkey, VoteAuthorize::Voter);
config.command = CliCommand::VoteAuthorize {
vote_account_pubkey: bob_pubkey,
new_authorized_pubkey: bob_pubkey,
vote_authorize: VoteAuthorize::Voter,
};
assert!(process_command(&config).is_err());
config.command = CliCommand::VoteUpdateValidator {
vote_account_pubkey: bob_pubkey,
new_identity_pubkey: bob_pubkey,
authorized_voter: Keypair::new().into(),
};
assert!(process_command(&config).is_err());
config.command = CliCommand::GetSlot {

View File

@ -70,6 +70,37 @@ impl VoteSubCommands for App<'_, '_> {
.help("Public key of the authorized withdrawer (defaults to cli config pubkey)"),
),
)
.subcommand(
SubCommand::with_name("vote-update-validator")
.about("Update the vote account's validator identity")
.arg(
Arg::with_name("vote_account_pubkey")
.index(1)
.value_name("VOTE ACCOUNT PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.help("Vote account to update"),
)
.arg(
Arg::with_name("new_identity_pubkey")
.index(2)
.value_name("NEW VALIDATOR IDENTITY PUBKEY")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.help("New validator that will vote with this account"),
)
.arg(
Arg::with_name("authorized_voter")
.index(3)
.value_name("AUTHORIZED VOTER KEYPAIR")
.takes_value(true)
.required(true)
.validator(is_keypair)
.help("Authorized voter keypair"),
)
)
.subcommand(
SubCommand::with_name("vote-authorize-voter")
.about("Authorize a new vote signing keypair for the given vote account")
@ -188,11 +219,26 @@ pub fn parse_vote_authorize(
let new_authorized_pubkey = pubkey_of(matches, "new_authorized_pubkey").unwrap();
Ok(CliCommandInfo {
command: CliCommand::VoteAuthorize(
command: CliCommand::VoteAuthorize {
vote_account_pubkey,
new_authorized_pubkey,
vote_authorize,
),
},
require_keypair: true,
})
}
pub fn parse_vote_update_validator(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let new_identity_pubkey = pubkey_of(matches, "new_identity_pubkey").unwrap();
let authorized_voter = keypair_of(matches, "authorized_voter").unwrap();
Ok(CliCommandInfo {
command: CliCommand::VoteUpdateValidator {
vote_account_pubkey,
new_identity_pubkey,
authorized_voter: authorized_voter.into(),
},
require_keypair: true,
})
}
@ -315,6 +361,40 @@ pub fn process_vote_authorize(
log_instruction_custom_error::<VoteError>(result)
}
pub fn process_vote_update_validator(
rpc_client: &RpcClient,
config: &CliConfig,
vote_account_pubkey: &Pubkey,
new_identity_pubkey: &Pubkey,
authorized_voter: &Keypair,
) -> ProcessResult {
check_unique_pubkeys(
(vote_account_pubkey, "vote_account_pubkey".to_string()),
(new_identity_pubkey, "new_identity_pubkey".to_string()),
)?;
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
let ixs = vec![vote_instruction::update_node(
vote_account_pubkey,
&authorized_voter.pubkey(),
new_identity_pubkey,
)];
let mut tx = Transaction::new_signed_with_payer(
ixs,
Some(&config.keypair.pubkey()),
&[&config.keypair, authorized_voter],
recent_blockhash,
);
check_account_for_fee(
rpc_client,
&config.keypair.pubkey(),
&fee_calculator,
&tx.message,
)?;
let result = rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair]);
log_instruction_custom_error::<VoteError>(result)
}
fn get_vote_account(
rpc_client: &RpcClient,
vote_account_pubkey: &Pubkey,
@ -460,17 +540,24 @@ mod tests {
let keypair = Keypair::new();
let pubkey = keypair.pubkey();
let pubkey_string = pubkey.to_string();
let keypair2 = Keypair::new();
let pubkey2 = keypair2.pubkey();
let pubkey2_string = pubkey2.to_string();
let test_authorize_voter = test_commands.clone().get_matches_from(vec![
"test",
"vote-authorize-voter",
&pubkey_string,
&pubkey_string,
&pubkey2_string,
]);
assert_eq!(
parse_command(&test_authorize_voter).unwrap(),
CliCommandInfo {
command: CliCommand::VoteAuthorize(pubkey, pubkey, VoteAuthorize::Voter),
command: CliCommand::VoteAuthorize {
vote_account_pubkey: pubkey,
new_authorized_pubkey: pubkey2,
vote_authorize: VoteAuthorize::Voter
},
require_keypair: true
}
);
@ -581,6 +668,27 @@ mod tests {
}
);
let test_update_validator = test_commands.clone().get_matches_from(vec![
"test",
"vote-update-validator",
&pubkey_string,
&pubkey2_string,
&keypair_file,
]);
assert_eq!(
parse_command(&test_update_validator).unwrap(),
CliCommandInfo {
command: CliCommand::VoteUpdateValidator {
vote_account_pubkey: pubkey,
new_identity_pubkey: pubkey2,
authorized_voter: solana_sdk::signature::read_keypair_file(&keypair_file)
.unwrap()
.into(),
},
require_keypair: true
}
);
// Test Uptime Subcommand
let pubkey = Pubkey::new_rand();
let matches = test_commands.clone().get_matches_from(vec![

View File

@ -58,7 +58,7 @@ pub enum VoteInstruction {
/// Withdraw some amount of funds
Withdraw(u64),
/// Update the vote account's node id
/// Update the vote account's validator identity (node id)
UpdateNode(Pubkey),
}