Add CliCommand::StakeSetLockup (#8248)

automerge
This commit is contained in:
Tyera Eulberg
2020-02-12 16:36:29 -07:00
committed by GitHub
parent 58727463e1
commit 6309c97697
3 changed files with 417 additions and 8 deletions

View File

@@ -334,6 +334,17 @@ pub enum CliCommand {
nonce_authority: Option<SigningAuthority>,
fee_payer: Option<SigningAuthority>,
},
StakeSetLockup {
stake_account_pubkey: Pubkey,
lockup: Lockup,
custodian: Option<SigningAuthority>,
sign_only: bool,
signers: Option<Vec<(Pubkey, Signature)>>,
blockhash_query: BlockhashQuery,
nonce_account: Option<Pubkey>,
nonce_authority: Option<SigningAuthority>,
fee_payer: Option<SigningAuthority>,
},
WithdrawStake {
stake_account_pubkey: Pubkey,
destination_account_pubkey: Pubkey,
@@ -565,6 +576,7 @@ pub fn parse_command(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, Box<dyn
("stake-authorize-withdrawer", Some(matches)) => {
parse_stake_authorize(matches, StakeAuthorize::Withdrawer)
}
("stake-set-lockup", Some(matches)) => parse_stake_set_lockup(matches),
("stake-account", Some(matches)) => parse_show_stake_account(matches),
("stake-history", Some(matches)) => parse_show_stake_history(matches),
// Storage Commands
@@ -1665,7 +1677,29 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
nonce_authority.as_ref(),
fee_payer.as_ref(),
),
CliCommand::StakeSetLockup {
stake_account_pubkey,
mut lockup,
ref custodian,
sign_only,
ref signers,
blockhash_query,
nonce_account,
ref nonce_authority,
ref fee_payer,
} => process_stake_set_lockup(
&rpc_client,
config,
&stake_account_pubkey,
&mut lockup,
custodian.as_ref(),
*sign_only,
signers,
blockhash_query,
*nonce_account,
nonce_authority.as_ref(),
fee_payer.as_ref(),
),
CliCommand::WithdrawStake {
stake_account_pubkey,
destination_account_pubkey,

View File

@@ -47,7 +47,7 @@ fn stake_authority_arg<'a, 'b>() -> Arg<'a, 'b> {
Arg::with_name(STAKE_AUTHORITY_ARG.name)
.long(STAKE_AUTHORITY_ARG.long)
.takes_value(true)
.value_name("KEYPAIR of PUBKEY")
.value_name("KEYPAIR or PUBKEY")
.validator(is_pubkey_or_keypair_or_ask_keyword)
.help(STAKE_AUTHORITY_ARG.help)
}
@@ -99,7 +99,7 @@ impl StakeSubCommands for App<'_, '_> {
.arg(
Arg::with_name("custodian")
.long("custodian")
.value_name("PUBKEY")
.value_name("KEYPAIR or PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.help("Identity of the custodian (can withdraw before lockup expires)")
@@ -337,7 +337,55 @@ impl StakeSubCommands for App<'_, '_> {
.help("Specify unit to use for request")
)
.arg(withdraw_authority_arg())
)
)
.subcommand(
SubCommand::with_name("stake-set-lockup")
.about("Set Lockup for the stake account")
.arg(
Arg::with_name("stake_account_pubkey")
.index(1)
.value_name("STAKE ACCOUNT")
.takes_value(true)
.required(true)
.validator(is_pubkey_or_keypair)
.help("Stake account for which to set Lockup")
)
.arg(
Arg::with_name("lockup_epoch")
.long("lockup-epoch")
.value_name("EPOCH")
.takes_value(true)
.help("The epoch height at which this account will be available for withdrawal")
)
.arg(
Arg::with_name("lockup_date")
.long("lockup-date")
.value_name("RFC3339 DATE TIME")
.validator(is_rfc3339_datetime)
.takes_value(true)
.help("The date and time at which this account will be available for withdrawal")
)
.arg(
Arg::with_name("new_custodian")
.long("new-custodian")
.value_name("KEYPAIR or PUBKEY")
.takes_value(true)
.validator(is_pubkey_or_keypair)
.help("Identity of the new lockup custodian (can withdraw before lockup expires)")
)
.arg(
Arg::with_name("custodian")
.long("custodian")
.takes_value(true)
.value_name("KEYPAIR or PUBKEY")
.validator(is_pubkey_or_keypair_or_ask_keyword)
.help("Public key of signing custodian (defaults to cli config pubkey)")
)
.offline_args()
.arg(nonce_arg())
.arg(nonce_authority_arg())
.arg(fee_payer_arg())
)
.subcommand(
SubCommand::with_name("stake-account")
.about("Show the contents of a stake account")
@@ -553,6 +601,44 @@ pub fn parse_stake_withdraw_stake(matches: &ArgMatches<'_>) -> Result<CliCommand
})
}
pub fn parse_stake_set_lockup(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let epoch = value_of(&matches, "lockup_epoch").unwrap_or(0);
let unix_timestamp = unix_timestamp_from_rfc3339_datetime(&matches, "lockup_date").unwrap_or(0);
let new_custodian = pubkey_of(matches, "new_custodian").unwrap_or_default();
let sign_only = matches.is_present(SIGN_ONLY_ARG.name);
let signers = pubkeys_sigs_of(&matches, SIGNER_ARG.name);
let blockhash_query = BlockhashQuery::new_from_matches(matches);
let require_keypair = signers.is_none();
let nonce_account = pubkey_of(&matches, NONCE_ARG.name);
let custodian = SigningAuthority::new_from_matches(&matches, "custodian", signers.as_deref())?;
let nonce_authority =
SigningAuthority::new_from_matches(&matches, NONCE_AUTHORITY_ARG.name, signers.as_deref())?;
let fee_payer =
SigningAuthority::new_from_matches(&matches, FEE_PAYER_ARG.name, signers.as_deref())?;
Ok(CliCommandInfo {
command: CliCommand::StakeSetLockup {
stake_account_pubkey,
lockup: Lockup {
custodian: new_custodian,
epoch,
unix_timestamp,
},
custodian,
sign_only,
signers,
blockhash_query,
nonce_account,
nonce_authority,
fee_payer,
},
require_keypair,
})
}
pub fn parse_show_stake_account(matches: &ArgMatches<'_>) -> Result<CliCommandInfo, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let use_lamports_unit = matches.is_present("lamports");
@@ -984,6 +1070,74 @@ pub fn process_split_stake(
}
}
#[allow(clippy::too_many_arguments)]
pub fn process_stake_set_lockup(
rpc_client: &RpcClient,
config: &CliConfig,
stake_account_pubkey: &Pubkey,
lockup: &mut Lockup,
custodian: Option<&SigningAuthority>,
sign_only: bool,
signers: &Option<Vec<(Pubkey, Signature)>>,
blockhash_query: &BlockhashQuery,
nonce_account: Option<Pubkey>,
nonce_authority: Option<&SigningAuthority>,
fee_payer: Option<&SigningAuthority>,
) -> ProcessResult {
let (recent_blockhash, fee_calculator) =
blockhash_query.get_blockhash_fee_calculator(rpc_client)?;
let custodian = custodian.map(|a| a.keypair()).unwrap_or(&config.keypair);
// If new custodian is not explicitly set, default to current custodian
if lockup.custodian == Pubkey::default() {
lockup.custodian = custodian.pubkey();
}
let ixs = vec![stake_instruction::set_lockup(
stake_account_pubkey,
lockup,
&custodian.pubkey(),
)];
let (nonce_authority, nonce_authority_pubkey) = nonce_authority
.map(|a| (a.keypair(), a.pubkey()))
.unwrap_or((&config.keypair, config.keypair.pubkey()));
let fee_payer = fee_payer.map(|f| f.keypair()).unwrap_or(&config.keypair);
let mut tx = if let Some(nonce_account) = &nonce_account {
Transaction::new_signed_with_nonce(
ixs,
Some(&fee_payer.pubkey()),
&[fee_payer, nonce_authority, custodian],
nonce_account,
&nonce_authority.pubkey(),
recent_blockhash,
)
} else {
Transaction::new_signed_with_payer(
ixs,
Some(&fee_payer.pubkey()),
&[fee_payer, custodian],
recent_blockhash,
)
};
if let Some(signers) = signers {
replace_signatures(&mut tx, &signers)?;
}
if sign_only {
return_signers(&tx)
} else {
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority_pubkey, &recent_blockhash)?;
}
check_account_for_fee(
rpc_client,
&tx.message.account_keys[0],
&fee_calculator,
&tx.message,
)?;
let result = rpc_client.send_and_confirm_transaction(&mut tx, &[&config.keypair]);
log_instruction_custom_error::<StakeError>(result)
}
}
pub fn print_stake_state(stake_lamports: u64, stake_state: &StakeState, use_lamports_unit: bool) {
fn show_authorized(authorized: &Authorized) {
println!("Authorized Staker: {}", authorized.staker);