Add custodian option to withdraw-stake command (#9662)

automerge
This commit is contained in:
Greg Fitzgerald
2020-04-22 16:00:18 -06:00
committed by GitHub
parent 17e7667da4
commit 71f7a7243b
3 changed files with 61 additions and 1 deletions

View File

@ -339,6 +339,7 @@ pub enum CliCommand {
destination_account_pubkey: Pubkey, destination_account_pubkey: Pubkey,
lamports: u64, lamports: u64,
withdraw_authority: SignerIndex, withdraw_authority: SignerIndex,
custodian: Option<SignerIndex>,
sign_only: bool, sign_only: bool,
blockhash_query: BlockhashQuery, blockhash_query: BlockhashQuery,
nonce_account: Option<Pubkey>, nonce_account: Option<Pubkey>,
@ -1968,6 +1969,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
destination_account_pubkey, destination_account_pubkey,
lamports, lamports,
withdraw_authority, withdraw_authority,
custodian,
sign_only, sign_only,
blockhash_query, blockhash_query,
ref nonce_account, ref nonce_account,
@ -1980,6 +1982,7 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
&destination_account_pubkey, &destination_account_pubkey,
*lamports, *lamports,
*withdraw_authority, *withdraw_authority,
*custodian,
*sign_only, *sign_only,
blockhash_query, blockhash_query,
nonce_account.as_ref(), nonce_account.as_ref(),
@ -3360,6 +3363,7 @@ mod tests {
destination_account_pubkey: to_pubkey, destination_account_pubkey: to_pubkey,
lamports: 100, lamports: 100,
withdraw_authority: 0, withdraw_authority: 0,
custodian: None,
sign_only: false, sign_only: false,
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster), blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
nonce_account: None, nonce_account: None,

View File

@ -293,6 +293,14 @@ impl StakeSubCommands for App<'_, '_> {
.arg(nonce_arg()) .arg(nonce_arg())
.arg(nonce_authority_arg()) .arg(nonce_authority_arg())
.arg(fee_payer_arg()) .arg(fee_payer_arg())
.arg(
Arg::with_name("custodian")
.long("custodian")
.takes_value(true)
.value_name("KEYPAIR")
.validator(is_valid_signer)
.help("Authority to override account lockup")
)
) )
.subcommand( .subcommand(
SubCommand::with_name("stake-set-lockup") SubCommand::with_name("stake-set-lockup")
@ -650,11 +658,15 @@ pub fn parse_stake_withdraw_stake(
let (nonce_authority, nonce_authority_pubkey) = let (nonce_authority, nonce_authority_pubkey) =
signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?; signer_of(matches, NONCE_AUTHORITY_ARG.name, wallet_manager)?;
let (fee_payer, fee_payer_pubkey) = signer_of(matches, FEE_PAYER_ARG.name, wallet_manager)?; let (fee_payer, fee_payer_pubkey) = signer_of(matches, FEE_PAYER_ARG.name, wallet_manager)?;
let (custodian, custodian_pubkey) = signer_of(matches, "custodian", wallet_manager)?;
let mut bulk_signers = vec![withdraw_authority, fee_payer]; let mut bulk_signers = vec![withdraw_authority, fee_payer];
if nonce_account.is_some() { if nonce_account.is_some() {
bulk_signers.push(nonce_authority); bulk_signers.push(nonce_authority);
} }
if custodian.is_some() {
bulk_signers.push(custodian);
}
let signer_info = let signer_info =
generate_unique_signers(bulk_signers, matches, default_signer_path, wallet_manager)?; generate_unique_signers(bulk_signers, matches, default_signer_path, wallet_manager)?;
@ -669,6 +681,7 @@ pub fn parse_stake_withdraw_stake(
nonce_account, nonce_account,
nonce_authority: signer_info.index_of(nonce_authority_pubkey).unwrap(), nonce_authority: signer_info.index_of(nonce_authority_pubkey).unwrap(),
fee_payer: signer_info.index_of(fee_payer_pubkey).unwrap(), fee_payer: signer_info.index_of(fee_payer_pubkey).unwrap(),
custodian: custodian_pubkey.and_then(|_| signer_info.index_of(custodian_pubkey)),
}, },
signers: signer_info.signers, signers: signer_info.signers,
}) })
@ -987,6 +1000,7 @@ pub fn process_withdraw_stake(
destination_account_pubkey: &Pubkey, destination_account_pubkey: &Pubkey,
lamports: u64, lamports: u64,
withdraw_authority: SignerIndex, withdraw_authority: SignerIndex,
custodian: Option<SignerIndex>,
sign_only: bool, sign_only: bool,
blockhash_query: &BlockhashQuery, blockhash_query: &BlockhashQuery,
nonce_account: Option<&Pubkey>, nonce_account: Option<&Pubkey>,
@ -996,13 +1010,14 @@ pub fn process_withdraw_stake(
let (recent_blockhash, fee_calculator) = let (recent_blockhash, fee_calculator) =
blockhash_query.get_blockhash_and_fee_calculator(rpc_client)?; blockhash_query.get_blockhash_and_fee_calculator(rpc_client)?;
let withdraw_authority = config.signers[withdraw_authority]; let withdraw_authority = config.signers[withdraw_authority];
let custodian = custodian.map(|index| config.signers[index]);
let ixs = vec![stake_instruction::withdraw( let ixs = vec![stake_instruction::withdraw(
stake_account_pubkey, stake_account_pubkey,
&withdraw_authority.pubkey(), &withdraw_authority.pubkey(),
destination_account_pubkey, destination_account_pubkey,
lamports, lamports,
None, custodian.map(|signer| signer.pubkey()).as_ref(),
)]; )];
let fee_payer = config.signers[fee_payer]; let fee_payer = config.signers[fee_payer];
@ -1471,6 +1486,9 @@ mod tests {
let (stake_authority_keypair_file, mut tmp_file) = make_tmp_file(); let (stake_authority_keypair_file, mut tmp_file) = make_tmp_file();
let stake_authority_keypair = Keypair::new(); let stake_authority_keypair = Keypair::new();
write_keypair(&stake_authority_keypair, tmp_file.as_file_mut()).unwrap(); write_keypair(&stake_authority_keypair, tmp_file.as_file_mut()).unwrap();
let (custodian_keypair_file, mut tmp_file) = make_tmp_file();
let custodian_keypair = Keypair::new();
write_keypair(&custodian_keypair, tmp_file.as_file_mut()).unwrap();
// stake-authorize subcommand // stake-authorize subcommand
let stake_account_string = stake_account_pubkey.to_string(); let stake_account_string = stake_account_pubkey.to_string();
@ -2409,6 +2427,7 @@ mod tests {
destination_account_pubkey: stake_account_pubkey, destination_account_pubkey: stake_account_pubkey,
lamports: 42_000_000_000, lamports: 42_000_000_000,
withdraw_authority: 0, withdraw_authority: 0,
custodian: None,
sign_only: false, sign_only: false,
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster), blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
nonce_account: None, nonce_account: None,
@ -2438,6 +2457,7 @@ mod tests {
destination_account_pubkey: stake_account_pubkey, destination_account_pubkey: stake_account_pubkey,
lamports: 42_000_000_000, lamports: 42_000_000_000,
withdraw_authority: 1, withdraw_authority: 1,
custodian: None,
sign_only: false, sign_only: false,
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster), blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
nonce_account: None, nonce_account: None,
@ -2453,6 +2473,39 @@ mod tests {
} }
); );
// Test WithdrawStake Subcommand w/ custodian
let test_withdraw_stake = test_commands.clone().get_matches_from(vec![
"test",
"withdraw-stake",
&stake_account_string,
&stake_account_string,
"42",
"--custodian",
&custodian_keypair_file,
]);
assert_eq!(
parse_command(&test_withdraw_stake, &default_keypair_file, &mut None).unwrap(),
CliCommandInfo {
command: CliCommand::WithdrawStake {
stake_account_pubkey,
destination_account_pubkey: stake_account_pubkey,
lamports: 42_000_000_000,
withdraw_authority: 0,
custodian: Some(1),
sign_only: false,
blockhash_query: BlockhashQuery::All(blockhash_query::Source::Cluster),
nonce_account: None,
nonce_authority: 0,
fee_payer: 0,
},
signers: vec![
read_keypair_file(&default_keypair_file).unwrap().into(),
read_keypair_file(&custodian_keypair_file).unwrap().into()
],
}
);
// Test WithdrawStake Subcommand w/ authority and offline nonce // Test WithdrawStake Subcommand w/ authority and offline nonce
let test_withdraw_stake = test_commands.clone().get_matches_from(vec![ let test_withdraw_stake = test_commands.clone().get_matches_from(vec![
"test", "test",
@ -2482,6 +2535,7 @@ mod tests {
destination_account_pubkey: stake_account_pubkey, destination_account_pubkey: stake_account_pubkey,
lamports: 42_000_000_000, lamports: 42_000_000_000,
withdraw_authority: 0, withdraw_authority: 0,
custodian: None,
sign_only: false, sign_only: false,
blockhash_query: BlockhashQuery::FeeCalculator( blockhash_query: BlockhashQuery::FeeCalculator(
blockhash_query::Source::NonceAccount(nonce_account), blockhash_query::Source::NonceAccount(nonce_account),

View File

@ -1439,6 +1439,7 @@ fn test_offline_nonced_create_stake_account_and_withdraw() {
destination_account_pubkey: recipient_pubkey, destination_account_pubkey: recipient_pubkey,
lamports: 42, lamports: 42,
withdraw_authority: 0, withdraw_authority: 0,
custodian: None,
sign_only: true, sign_only: true,
blockhash_query: BlockhashQuery::None(nonce_hash), blockhash_query: BlockhashQuery::None(nonce_hash),
nonce_account: Some(nonce_pubkey), nonce_account: Some(nonce_pubkey),
@ -1454,6 +1455,7 @@ fn test_offline_nonced_create_stake_account_and_withdraw() {
destination_account_pubkey: recipient_pubkey, destination_account_pubkey: recipient_pubkey,
lamports: 42, lamports: 42,
withdraw_authority: 0, withdraw_authority: 0,
custodian: None,
sign_only: false, sign_only: false,
blockhash_query: BlockhashQuery::FeeCalculator( blockhash_query: BlockhashQuery::FeeCalculator(
blockhash_query::Source::NonceAccount(nonce_pubkey), blockhash_query::Source::NonceAccount(nonce_pubkey),