include vote account in deactivate (#5476)
This commit is contained in:
@ -47,7 +47,8 @@ pub enum StakeInstruction {
|
||||
///
|
||||
/// Expects 2 Accounts:
|
||||
/// 0 - Delegate StakeAccount
|
||||
/// 1 - Syscall Account that carries epoch
|
||||
/// 1 - VoteAccount to which the Stake is delegated
|
||||
/// 2 - Syscall Account that carries epoch
|
||||
Deactivate,
|
||||
}
|
||||
|
||||
@ -79,7 +80,7 @@ pub fn create_stake_account_and_delegate_stake(
|
||||
pub fn redeem_vote_credits(stake_pubkey: &Pubkey, vote_pubkey: &Pubkey) -> Instruction {
|
||||
let account_metas = vec![
|
||||
AccountMeta::new(*stake_pubkey, false),
|
||||
AccountMeta::new(*vote_pubkey, false),
|
||||
AccountMeta::new_credit_only(*vote_pubkey, false),
|
||||
AccountMeta::new(crate::rewards_pools::random_id(), false),
|
||||
AccountMeta::new_credit_only(sysvar::rewards::id(), false),
|
||||
];
|
||||
@ -104,9 +105,10 @@ pub fn withdraw(stake_pubkey: &Pubkey, to_pubkey: &Pubkey, lamports: u64) -> Ins
|
||||
Instruction::new(id(), &StakeInstruction::Withdraw(lamports), account_metas)
|
||||
}
|
||||
|
||||
pub fn deactivate_stake(stake_pubkey: &Pubkey) -> Instruction {
|
||||
pub fn deactivate_stake(stake_pubkey: &Pubkey, vote_pubkey: &Pubkey) -> Instruction {
|
||||
let account_metas = vec![
|
||||
AccountMeta::new(*stake_pubkey, true),
|
||||
AccountMeta::new_credit_only(*vote_pubkey, false),
|
||||
AccountMeta::new_credit_only(sysvar::clock::id(), false),
|
||||
];
|
||||
Instruction::new(id(), &StakeInstruction::Deactivate, account_metas)
|
||||
@ -168,12 +170,14 @@ pub fn process_instruction(
|
||||
)
|
||||
}
|
||||
StakeInstruction::Deactivate => {
|
||||
if rest.len() != 1 {
|
||||
if rest.len() != 2 {
|
||||
Err(InstructionError::InvalidInstructionData)?;
|
||||
}
|
||||
let sysvar = &rest[0];
|
||||
let (vote, rest) = rest.split_at_mut(1);
|
||||
let vote = &mut vote[0];
|
||||
let clock = &rest[0];
|
||||
|
||||
me.deactivate_stake(&sysvar::clock::from_keyed_account(&sysvar)?)
|
||||
me.deactivate_stake(vote, &sysvar::clock::from_keyed_account(&clock)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,7 +229,7 @@ mod tests {
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
assert_eq!(
|
||||
process_instruction(&deactivate_stake(&Pubkey::default())),
|
||||
process_instruction(&deactivate_stake(&Pubkey::default(), &Pubkey::default())),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
}
|
||||
@ -351,6 +355,7 @@ 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(),
|
||||
@ -368,7 +373,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::clock::id(),
|
||||
|
@ -180,7 +180,11 @@ pub trait StakeAccount {
|
||||
stake: u64,
|
||||
clock: &sysvar::clock::Clock,
|
||||
) -> Result<(), InstructionError>;
|
||||
fn deactivate_stake(&mut self, clock: &sysvar::clock::Clock) -> Result<(), InstructionError>;
|
||||
fn deactivate_stake(
|
||||
&mut self,
|
||||
vote_account: &KeyedAccount,
|
||||
clock: &sysvar::clock::Clock,
|
||||
) -> Result<(), InstructionError>;
|
||||
fn redeem_vote_credits(
|
||||
&mut self,
|
||||
vote_account: &mut KeyedAccount,
|
||||
@ -225,7 +229,11 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
||||
Err(InstructionError::InvalidAccountData)
|
||||
}
|
||||
}
|
||||
fn deactivate_stake(&mut self, clock: &sysvar::clock::Clock) -> Result<(), InstructionError> {
|
||||
fn deactivate_stake(
|
||||
&mut self,
|
||||
_vote_account: &KeyedAccount, // TODO: used in slashing
|
||||
clock: &sysvar::clock::Clock,
|
||||
) -> Result<(), InstructionError> {
|
||||
if self.signer_key().is_none() {
|
||||
return Err(InstructionError::MissingRequiredSignature);
|
||||
}
|
||||
@ -466,17 +474,22 @@ 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);
|
||||
|
||||
// unsigned keyed account
|
||||
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, false, &mut stake_account);
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&clock),
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
);
|
||||
|
||||
// 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(&clock),
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock),
|
||||
Err(InstructionError::InvalidAccountData)
|
||||
);
|
||||
|
||||
@ -492,7 +505,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// Deactivate after staking
|
||||
assert_eq!(stake_keyed_account.deactivate_stake(&clock), Ok(()));
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock),
|
||||
Ok(())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -570,7 +586,10 @@ mod tests {
|
||||
);
|
||||
|
||||
// deactivate the stake before withdrawal
|
||||
assert_eq!(stake_keyed_account.deactivate_stake(&clock), Ok(()));
|
||||
assert_eq!(
|
||||
stake_keyed_account.deactivate_stake(&vote_keyed_account, &clock),
|
||||
Ok(())
|
||||
);
|
||||
// simulate time passing
|
||||
clock.epoch += STAKE_WARMUP_EPOCHS * 2;
|
||||
|
||||
|
@ -175,7 +175,10 @@ fn test_stake_account_delegate() {
|
||||
|
||||
// Deactivate the stake
|
||||
let message = Message::new_with_payer(
|
||||
vec![stake_instruction::deactivate_stake(&staker_pubkey)],
|
||||
vec![stake_instruction::deactivate_stake(
|
||||
&staker_pubkey,
|
||||
&vote_pubkey,
|
||||
)],
|
||||
Some(&mint_pubkey),
|
||||
);
|
||||
assert!(bank_client
|
||||
|
Reference in New Issue
Block a user