Remove vote pubkey from deactivate_stake (#6257)
* Remove vote pubkey from deactivate_stake * Fix test * Update docs
This commit is contained in:
parent
4a071b06bd
commit
79987e788e
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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(
|
||||
&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),
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue