Remove vote pubkey from deactivate_stake (#6257)

* Remove vote pubkey from deactivate_stake

* Fix test

* Update docs
This commit is contained in:
Tyera Eulberg
2019-10-07 16:07:01 -06:00
committed by GitHub
parent 4a071b06bd
commit 79987e788e
8 changed files with 33 additions and 98 deletions

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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());

View File

@ -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

View File

@ -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),

View File

@ -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(())
);
}

View File

@ -190,7 +190,6 @@ fn test_stake_account_delegate() {
vec![stake_instruction::deactivate_stake(
&staker_pubkey,
&staker_pubkey,
&vote_pubkey,
)],
Some(&mint_pubkey),
);