stake: Remove `stake_allow_zero_undelegated_amount` usage (#32210)
This commit is contained in:
parent
9a620b4862
commit
383063eeb2
|
@ -77,13 +77,7 @@ declare_process_instruction!(
|
|||
let mut me = get_stake_account()?;
|
||||
let rent =
|
||||
get_sysvar_with_account_check::rent(invoke_context, instruction_context, 1)?;
|
||||
initialize(
|
||||
&mut me,
|
||||
&authorized,
|
||||
&lockup,
|
||||
&rent,
|
||||
&invoke_context.feature_set,
|
||||
)
|
||||
initialize(&mut me, &authorized, &lockup, &rent)
|
||||
}
|
||||
Ok(StakeInstruction::Authorize(authorized_pubkey, stake_authorize)) => {
|
||||
let mut me = get_stake_account()?;
|
||||
|
@ -261,7 +255,6 @@ declare_process_instruction!(
|
|||
} else {
|
||||
None
|
||||
},
|
||||
&invoke_context.feature_set,
|
||||
)
|
||||
}
|
||||
Ok(StakeInstruction::Deactivate) => {
|
||||
|
@ -302,13 +295,7 @@ declare_process_instruction!(
|
|||
instruction_context,
|
||||
1,
|
||||
)?;
|
||||
initialize(
|
||||
&mut me,
|
||||
&authorized,
|
||||
&Lockup::default(),
|
||||
&rent,
|
||||
&invoke_context.feature_set,
|
||||
)
|
||||
initialize(&mut me, &authorized, &Lockup::default(), &rent)
|
||||
} else {
|
||||
Err(InstructionError::InvalidInstructionData)
|
||||
}
|
||||
|
@ -525,16 +512,6 @@ mod tests {
|
|||
feature_set
|
||||
}
|
||||
|
||||
/// The "old old" behavior is both before the stake minimum delegation was raised *and* before
|
||||
/// undelegated stake accounts could have zero lamports beyond rent
|
||||
fn feature_set_old_old_behavior() -> Arc<FeatureSet> {
|
||||
let mut feature_set = feature_set_old_behavior();
|
||||
Arc::get_mut(&mut feature_set)
|
||||
.unwrap()
|
||||
.deactivate(&feature_set::stake_allow_zero_undelegated_amount::id());
|
||||
feature_set
|
||||
}
|
||||
|
||||
fn create_default_account() -> AccountSharedData {
|
||||
AccountSharedData::new(0, 0, &Pubkey::new_unique())
|
||||
}
|
||||
|
@ -4470,17 +4447,9 @@ mod tests {
|
|||
/// 3. Deactives the delegation
|
||||
/// 4. Withdraws from the account such that the ending balance is *below* rent + minimum delegation
|
||||
/// 5. Re-delegates, now with less than the minimum delegation, but it still succeeds
|
||||
//
|
||||
// The "old old" behavior relies on `validate_delegated_amount()` *not* checking if the
|
||||
// stake amount meets the minimum delegation. Once the
|
||||
// `stake_allow_zero_undelegated_amount` feature is activated, `the expected_result`
|
||||
// parameter can be removed and consolidated.
|
||||
#[test_case(feature_set_old_old_behavior(), Ok(()); "old_old_behavior")]
|
||||
#[test_case(feature_set_new_behavior(), Err(StakeError::InsufficientDelegation.into()); "new_behavior")]
|
||||
fn test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation(
|
||||
feature_set: Arc<FeatureSet>,
|
||||
expected_result: Result<(), InstructionError>,
|
||||
) {
|
||||
#[test]
|
||||
fn test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation() {
|
||||
let feature_set = feature_set_new_behavior();
|
||||
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
|
||||
let rent = Rent::default();
|
||||
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
|
||||
|
@ -4641,7 +4610,7 @@ mod tests {
|
|||
&serialize(&StakeInstruction::DelegateStake).unwrap(),
|
||||
transaction_accounts,
|
||||
instruction_accounts,
|
||||
expected_result,
|
||||
Err(StakeError::InsufficientDelegation.into()),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ use {
|
|||
account_utils::StateMut,
|
||||
clock::{Clock, Epoch},
|
||||
feature_set::{
|
||||
self, clean_up_delegation_errors, stake_allow_zero_undelegated_amount,
|
||||
stake_merge_with_unmatched_credits_observed, stake_split_uses_rent_sysvar, FeatureSet,
|
||||
self, clean_up_delegation_errors, stake_merge_with_unmatched_credits_observed,
|
||||
stake_split_uses_rent_sysvar, FeatureSet,
|
||||
},
|
||||
instruction::{checked_add, InstructionError},
|
||||
pubkey::Pubkey,
|
||||
|
@ -464,22 +464,13 @@ pub fn initialize(
|
|||
authorized: &Authorized,
|
||||
lockup: &Lockup,
|
||||
rent: &Rent,
|
||||
feature_set: &FeatureSet,
|
||||
) -> Result<(), InstructionError> {
|
||||
if stake_account.get_data().len() != StakeState::size_of() {
|
||||
return Err(InstructionError::InvalidAccountData);
|
||||
}
|
||||
if let StakeState::Uninitialized = stake_account.get_state()? {
|
||||
let rent_exempt_reserve = rent.minimum_balance(stake_account.get_data().len());
|
||||
// when removing this feature, remove `minimum_balance` and just use `rent_exempt_reserve`
|
||||
let minimum_balance = if feature_set.is_active(&stake_allow_zero_undelegated_amount::id()) {
|
||||
rent_exempt_reserve
|
||||
} else {
|
||||
let minimum_delegation = crate::get_minimum_delegation(feature_set);
|
||||
rent_exempt_reserve + minimum_delegation
|
||||
};
|
||||
|
||||
if stake_account.get_lamports() >= minimum_balance {
|
||||
if stake_account.get_lamports() >= rent_exempt_reserve {
|
||||
stake_account.set_state(&StakeState::Initialized(Meta {
|
||||
rent_exempt_reserve,
|
||||
authorized: *authorized,
|
||||
|
@ -774,14 +765,6 @@ pub fn split(
|
|||
}
|
||||
StakeState::Initialized(meta) => {
|
||||
meta.authorized.check(signers, StakeAuthorize::Staker)?;
|
||||
let additional_required_lamports = if invoke_context
|
||||
.feature_set
|
||||
.is_active(&stake_allow_zero_undelegated_amount::id())
|
||||
{
|
||||
0
|
||||
} else {
|
||||
crate::get_minimum_delegation(&invoke_context.feature_set)
|
||||
};
|
||||
let validated_split_info = validate_split_amount(
|
||||
invoke_context,
|
||||
transaction_context,
|
||||
|
@ -791,7 +774,7 @@ pub fn split(
|
|||
lamports,
|
||||
&meta,
|
||||
None,
|
||||
additional_required_lamports,
|
||||
0, // additional_required_lamports
|
||||
)?;
|
||||
let mut split_meta = meta;
|
||||
split_meta.rent_exempt_reserve = validated_split_info.destination_rent_exempt_reserve;
|
||||
|
@ -1026,7 +1009,6 @@ pub fn withdraw(
|
|||
stake_history: &StakeHistory,
|
||||
withdraw_authority_index: IndexOfAccount,
|
||||
custodian_index: Option<IndexOfAccount>,
|
||||
feature_set: &FeatureSet,
|
||||
) -> Result<(), InstructionError> {
|
||||
let withdraw_authority_pubkey = transaction_context.get_key_of_account_at_index(
|
||||
instruction_context
|
||||
|
@ -1061,16 +1043,7 @@ pub fn withdraw(
|
|||
meta.authorized
|
||||
.check(&signers, StakeAuthorize::Withdrawer)?;
|
||||
// stake accounts must have a balance >= rent_exempt_reserve
|
||||
let reserve = if feature_set.is_active(&stake_allow_zero_undelegated_amount::id()) {
|
||||
meta.rent_exempt_reserve
|
||||
} else {
|
||||
checked_add(
|
||||
meta.rent_exempt_reserve,
|
||||
crate::get_minimum_delegation(feature_set),
|
||||
)?
|
||||
};
|
||||
|
||||
(meta.lockup, reserve, false)
|
||||
(meta.lockup, meta.rent_exempt_reserve, false)
|
||||
}
|
||||
StakeState::Uninitialized => {
|
||||
if !signers.contains(stake_account.get_key()) {
|
||||
|
@ -1200,10 +1173,7 @@ fn validate_delegated_amount(
|
|||
|
||||
// Stake accounts may be initialized with a stake amount below the minimum delegation so check
|
||||
// that the minimum is met before delegation.
|
||||
if (feature_set.is_active(&stake_allow_zero_undelegated_amount::id())
|
||||
|| feature_set.is_active(&feature_set::stake_raise_minimum_delegation_to_1_sol::id()))
|
||||
&& stake_amount < crate::get_minimum_delegation(feature_set)
|
||||
{
|
||||
if stake_amount < crate::get_minimum_delegation(feature_set) {
|
||||
return Err(StakeError::InsufficientDelegation.into());
|
||||
}
|
||||
Ok(ValidatedDelegatedInfo { stake_amount })
|
||||
|
|
Loading…
Reference in New Issue