stake-pool: Check transient stake state (#3987)

This commit is contained in:
Jon Cinque 2023-01-27 16:09:03 +01:00 committed by GitHub
parent c6c83982d7
commit c7a1e985ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 7 deletions

View File

@ -222,6 +222,42 @@ fn stake_is_inactive_without_history(stake: &stake::state::Stake, epoch: Epoch)
&& stake.delegation.deactivation_epoch == epoch) && stake.delegation.deactivation_epoch == epoch)
} }
/// Roughly checks if a stake account is deactivating or inactive
fn check_if_stake_is_deactivating_or_inactive(
account_info: &AccountInfo,
vote_account_address: &Pubkey,
) -> Result<(), ProgramError> {
let (_, stake) = get_stake_state(account_info)?;
if stake.delegation.deactivation_epoch == Epoch::MAX {
msg!(
"Existing stake {} delegated to {} is activating or active",
account_info.key,
vote_account_address
);
Err(StakePoolError::WrongStakeState.into())
} else {
Ok(())
}
}
/// Roughly checks if a stake account is activating or active
fn check_if_stake_is_activating_or_active(
account_info: &AccountInfo,
vote_account_address: &Pubkey,
) -> Result<(), ProgramError> {
let (_, stake) = get_stake_state(account_info)?;
if stake.delegation.deactivation_epoch != Epoch::MAX {
msg!(
"Existing stake {} delegated to {} is deactivating or inactive",
account_info.key,
vote_account_address
);
Err(StakePoolError::WrongStakeState.into())
} else {
Ok(())
}
}
/// Check that the stake state is correct: usable by the pool and delegated to /// Check that the stake state is correct: usable by the pool and delegated to
/// the expected validator /// the expected validator
fn check_stake_state( fn check_stake_state(
@ -1337,8 +1373,10 @@ impl Processor {
); );
return Err(ProgramError::InvalidSeeds); return Err(ProgramError::InvalidSeeds);
} }
// Let the runtime check to see if the merge is valid, so there's no check_if_stake_is_deactivating_or_inactive(
// explicit check here that the transient stake is decreasing transient_stake_account_info,
&vote_account_address,
)?;
} }
let stake_minimum_delegation = stake::tools::get_minimum_delegation()?; let stake_minimum_delegation = stake::tools::get_minimum_delegation()?;
@ -1586,8 +1624,10 @@ impl Processor {
); );
return Err(ProgramError::InvalidSeeds); return Err(ProgramError::InvalidSeeds);
} }
// Let the runtime check to see if the merge is valid, so there's no check_if_stake_is_activating_or_active(
// explicit check here that the transient stake is increasing transient_stake_account_info,
vote_account_address,
)?;
} }
check_validator_stake_account( check_validator_stake_account(
@ -2037,6 +2077,10 @@ impl Processor {
destination_transient_stake_seed, destination_transient_stake_seed,
&stake_pool.lockup, &stake_pool.lockup,
)?; )?;
check_if_stake_is_activating_or_active(
destination_transient_stake_account_info,
vote_account_address,
)?;
Self::stake_merge( Self::stake_merge(
stake_pool_info.key, stake_pool_info.key,
ephemeral_stake_account_info.clone(), ephemeral_stake_account_info.clone(),

View File

@ -586,7 +586,7 @@ async fn fail_additional_with_increasing() {
error, error,
TransactionError::InstructionError( TransactionError::InstructionError(
0, 0,
InstructionError::Custom(stake::instruction::StakeError::MergeTransientStake as u32) InstructionError::Custom(StakePoolError::WrongStakeState as u32)
) )
); );
} }

View File

@ -585,7 +585,7 @@ async fn fail_additional_with_decreasing() {
error, error,
TransactionError::InstructionError( TransactionError::InstructionError(
0, 0,
InstructionError::Custom(StakeError::MergeTransientStake as u32) InstructionError::Custom(StakePoolError::WrongStakeState as u32)
) )
); );
} }

View File

@ -657,7 +657,7 @@ async fn fail_with_decreasing_stake() {
error, error,
TransactionError::InstructionError( TransactionError::InstructionError(
0, 0,
InstructionError::Custom(StakeError::MergeTransientStake as u32) InstructionError::Custom(StakePoolError::WrongStakeState as u32)
) )
); );
} }