multiple deactivation (#6354)

This commit is contained in:
Rob Walker 2019-10-15 12:50:31 -07:00 committed by GitHub
parent dfca2b510b
commit 41067de5e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 3 deletions

View File

@ -20,6 +20,7 @@ use solana_sdk::{
pub enum StakeError {
NoCreditsToRedeem,
LockupInForce,
AlreadyDeactivated,
}
impl<E> DecodeError<E> for StakeError {
fn type_of() -> &'static str {
@ -31,6 +32,7 @@ impl std::fmt::Display for StakeError {
match self {
StakeError::NoCreditsToRedeem => write!(f, "not enough credits to redeem"),
StakeError::LockupInForce => write!(f, "lockup has not yet expired"),
StakeError::AlreadyDeactivated => write!(f, "stake already deactivated"),
}
}
}

View File

@ -396,8 +396,13 @@ impl Stake {
}
}
fn deactivate(&mut self, epoch: u64) {
self.deactivation_epoch = epoch;
fn deactivate(&mut self, epoch: u64) -> Result<(), StakeError> {
if self.deactivation_epoch != std::u64::MAX {
Err(StakeError::AlreadyDeactivated)
} else {
self.deactivation_epoch = epoch;
Ok(())
}
}
}
@ -512,7 +517,7 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
) -> Result<(), InstructionError> {
if let StakeState::Stake(authorized, lockup, mut stake) = self.state()? {
authorized.check(signers, StakeAuthorize::Staker)?;
stake.deactivate(clock.epoch);
stake.deactivate(clock.epoch)?;
self.set_state(&StakeState::Stake(authorized, lockup, stake))
} else {
@ -1250,6 +1255,12 @@ mod tests {
stake_keyed_account.deactivate_stake(&clock, &signers),
Ok(())
);
// verify that deactivate() only works once
assert_eq!(
stake_keyed_account.deactivate_stake(&clock, &signers),
Err(StakeError::AlreadyDeactivated.into())
);
}
#[test]