Remove vote pubkey from deactivate_stake (#6257)
* Remove vote pubkey from deactivate_stake * Fix test * Update docs
This commit is contained in:
@ -483,7 +483,7 @@ solana-deactivate-stake
|
||||
Deactivate the delegated stake from the stake account
|
||||
|
||||
USAGE:
|
||||
solana deactivate-stake [OPTIONS] <STAKE ACCOUNT> <VOTE ACCOUNT>
|
||||
solana deactivate-stake [OPTIONS] <STAKE ACCOUNT>
|
||||
|
||||
FLAGS:
|
||||
-h, --help Prints help information
|
||||
@ -496,7 +496,6 @@ OPTIONS:
|
||||
|
||||
ARGS:
|
||||
<STAKE ACCOUNT> Stake account to be deactivated.
|
||||
<VOTE ACCOUNT> The vote account to which the stake is currently delegated
|
||||
```
|
||||
|
||||
#### solana-delegate-stake
|
||||
|
@ -135,8 +135,7 @@ A staker may wish to withdraw from the network. To do so he must first deactivat
|
||||
The transaction must be signed by the stake's `authorized_staker`.
|
||||
|
||||
* `account[0]` - RW - The StakeState::Stake instance that is deactivating.
|
||||
* `account[1]` - R - The VoteState instance to which this stake is delegated, required in case of slashing
|
||||
* `account[2]` - R - sysvar::clock account from the Bank that carries current epoch
|
||||
* `account[1]` - R - sysvar::clock account from the Bank that carries current epoch
|
||||
|
||||
StakeState::Stake::deactivated is set to the current epoch + cool down. The account's stake will ramp down to zero by that epoch, and Account::lamports will be available for withdrawal.
|
||||
|
||||
@ -230,4 +229,3 @@ Only lamports in excess of effective+activating stake may be withdrawn at any ti
|
||||
### Lock-up
|
||||
|
||||
Stake accounts support the notion of lock-up, wherein the stake account balance is unavailable for withdrawal until a specified time. Lock-up is specified as a slot height, i.e. the minimum slot height that must be reached by the network before the stake account balance is available for withdrawal, except to a specified custodian. This information is gathered when the stake account is created.
|
||||
|
||||
|
@ -36,7 +36,7 @@ The rewards lamports earned are split between your stake account and the vote ac
|
||||
Stake can be deactivated by running:
|
||||
|
||||
```bash
|
||||
$ solana deactivate-stake ~/validator-config/stake-keypair.json ~/validator-vote-keypair.json
|
||||
$ solana deactivate-stake ~/validator-config/stake-keypair.json
|
||||
```
|
||||
|
||||
The stake will cool down, deactivate over time. While cooling down, your stake will continue to earn rewards. Only after stake cooldown is it safe to turn off your validator or withdraw it from the network. Cooldown may take several epochs to complete, depending on active stake and the size of your stake.
|
||||
|
@ -61,7 +61,7 @@ pub enum CliCommand {
|
||||
Deploy(String),
|
||||
// Stake Commands
|
||||
CreateStakeAccount(Pubkey, Authorized, Lockup, u64),
|
||||
DeactivateStake(Pubkey, Pubkey),
|
||||
DeactivateStake(Pubkey),
|
||||
DelegateStake(Pubkey, Pubkey, bool),
|
||||
RedeemVoteCredits(Pubkey, Pubkey),
|
||||
ShowStakeAccount {
|
||||
@ -774,13 +774,8 @@ pub fn process_command(config: &CliConfig) -> ProcessResult {
|
||||
)
|
||||
}
|
||||
// Deactivate stake account
|
||||
CliCommand::DeactivateStake(stake_account_pubkey, vote_account_pubkey) => {
|
||||
process_deactivate_stake_account(
|
||||
&rpc_client,
|
||||
config,
|
||||
&stake_account_pubkey,
|
||||
&vote_account_pubkey,
|
||||
)
|
||||
CliCommand::DeactivateStake(stake_account_pubkey) => {
|
||||
process_deactivate_stake_account(&rpc_client, config, &stake_account_pubkey)
|
||||
}
|
||||
CliCommand::DelegateStake(stake_account_pubkey, vote_account_pubkey, force) => {
|
||||
process_delegate_stake(
|
||||
@ -1733,8 +1728,7 @@ mod tests {
|
||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||
|
||||
let stake_pubkey = Pubkey::new_rand();
|
||||
let vote_pubkey = Pubkey::new_rand();
|
||||
config.command = CliCommand::DeactivateStake(stake_pubkey, vote_pubkey);
|
||||
config.command = CliCommand::DeactivateStake(stake_pubkey);
|
||||
let signature = process_command(&config);
|
||||
assert_eq!(signature.unwrap(), SIGNATURE.to_string());
|
||||
|
||||
|
@ -168,15 +168,6 @@ impl StakeSubCommands for App<'_, '_> {
|
||||
.required(true)
|
||||
.help("Stake account to be deactivated.")
|
||||
)
|
||||
.arg(
|
||||
Arg::with_name("vote_account_pubkey")
|
||||
.index(2)
|
||||
.value_name("VOTE ACCOUNT")
|
||||
.takes_value(true)
|
||||
.required(true)
|
||||
.validator(is_pubkey_or_keypair)
|
||||
.help("The vote account to which the stake is currently delegated")
|
||||
)
|
||||
)
|
||||
.subcommand(
|
||||
SubCommand::with_name("withdraw-stake")
|
||||
@ -316,11 +307,7 @@ pub fn parse_redeem_vote_credits(matches: &ArgMatches<'_>) -> Result<CliCommand,
|
||||
|
||||
pub fn parse_stake_deactivate_stake(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
|
||||
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
|
||||
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
|
||||
Ok(CliCommand::DeactivateStake(
|
||||
stake_account_pubkey,
|
||||
vote_account_pubkey,
|
||||
))
|
||||
Ok(CliCommand::DeactivateStake(stake_account_pubkey))
|
||||
}
|
||||
|
||||
pub fn parse_stake_withdraw_stake(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
|
||||
@ -419,13 +406,11 @@ pub fn process_deactivate_stake_account(
|
||||
rpc_client: &RpcClient,
|
||||
config: &CliConfig,
|
||||
stake_account_pubkey: &Pubkey,
|
||||
vote_account_pubkey: &Pubkey,
|
||||
) -> ProcessResult {
|
||||
let (recent_blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
|
||||
let ixs = vec![stake_instruction::deactivate_stake(
|
||||
stake_account_pubkey,
|
||||
&config.keypair.pubkey(),
|
||||
vote_account_pubkey,
|
||||
)];
|
||||
let mut tx = Transaction::new_signed_instructions(&[&config.keypair], ixs, recent_blockhash);
|
||||
check_account_for_fee(rpc_client, config, &fee_calculator, &tx.message)?;
|
||||
@ -744,11 +729,10 @@ mod tests {
|
||||
"test",
|
||||
"deactivate-stake",
|
||||
&stake_pubkey_string,
|
||||
&pubkey_string,
|
||||
]);
|
||||
assert_eq!(
|
||||
parse_command(&pubkey, &test_deactivate_stake).unwrap(),
|
||||
CliCommand::DeactivateStake(stake_pubkey, pubkey)
|
||||
CliCommand::DeactivateStake(stake_pubkey)
|
||||
);
|
||||
}
|
||||
// TODO: Add process tests
|
||||
|
@ -100,10 +100,9 @@ pub enum StakeInstruction {
|
||||
/// Deactivates the stake in the account
|
||||
/// requires Authorized::staker signature
|
||||
///
|
||||
/// Expects 3 Accounts:
|
||||
/// Expects 2 Accounts:
|
||||
/// 0 - Delegate StakeAccount
|
||||
/// 1 - VoteAccount to which the Stake is delegated
|
||||
/// 2 - Syscall Account that carries epoch
|
||||
/// 1 - Syscall Account that carries epoch
|
||||
///
|
||||
Deactivate,
|
||||
}
|
||||
@ -250,18 +249,11 @@ pub fn withdraw(
|
||||
Instruction::new(id(), &StakeInstruction::Withdraw(lamports), account_metas)
|
||||
}
|
||||
|
||||
pub fn deactivate_stake(
|
||||
stake_pubkey: &Pubkey,
|
||||
authorized_pubkey: &Pubkey,
|
||||
vote_pubkey: &Pubkey,
|
||||
) -> Instruction {
|
||||
pub fn deactivate_stake(stake_pubkey: &Pubkey, authorized_pubkey: &Pubkey) -> Instruction {
|
||||
let account_metas = metas_for_authorized_signer(
|
||||
stake_pubkey,
|
||||
authorized_pubkey,
|
||||
&[
|
||||
AccountMeta::new_credit_only(*vote_pubkey, false),
|
||||
AccountMeta::new_credit_only(sysvar::clock::id(), false),
|
||||
],
|
||||
&[AccountMeta::new_credit_only(sysvar::clock::id(), false)],
|
||||
);
|
||||
Instruction::new(id(), &StakeInstruction::Deactivate, account_metas)
|
||||
}
|
||||
@ -340,17 +332,11 @@ pub fn process_instruction(
|
||||
)
|
||||
}
|
||||
StakeInstruction::Deactivate => {
|
||||
if rest.len() < 2 {
|
||||
if rest.is_empty() {
|
||||
return Err(InstructionError::InvalidInstructionData);
|
||||
}
|
||||
let (vote, rest) = rest.split_at_mut(1);
|
||||
let vote = &mut vote[0];
|
||||
|
||||
me.deactivate_stake(
|
||||
vote,
|
||||
&sysvar::clock::from_keyed_account(&rest[0])?,
|
||||
&rest[1..],
|
||||
)
|
||||
me.deactivate_stake(&sysvar::clock::from_keyed_account(&rest[0])?, &rest[1..])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -419,11 +405,7 @@ mod tests {
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
assert_eq!(
|
||||
process_instruction(&deactivate_stake(
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default()
|
||||
)),
|
||||
process_instruction(&deactivate_stake(&Pubkey::default(), &Pubkey::default())),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
}
|
||||
@ -600,7 +582,6 @@ mod tests {
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
KeyedAccount::new(
|
||||
&sysvar::rewards::id(),
|
||||
@ -617,14 +598,11 @@ mod tests {
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
KeyedAccount::new(
|
||||
&mut [KeyedAccount::new(
|
||||
&sysvar::clock::id(),
|
||||
false,
|
||||
&mut sysvar::rewards::create_account(1, 0.0, 0.0)
|
||||
),
|
||||
],
|
||||
),],
|
||||
&serialize(&StakeInstruction::Deactivate).unwrap(),
|
||||
),
|
||||
Err(InstructionError::InvalidInstructionData),
|
||||
|
@ -430,7 +430,6 @@ pub trait StakeAccount {
|
||||
) -> Result<(), InstructionError>;
|
||||
fn deactivate_stake(
|
||||
&mut self,
|
||||
vote_account: &KeyedAccount,
|
||||
clock: &sysvar::clock::Clock,
|
||||
other_signers: &[KeyedAccount],
|
||||
) -> Result<(), InstructionError>;
|
||||
@ -516,7 +515,6 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
||||
}
|
||||
fn deactivate_stake(
|
||||
&mut self,
|
||||
_vote_account: &KeyedAccount, // TODO: used in slashing
|
||||
clock: &sysvar::clock::Clock,
|
||||
other_signers: &[KeyedAccount],
|
||||
) -> Result<(), InstructionError> {
|
||||
@ -1156,15 +1154,10 @@ mod tests {
|
||||
..sysvar::clock::Clock::default()
|
||||
};
|
||||
|
||||
let vote_pubkey = Pubkey::new_rand();
|
||||
let mut vote_account =
|
||||
vote_state::create_account(&vote_pubkey, &Pubkey::new_rand(), 0, 100);
|
||||
let vote_keyed_account = KeyedAccount::new(&vote_pubkey, false, &mut vote_account);
|
||||
|
||||
// signed keyed account but not staked yet
|
||||
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, true, &mut stake_account);
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock, &[]),
|
||||
stake_keyed_account.deactivate_stake(&clock, &[]),
|
||||
Err(InstructionError::InvalidAccountData)
|
||||
);
|
||||
|
||||
@ -1187,16 +1180,13 @@ mod tests {
|
||||
// unsigned keyed account
|
||||
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, false, &mut stake_account);
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock, &[]),
|
||||
stake_keyed_account.deactivate_stake(&clock, &[]),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
|
||||
// Deactivate after staking
|
||||
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, true, &mut stake_account);
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock, &[]),
|
||||
Ok(())
|
||||
);
|
||||
assert_eq!(stake_keyed_account.deactivate_stake(&clock, &[]), Ok(()));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -1317,10 +1307,7 @@ mod tests {
|
||||
);
|
||||
|
||||
// deactivate the stake before withdrawal
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock, &[]),
|
||||
Ok(())
|
||||
);
|
||||
assert_eq!(stake_keyed_account.deactivate_stake(&clock, &[]), Ok(()));
|
||||
// simulate time passing
|
||||
clock.epoch += 100;
|
||||
|
||||
@ -1896,11 +1883,7 @@ mod tests {
|
||||
let new_staker_keyed_account =
|
||||
KeyedAccount::new(&new_staker_pubkey, true, &mut new_staker_account);
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(
|
||||
&vote_keyed_account,
|
||||
&clock,
|
||||
&[new_staker_keyed_account]
|
||||
),
|
||||
stake_keyed_account.deactivate_stake(&clock, &[new_staker_keyed_account]),
|
||||
Ok(())
|
||||
);
|
||||
}
|
||||
|
@ -190,7 +190,6 @@ fn test_stake_account_delegate() {
|
||||
vec![stake_instruction::deactivate_stake(
|
||||
&staker_pubkey,
|
||||
&staker_pubkey,
|
||||
&vote_pubkey,
|
||||
)],
|
||||
Some(&mint_pubkey),
|
||||
);
|
||||
|
Reference in New Issue
Block a user