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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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

@ -29,9 +29,9 @@ VoteState is the current state of all the votes the validator has submitted to t
* Account::lamports - The accumulated lamports from the commission. These do not count as stakes.
* `authorized_voter` - Only this identity is authorized to submit votes. This field can only modified by this identity.
* `node_pubkey` - The Solana node that votes in this account.
* `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's
* `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's
address and the authorized vote signer
### VoteInstruction::Initialize(VoteInit)
@ -77,12 +77,12 @@ StakeState::Stake is the current delegation preference of the **staker** and con
* `deactivated` - the epoch at which this stake was de-activated, some cool down epochs are required before the account
is fully deactivated, and the stake available for withdrawal
* `authorized_staker` - the pubkey of the entity that must sign delegation, activation, and deactivation transactions
* `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's
* `authorized_withdrawer` - the identity of the entity in charge of the lamports of this account, separate from the account's
address, and the authorized staker
### StakeState::RewardsPool
To avoid a single network wide lock or contention in redemption, 256 RewardsPools are part of genesis under pre-determined
To avoid a single network wide lock or contention in redemption, 256 RewardsPools are part of genesis under pre-determined
keys, each with std::u64::MAX credits to be able to satisfy redemptions according to point value.
The Stakes and the RewardsPool are accounts that are owned by the same `Stake` program.
@ -99,8 +99,8 @@ stake is re-delegated The transaction must be signed by the stake's `authorized
### StakeInstruction::Authorize\(Pubkey, StakeAuthorize\)
Updates the account with a new authorized staker or withdrawer, according to
the StakeAuthorize parameter (`Staker` or `Withdrawer`). The transaction must be by signed by the
Updates the account with a new authorized staker or withdrawer, according to
the StakeAuthorize parameter (`Staker` or `Withdrawer`). The transaction must be by signed by the
Stakee account's current `authorized_staker` or `authorized_withdrawer`.
* `account[0]` - RW - The StakeState
@ -119,7 +119,7 @@ The Vote account and the Stake account pair maintain a lifetime counter of total
* `account[3]` - R - sysvar::rewards account from the Bank that carries point value.
* `account[4]` - R - sysvar::stake\_history account from the Bank that carries stake warmup/cooldown history
Reward is paid out for the difference between `VoteState::credits` to `StakeState::Stake::credits_observed`, multiplied by `sysvar::rewards::Rewards::validator_point_value`. `StakeState::Stake::credits_observed` is updated to`VoteState::credits`. The commission is deposited into the Vote account token balance, and the reward is deposited to the Stake account token balance and
Reward is paid out for the difference between `VoteState::credits` to `StakeState::Stake::credits_observed`, multiplied by `sysvar::rewards::Rewards::validator_point_value`. `StakeState::Stake::credits_observed` is updated to`VoteState::credits`. The commission is deposited into the Vote account token balance, and the reward is deposited to the Stake account token balance and
the stake account's `stake` is increased by the same amount (re-invested).
```text
@ -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(
&sysvar::clock::id(),
false,
&mut sysvar::rewards::create_account(1, 0.0, 0.0)
),
],
&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),
);