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, aggregate: bool,
span: Option<u64>, 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 // Wallet Commands
Address, Address,
Airdrop { Airdrop {
@ -371,6 +380,7 @@ pub fn parse_command(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, Box<dyn
}, },
// Vote Commands // Vote Commands
("create-vote-account", Some(matches)) => parse_vote_create_account(matches), ("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)) => { ("vote-authorize-voter", Some(matches)) => {
parse_vote_authorize(matches, VoteAuthorize::Voter) parse_vote_authorize(matches, VoteAuthorize::Voter)
} }
@ -1265,15 +1275,28 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
&vote_account_pubkey, &vote_account_pubkey,
*use_lamports_unit, *use_lamports_unit,
), ),
CliCommand::VoteAuthorize(vote_account_pubkey, new_authorized_pubkey, vote_authorize) => { CliCommand::VoteAuthorize {
process_vote_authorize( vote_account_pubkey,
&rpc_client, new_authorized_pubkey,
config, vote_authorize,
&vote_account_pubkey, } => process_vote_authorize(
&new_authorized_pubkey, &rpc_client,
*vote_authorize, 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 { CliCommand::Uptime {
pubkey: vote_account_pubkey, pubkey: vote_account_pubkey,
aggregate, aggregate,
@ -2254,8 +2277,20 @@ mod tests {
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let new_authorized_pubkey = Pubkey::new_rand(); let new_authorized_pubkey = Pubkey::new_rand();
config.command = config.command = CliCommand::VoteAuthorize {
CliCommand::VoteAuthorize(bob_pubkey, new_authorized_pubkey, VoteAuthorize::Voter); 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); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
@ -2438,7 +2473,18 @@ mod tests {
}; };
assert!(process_command(&config).is_err()); 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()); assert!(process_command(&config).is_err());
config.command = CliCommand::GetSlot { 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)"), .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(
SubCommand::with_name("vote-authorize-voter") SubCommand::with_name("vote-authorize-voter")
.about("Authorize a new vote signing keypair for the given vote account") .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(); let new_authorized_pubkey = pubkey_of(matches, "new_authorized_pubkey").unwrap();
Ok(CliCommandInfo { Ok(CliCommandInfo {
command: CliCommand::VoteAuthorize( command: CliCommand::VoteAuthorize {
vote_account_pubkey, vote_account_pubkey,
new_authorized_pubkey, new_authorized_pubkey,
vote_authorize, 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, require_keypair: true,
}) })
} }
@ -315,6 +361,40 @@ pub fn process_vote_authorize(
log_instruction_custom_error::<VoteError>(result) 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( fn get_vote_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
@ -460,17 +540,24 @@ mod tests {
let keypair = Keypair::new(); let keypair = Keypair::new();
let pubkey = keypair.pubkey(); let pubkey = keypair.pubkey();
let pubkey_string = pubkey.to_string(); 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![ let test_authorize_voter = test_commands.clone().get_matches_from(vec![
"test", "test",
"vote-authorize-voter", "vote-authorize-voter",
&pubkey_string, &pubkey_string,
&pubkey_string, &pubkey2_string,
]); ]);
assert_eq!( assert_eq!(
parse_command(&test_authorize_voter).unwrap(), parse_command(&test_authorize_voter).unwrap(),
CliCommandInfo { 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 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 // Test Uptime Subcommand
let pubkey = Pubkey::new_rand(); let pubkey = Pubkey::new_rand();
let matches = test_commands.clone().get_matches_from(vec![ let matches = test_commands.clone().get_matches_from(vec![

View File

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