add authorized parameters to vote api (#6072)
* add authorized parameters to vote api * code review
This commit is contained in:
147
cli/src/vote.rs
147
cli/src/vote.rs
@ -15,13 +15,16 @@ use solana_sdk::{
|
||||
};
|
||||
use solana_vote_api::{
|
||||
vote_instruction::{self, VoteError},
|
||||
vote_state::VoteState,
|
||||
vote_state::{VoteAuthorize, VoteInit, VoteState},
|
||||
};
|
||||
|
||||
pub fn parse_vote_create_account(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> {
|
||||
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
|
||||
let node_pubkey = pubkey_of(matches, "node_pubkey").unwrap();
|
||||
let commission = value_of(&matches, "commission").unwrap_or(0);
|
||||
let authorized_voter = pubkey_of(matches, "authorized_voter").unwrap_or(vote_account_pubkey);
|
||||
let authorized_withdrawer =
|
||||
pubkey_of(matches, "authorized_withdrawer").unwrap_or(vote_account_pubkey);
|
||||
let lamports = matches
|
||||
.value_of("lamports")
|
||||
.unwrap()
|
||||
@ -29,21 +32,29 @@ pub fn parse_vote_create_account(matches: &ArgMatches<'_>) -> Result<WalletComma
|
||||
.map_err(|err| WalletError::BadParameter(format!("Invalid lamports: {:?}", err)))?;
|
||||
Ok(WalletCommand::CreateVoteAccount(
|
||||
vote_account_pubkey,
|
||||
node_pubkey,
|
||||
commission,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter,
|
||||
authorized_withdrawer,
|
||||
commission,
|
||||
},
|
||||
lamports,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn parse_vote_authorize_voter(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> {
|
||||
pub fn parse_vote_authorize(
|
||||
matches: &ArgMatches<'_>,
|
||||
vote_authorize: VoteAuthorize,
|
||||
) -> Result<WalletCommand, WalletError> {
|
||||
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
|
||||
let authorized_voter_keypair = keypair_of(matches, "authorized_voter_keypair_file").unwrap();
|
||||
let new_authorized_voter_pubkey = pubkey_of(matches, "new_authorized_voter_pubkey").unwrap();
|
||||
let authorized_keypair = keypair_of(matches, "authorized_keypair_file").unwrap();
|
||||
let new_authorized_pubkey = pubkey_of(matches, "new_authorized_pubkey").unwrap();
|
||||
|
||||
Ok(WalletCommand::AuthorizeVoter(
|
||||
Ok(WalletCommand::VoteAuthorize(
|
||||
vote_account_pubkey,
|
||||
authorized_voter_keypair,
|
||||
new_authorized_voter_pubkey,
|
||||
authorized_keypair,
|
||||
new_authorized_pubkey,
|
||||
vote_authorize,
|
||||
))
|
||||
}
|
||||
|
||||
@ -58,13 +69,12 @@ pub fn process_create_vote_account(
|
||||
rpc_client: &RpcClient,
|
||||
config: &WalletConfig,
|
||||
vote_account_pubkey: &Pubkey,
|
||||
node_pubkey: &Pubkey,
|
||||
commission: u8,
|
||||
vote_init: &VoteInit,
|
||||
lamports: u64,
|
||||
) -> ProcessResult {
|
||||
check_unique_pubkeys(
|
||||
(vote_account_pubkey, "vote_account_pubkey".to_string()),
|
||||
(node_pubkey, "node_pubkey".to_string()),
|
||||
(&vote_init.node_pubkey, "node_pubkey".to_string()),
|
||||
)?;
|
||||
check_unique_pubkeys(
|
||||
(&config.keypair.pubkey(), "wallet keypair".to_string()),
|
||||
@ -73,8 +83,7 @@ pub fn process_create_vote_account(
|
||||
let ixs = vote_instruction::create_account(
|
||||
&config.keypair.pubkey(),
|
||||
vote_account_pubkey,
|
||||
node_pubkey,
|
||||
commission,
|
||||
vote_init,
|
||||
lamports,
|
||||
);
|
||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||
@ -84,36 +93,35 @@ pub fn process_create_vote_account(
|
||||
log_instruction_custom_error::<SystemError>(result)
|
||||
}
|
||||
|
||||
pub fn process_authorize_voter(
|
||||
pub fn process_vote_authorize(
|
||||
rpc_client: &RpcClient,
|
||||
config: &WalletConfig,
|
||||
vote_account_pubkey: &Pubkey,
|
||||
authorized_voter_keypair: &Keypair,
|
||||
new_authorized_voter_pubkey: &Pubkey,
|
||||
authorized_keypair: &Keypair,
|
||||
new_authorized_pubkey: &Pubkey,
|
||||
vote_authorize: VoteAuthorize,
|
||||
) -> ProcessResult {
|
||||
check_unique_pubkeys(
|
||||
(vote_account_pubkey, "vote_account_pubkey".to_string()),
|
||||
(
|
||||
new_authorized_voter_pubkey,
|
||||
"new_authorized_voter_pubkey".to_string(),
|
||||
),
|
||||
(new_authorized_pubkey, "new_authorized_pubkey".to_string()),
|
||||
)?;
|
||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||
let ixs = vec![vote_instruction::authorize_voter(
|
||||
vote_account_pubkey, // vote account to update
|
||||
&authorized_voter_keypair.pubkey(), // current authorized voter (often the vote account itself)
|
||||
new_authorized_voter_pubkey, // new vote signer
|
||||
let ixs = vec![vote_instruction::authorize(
|
||||
vote_account_pubkey, // vote account to update
|
||||
&authorized_keypair.pubkey(), // current authorized voter (often the vote account itself)
|
||||
new_authorized_pubkey, // new vote signer
|
||||
vote_authorize, // vote or withdraw
|
||||
)];
|
||||
|
||||
let mut tx = Transaction::new_signed_with_payer(
|
||||
ixs,
|
||||
Some(&config.keypair.pubkey()),
|
||||
&[&config.keypair, &authorized_voter_keypair],
|
||||
&[&config.keypair, &authorized_keypair],
|
||||
recent_blockhash,
|
||||
);
|
||||
check_account_for_fee(rpc_client, config, &fee_calculator, &tx.message)?;
|
||||
let result = rpc_client
|
||||
.send_and_confirm_transaction(&mut tx, &[&config.keypair, &authorized_voter_keypair]);
|
||||
let result =
|
||||
rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair, &authorized_keypair]);
|
||||
log_instruction_custom_error::<VoteError>(result)
|
||||
}
|
||||
|
||||
@ -153,9 +161,10 @@ pub fn process_show_vote_account(
|
||||
|
||||
println!("account lamports: {}", vote_account.lamports);
|
||||
println!("node id: {}", vote_state.node_pubkey);
|
||||
println!("authorized voter: {}", vote_state.authorized_voter);
|
||||
println!(
|
||||
"authorized voter pubkey: {}",
|
||||
vote_state.authorized_voter_pubkey
|
||||
"authorized withdrawer: {}",
|
||||
vote_state.authorized_withdrawer
|
||||
);
|
||||
println!("credits: {}", vote_state.credits());
|
||||
println!(
|
||||
@ -221,10 +230,7 @@ pub fn process_uptime(
|
||||
})?;
|
||||
|
||||
println!("Node id: {}", vote_state.node_pubkey);
|
||||
println!(
|
||||
"Authorized voter pubkey: {}",
|
||||
vote_state.authorized_voter_pubkey
|
||||
);
|
||||
println!("Authorized voter: {}", vote_state.authorized_voter);
|
||||
if !vote_state.votes.is_empty() {
|
||||
println!("Uptime:");
|
||||
|
||||
@ -291,14 +297,14 @@ mod tests {
|
||||
|
||||
let test_authorize_voter = test_commands.clone().get_matches_from(vec![
|
||||
"test",
|
||||
"authorize-voter",
|
||||
"vote-authorize-voter",
|
||||
&pubkey_string,
|
||||
&keypair_file,
|
||||
&pubkey_string,
|
||||
]);
|
||||
assert_eq!(
|
||||
parse_command(&pubkey, &test_authorize_voter).unwrap(),
|
||||
WalletCommand::AuthorizeVoter(pubkey, keypair, pubkey)
|
||||
WalletCommand::VoteAuthorize(pubkey, keypair, pubkey, VoteAuthorize::Voter)
|
||||
);
|
||||
fs::remove_file(&keypair_file).unwrap();
|
||||
|
||||
@ -316,7 +322,16 @@ mod tests {
|
||||
]);
|
||||
assert_eq!(
|
||||
parse_command(&pubkey, &test_create_vote_account).unwrap(),
|
||||
WalletCommand::CreateVoteAccount(pubkey, node_pubkey, 10, 50)
|
||||
WalletCommand::CreateVoteAccount(
|
||||
pubkey,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter: pubkey,
|
||||
authorized_withdrawer: pubkey,
|
||||
commission: 10
|
||||
},
|
||||
50
|
||||
)
|
||||
);
|
||||
let test_create_vote_account2 = test_commands.clone().get_matches_from(vec![
|
||||
"test",
|
||||
@ -327,7 +342,63 @@ mod tests {
|
||||
]);
|
||||
assert_eq!(
|
||||
parse_command(&pubkey, &test_create_vote_account2).unwrap(),
|
||||
WalletCommand::CreateVoteAccount(pubkey, node_pubkey, 0, 50)
|
||||
WalletCommand::CreateVoteAccount(
|
||||
pubkey,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter: pubkey,
|
||||
authorized_withdrawer: pubkey,
|
||||
commission: 0
|
||||
},
|
||||
50
|
||||
)
|
||||
);
|
||||
// test init with an authed voter
|
||||
let authed = Pubkey::new_rand();
|
||||
let test_create_vote_account3 = test_commands.clone().get_matches_from(vec![
|
||||
"test",
|
||||
"create-vote-account",
|
||||
&pubkey_string,
|
||||
&node_pubkey_string,
|
||||
"50",
|
||||
"--authorized-voter",
|
||||
&authed.to_string(),
|
||||
]);
|
||||
assert_eq!(
|
||||
parse_command(&pubkey, &test_create_vote_account3).unwrap(),
|
||||
WalletCommand::CreateVoteAccount(
|
||||
pubkey,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter: authed,
|
||||
authorized_withdrawer: pubkey,
|
||||
commission: 0
|
||||
},
|
||||
50
|
||||
)
|
||||
);
|
||||
// test init with an authed withdrawer
|
||||
let test_create_vote_account4 = test_commands.clone().get_matches_from(vec![
|
||||
"test",
|
||||
"create-vote-account",
|
||||
&pubkey_string,
|
||||
&node_pubkey_string,
|
||||
"50",
|
||||
"--authorized-withdrawer",
|
||||
&authed.to_string(),
|
||||
]);
|
||||
assert_eq!(
|
||||
parse_command(&pubkey, &test_create_vote_account4).unwrap(),
|
||||
WalletCommand::CreateVoteAccount(
|
||||
pubkey,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter: pubkey,
|
||||
authorized_withdrawer: authed,
|
||||
commission: 0
|
||||
},
|
||||
50
|
||||
)
|
||||
);
|
||||
|
||||
// Test Uptime Subcommand
|
||||
|
@ -7,11 +7,9 @@ use clap::{value_t_or_exit, App, AppSettings, Arg, ArgMatches, SubCommand};
|
||||
use console::{style, Emoji};
|
||||
use log::*;
|
||||
use num_traits::FromPrimitive;
|
||||
use serde_json;
|
||||
use serde_json::{json, Value};
|
||||
use serde_json::{self, json, Value};
|
||||
use solana_budget_api::budget_instruction::{self, BudgetError};
|
||||
use solana_client::client_error::ClientError;
|
||||
use solana_client::rpc_client::RpcClient;
|
||||
use solana_client::{client_error::ClientError, rpc_client::RpcClient};
|
||||
#[cfg(not(test))]
|
||||
use solana_drone::drone::request_airdrop_transaction;
|
||||
#[cfg(test)]
|
||||
@ -33,14 +31,16 @@ use solana_sdk::{
|
||||
};
|
||||
use solana_stake_api::stake_instruction::{self, StakeError};
|
||||
use solana_storage_api::storage_instruction;
|
||||
use solana_vote_api::vote_state::VoteState;
|
||||
use std::collections::VecDeque;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write};
|
||||
use std::net::{IpAddr, SocketAddr};
|
||||
use std::thread::sleep;
|
||||
use std::time::{Duration, Instant};
|
||||
use std::{error, fmt};
|
||||
use solana_vote_api::vote_state::{VoteAuthorize, VoteInit, VoteState};
|
||||
use std::{
|
||||
collections::VecDeque,
|
||||
fs::File,
|
||||
io::{Read, Write},
|
||||
net::{IpAddr, SocketAddr},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
{error, fmt},
|
||||
};
|
||||
|
||||
const USERDATA_CHUNK_SIZE: usize = 229; // Keep program chunks under PACKET_DATA_SIZE
|
||||
|
||||
@ -64,8 +64,8 @@ pub enum WalletCommand {
|
||||
},
|
||||
Cancel(Pubkey),
|
||||
Confirm(Signature),
|
||||
AuthorizeVoter(Pubkey, Keypair, Pubkey),
|
||||
CreateVoteAccount(Pubkey, Pubkey, u8, u64),
|
||||
VoteAuthorize(Pubkey, Keypair, Pubkey, VoteAuthorize),
|
||||
CreateVoteAccount(Pubkey, VoteInit, u64),
|
||||
ShowAccount {
|
||||
pubkey: Pubkey,
|
||||
output_file: Option<String>,
|
||||
@ -236,7 +236,12 @@ pub fn parse_command(
|
||||
})
|
||||
}
|
||||
("create-vote-account", Some(matches)) => parse_vote_create_account(matches),
|
||||
("authorize-voter", Some(matches)) => parse_vote_authorize_voter(matches),
|
||||
("vote-authorize-voter", Some(matches)) => {
|
||||
parse_vote_authorize(matches, VoteAuthorize::Voter)
|
||||
}
|
||||
("vote-authorize-withdrawer", Some(matches)) => {
|
||||
parse_vote_authorize(matches, VoteAuthorize::Withdrawer)
|
||||
}
|
||||
("show-vote-account", Some(matches)) => parse_vote_get_account_command(matches),
|
||||
("uptime", Some(matches)) => parse_vote_uptime_command(matches),
|
||||
("delegate-stake", Some(matches)) => {
|
||||
@ -1269,30 +1274,28 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
|
||||
WalletCommand::Confirm(signature) => process_confirm(&rpc_client, signature),
|
||||
|
||||
// Create vote account
|
||||
WalletCommand::CreateVoteAccount(
|
||||
vote_account_pubkey,
|
||||
node_pubkey,
|
||||
commission,
|
||||
lamports,
|
||||
) => process_create_vote_account(
|
||||
&rpc_client,
|
||||
config,
|
||||
&vote_account_pubkey,
|
||||
&node_pubkey,
|
||||
*commission,
|
||||
*lamports,
|
||||
),
|
||||
WalletCommand::CreateVoteAccount(vote_account_pubkey, vote_init, lamports) => {
|
||||
process_create_vote_account(
|
||||
&rpc_client,
|
||||
config,
|
||||
&vote_account_pubkey,
|
||||
&vote_init,
|
||||
*lamports,
|
||||
)
|
||||
}
|
||||
|
||||
WalletCommand::AuthorizeVoter(
|
||||
WalletCommand::VoteAuthorize(
|
||||
vote_account_pubkey,
|
||||
authorized_voter_keypair,
|
||||
new_authorized_voter_pubkey,
|
||||
) => process_authorize_voter(
|
||||
authorized_keypair,
|
||||
new_authorized_pubkey,
|
||||
vote_authorize,
|
||||
) => process_vote_authorize(
|
||||
&rpc_client,
|
||||
config,
|
||||
&vote_account_pubkey,
|
||||
&authorized_voter_keypair,
|
||||
&new_authorized_voter_pubkey,
|
||||
&authorized_keypair,
|
||||
&new_authorized_pubkey,
|
||||
*vote_authorize,
|
||||
),
|
||||
|
||||
WalletCommand::ShowAccount {
|
||||
@ -1646,7 +1649,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("authorize-voter")
|
||||
SubCommand::with_name("vote-authorize-voter")
|
||||
.about("Authorize a new vote signing keypair for the given vote account")
|
||||
.arg(
|
||||
Arg::with_name("vote_account_pubkey")
|
||||
@ -1658,7 +1661,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||
.help("Vote account in which to set the authorized voter"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("authorized_voter_keypair_file")
|
||||
Arg::with_name("authorized_keypair_file")
|
||||
.index(2)
|
||||
.value_name("CURRENT VOTER KEYPAIR FILE")
|
||||
.takes_value(true)
|
||||
@ -1667,7 +1670,7 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||
.help("Keypair file for the currently authorized vote signer"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("new_authorized_voter_pubkey")
|
||||
Arg::with_name("new_authorized_pubkey")
|
||||
.index(3)
|
||||
.value_name("NEW VOTER PUBKEY")
|
||||
.takes_value(true)
|
||||
@ -1676,6 +1679,37 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||
.help("New vote signer to authorize"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("vote-authorize-withdrawer")
|
||||
.about("Authorize a new withdraw signing keypair for the given vote account")
|
||||
.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 in which to set the authorized withdrawer"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("authorized_keypair_file")
|
||||
.index(2)
|
||||
.value_name("CURRENT WITHDRAWER KEYPAIR FILE")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.validator(is_keypair)
|
||||
.help("Keypair file for the currently authorized withdrawer"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("new_authorized_pubkey")
|
||||
.index(3)
|
||||
.value_name("NEW WITHDRAWER PUBKEY")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.validator(is_pubkey_or_keypair)
|
||||
.help("New withdrawer to authorize"),
|
||||
),
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("create-vote-account")
|
||||
.about("Create a vote account")
|
||||
@ -1711,7 +1745,25 @@ pub fn app<'ab, 'v>(name: &str, about: &'ab str, version: &'v str) -> App<'ab, '
|
||||
.value_name("NUM")
|
||||
.takes_value(true)
|
||||
.help("The commission taken on reward redemption (0-255), default: 0"),
|
||||
),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("authorized_voter")
|
||||
.long("authorized-voter")
|
||||
.value_name("PUBKEY")
|
||||
.takes_value(true)
|
||||
.validator(is_pubkey_or_keypair)
|
||||
.help("Public key of the authorized voter (defaults to vote account pubkey)"),
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("authorized_withdrawer")
|
||||
.long("authorized-withdrawer")
|
||||
.value_name("PUBKEY")
|
||||
.takes_value(true)
|
||||
.validator(is_pubkey_or_keypair)
|
||||
.help("Public key of the authorized withdrawer (defaults to vote account pubkey)"),
|
||||
)
|
||||
|
||||
,
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("show-account")
|
||||
@ -2621,14 +2673,27 @@ mod tests {
|
||||
|
||||
let bob_pubkey = Pubkey::new_rand();
|
||||
let node_pubkey = Pubkey::new_rand();
|
||||
config.command = WalletCommand::CreateVoteAccount(bob_pubkey, node_pubkey, 0, 10);
|
||||
config.command = WalletCommand::CreateVoteAccount(
|
||||
bob_pubkey,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter: bob_pubkey,
|
||||
authorized_withdrawer: bob_pubkey,
|
||||
commission: 0,
|
||||
},
|
||||
10,
|
||||
);
|
||||
let signature = process_command(&config);
|
||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||
|
||||
let bob_keypair = Keypair::new();
|
||||
let new_authorized_voter_pubkey = Pubkey::new_rand();
|
||||
config.command =
|
||||
WalletCommand::AuthorizeVoter(bob_pubkey, bob_keypair, new_authorized_voter_pubkey);
|
||||
let new_authorized_pubkey = Pubkey::new_rand();
|
||||
config.command = WalletCommand::VoteAuthorize(
|
||||
bob_pubkey,
|
||||
bob_keypair,
|
||||
new_authorized_pubkey,
|
||||
VoteAuthorize::Voter,
|
||||
);
|
||||
let signature = process_command(&config);
|
||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||
|
||||
@ -2778,10 +2843,24 @@ mod tests {
|
||||
};
|
||||
assert!(process_command(&config).is_err());
|
||||
|
||||
config.command = WalletCommand::CreateVoteAccount(bob_pubkey, node_pubkey, 0, 10);
|
||||
config.command = WalletCommand::CreateVoteAccount(
|
||||
bob_pubkey,
|
||||
VoteInit {
|
||||
node_pubkey,
|
||||
authorized_voter: bob_pubkey,
|
||||
authorized_withdrawer: bob_pubkey,
|
||||
commission: 0,
|
||||
},
|
||||
10,
|
||||
);
|
||||
assert!(process_command(&config).is_err());
|
||||
|
||||
config.command = WalletCommand::AuthorizeVoter(bob_pubkey, Keypair::new(), bob_pubkey);
|
||||
config.command = WalletCommand::VoteAuthorize(
|
||||
bob_pubkey,
|
||||
Keypair::new(),
|
||||
bob_pubkey,
|
||||
VoteAuthorize::Voter,
|
||||
);
|
||||
assert!(process_command(&config).is_err());
|
||||
|
||||
config.command = WalletCommand::GetSlot;
|
||||
|
Reference in New Issue
Block a user