Cleanup stake_instruction tests (#26393)

This commit is contained in:
Brooks Prumo 2022-07-06 16:15:01 -05:00 committed by GitHub
parent 16219e300e
commit ef30f1729c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 163 additions and 439 deletions

1
Cargo.lock generated
View File

@ -6096,6 +6096,7 @@ dependencies = [
"solana-program-runtime",
"solana-sdk 1.11.2",
"solana-vote-program",
"test-case",
"thiserror",
]

View File

@ -29,6 +29,7 @@ thiserror = "1.0"
assert_matches = "1.5.0"
proptest = "1.0"
solana-logger = { path = "../../logger", version = "=1.11.2" }
test-case = "2.1.0"
[build-dependencies]
rustc_version = "0.4"

View File

@ -471,8 +471,29 @@ mod tests {
},
solana_vote_program::vote_state::{self, VoteState, VoteStateVersions},
std::{borrow::BorrowMut, collections::HashSet, str::FromStr, sync::Arc},
test_case::test_case,
};
/// The "new" behavior enables all features
fn feature_set_new_behavior() -> FeatureSet {
FeatureSet::all_enabled()
}
/// The "old" behavior is before the stake minimum delegation was raised
fn feature_set_old_behavior() -> FeatureSet {
let mut feature_set = feature_set_new_behavior();
feature_set.deactivate(&feature_set::stake_raise_minimum_delegation_to_1_sol::id());
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() -> FeatureSet {
let mut feature_set = feature_set_old_behavior();
feature_set.deactivate(&feature_set::stake_allow_zero_undelegated_amount::id());
feature_set
}
fn create_default_account() -> AccountSharedData {
AccountSharedData::new(0, 0, &Pubkey::new_unique())
}
@ -599,7 +620,9 @@ mod tests {
)
}
fn do_test_stake_process_instruction(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_process_instruction(feature_set: FeatureSet) {
process_instruction_as_one_arg(
&feature_set,
&instruction::initialize(
@ -714,7 +737,9 @@ mod tests {
);
}
fn do_test_spoofed_stake_accounts(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_spoofed_stake_accounts(feature_set: FeatureSet) {
process_instruction_as_one_arg(
&feature_set,
&instruction::initialize(
@ -830,7 +855,9 @@ mod tests {
);
}
fn do_test_stake_process_instruction_decode_bail(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_process_instruction_decode_bail(feature_set: FeatureSet) {
// these will not call stake_state, have bogus contents
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
@ -1097,7 +1124,9 @@ mod tests {
);
}
fn do_test_stake_checked_instructions(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_checked_instructions(feature_set: FeatureSet) {
let stake_address = Pubkey::new_unique();
let staker = Pubkey::new_unique();
let staker_account = create_default_account();
@ -1457,7 +1486,9 @@ mod tests {
);
}
fn do_test_stake_initialize(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_initialize(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let stake_lamports = rent_exempt_reserve;
@ -1563,7 +1594,9 @@ mod tests {
);
}
fn do_test_authorize(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_authorize(feature_set: FeatureSet) {
let authority_address = solana_sdk::pubkey::new_rand();
let authority_address_2 = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
@ -1742,7 +1775,9 @@ mod tests {
);
}
fn do_test_authorize_override(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_authorize_override(feature_set: FeatureSet) {
let authority_address = solana_sdk::pubkey::new_rand();
let mallory_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
@ -1859,7 +1894,9 @@ mod tests {
);
}
fn do_test_authorize_with_seed(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_authorize_with_seed(feature_set: FeatureSet) {
let authority_base_address = solana_sdk::pubkey::new_rand();
let authority_address = solana_sdk::pubkey::new_rand();
let seed = "42";
@ -1974,7 +2011,9 @@ mod tests {
);
}
fn do_test_authorize_delegated_stake(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_authorize_delegated_stake(feature_set: FeatureSet) {
let authority_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -2163,7 +2202,9 @@ mod tests {
);
}
fn do_test_stake_delegate(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_delegate(feature_set: FeatureSet) {
let mut vote_state = VoteState::default();
for i in 0..1000 {
vote_state.process_slot_vote_unchecked(i);
@ -2411,7 +2452,9 @@ mod tests {
);
}
fn do_test_redelegate_consider_balance_changes(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_redelegate_consider_balance_changes(feature_set: FeatureSet) {
let mut clock = Clock::default();
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -2627,7 +2670,9 @@ mod tests {
);
}
fn do_test_split(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
let stake_lamports = minimum_delegation * 2;
@ -2735,7 +2780,9 @@ mod tests {
);
}
fn do_test_withdraw_stake(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_withdraw_stake(feature_set: FeatureSet) {
let recipient_address = solana_sdk::pubkey::new_rand();
let authority_address = solana_sdk::pubkey::new_rand();
let custodian_address = solana_sdk::pubkey::new_rand();
@ -3024,7 +3071,9 @@ mod tests {
);
}
fn do_test_withdraw_stake_before_warmup(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_withdraw_stake_before_warmup(feature_set: FeatureSet) {
let recipient_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -3155,7 +3204,9 @@ mod tests {
);
}
fn do_test_withdraw_lockup(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_withdraw_lockup(feature_set: FeatureSet) {
let recipient_address = solana_sdk::pubkey::new_rand();
let custodian_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
@ -3279,7 +3330,9 @@ mod tests {
assert_eq!(from(&accounts[0]).unwrap(), StakeState::Uninitialized);
}
fn do_test_withdraw_rent_exempt(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_withdraw_rent_exempt(feature_set: FeatureSet) {
let recipient_address = solana_sdk::pubkey::new_rand();
let custodian_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
@ -3369,7 +3422,9 @@ mod tests {
);
}
fn do_test_deactivate(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_deactivate(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
let stake_lamports = minimum_delegation;
@ -3491,7 +3546,9 @@ mod tests {
);
}
fn do_test_set_lockup(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_set_lockup(feature_set: FeatureSet) {
let custodian_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
let stake_address = solana_sdk::pubkey::new_rand();
@ -3775,7 +3832,9 @@ mod tests {
/// Ensure that `initialize()` respects the minimum balance requirements
/// - Assert 1: accounts with a balance equal-to the rent exemption initialize OK
/// - Assert 2: accounts with a balance less-than the rent exemption do not initialize
fn do_test_initialize_minimum_balance(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_initialize_minimum_balance(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let stake_address = solana_sdk::pubkey::new_rand();
@ -3831,7 +3890,9 @@ mod tests {
/// withdrawing below the minimum delegation, then re-delegating successfully (see
/// `test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation()` for
/// more information.)
fn do_test_delegate_minimum_stake_delegation(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_delegate_minimum_stake_delegation(feature_set: FeatureSet) {
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -3924,7 +3985,9 @@ mod tests {
/// EQ | LT | Err
/// LT | EQ | Err
/// LT | LT | Err
fn do_test_split_minimum_stake_delegation(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_minimum_stake_delegation(feature_set: FeatureSet) {
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -4017,7 +4080,9 @@ mod tests {
/// delegation is OK
/// - Assert 2: splitting the full amount from an account that has less than the minimum
/// delegation is not OK
fn do_test_split_full_amount_minimum_stake_delegation(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_full_amount_minimum_stake_delegation(feature_set: FeatureSet) {
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -4088,7 +4153,9 @@ mod tests {
/// Ensure that `split()` correctly handles prefunded destination accounts from
/// initialized stakes. When a destination account already has funds, ensure
/// the minimum split amount reduces accordingly.
fn do_test_initialized_split_destination_minimum_balance(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_initialized_split_destination_minimum_balance(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let source_address = Pubkey::new_unique();
@ -4183,7 +4250,9 @@ mod tests {
/// Ensure that `split()` correctly handles prefunded destination accounts from staked stakes.
/// When a destination account already has funds, ensure the minimum split amount reduces
/// accordingly.
fn do_test_staked_split_destination_minimum_balance(
#[test_case(feature_set_old_behavior(), &[Ok(()), Ok(())]; "old_behavior")]
#[test_case(feature_set_new_behavior(), &[ Err(InstructionError::InsufficientFunds), Err(InstructionError::InsufficientFunds) ] ; "new_behavior")]
fn test_staked_split_destination_minimum_balance(
feature_set: FeatureSet,
expected_results: &[Result<(), InstructionError>],
) {
@ -4334,7 +4403,9 @@ mod tests {
/// Ensure that `withdraw()` respects the minimum delegation requirements
/// - Assert 1: withdrawing so remaining stake is equal-to the minimum is OK
/// - Assert 2: withdrawing so remaining stake is less-than the minimum is not OK
fn do_test_withdraw_minimum_stake_delegation(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_withdraw_minimum_stake_delegation(feature_set: FeatureSet) {
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -4437,7 +4508,14 @@ 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
fn do_test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation(
//
// 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: FeatureSet,
expected_result: Result<(), InstructionError>,
) {
@ -4617,7 +4695,9 @@ mod tests {
);
}
fn do_test_split_source_uninitialized(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_source_uninitialized(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -4715,7 +4795,9 @@ mod tests {
);
}
fn do_test_split_split_not_uninitialized(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_split_not_uninitialized(feature_set: FeatureSet) {
let stake_lamports = 42;
let stake_address = solana_sdk::pubkey::new_rand();
let stake_account = AccountSharedData::new_data_with_space(
@ -4764,7 +4846,9 @@ mod tests {
}
}
fn do_test_split_more_than_staked(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_more_than_staked(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -4821,7 +4905,9 @@ mod tests {
);
}
fn do_test_split_with_rent(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_with_rent(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -4929,7 +5015,9 @@ mod tests {
}
}
fn do_test_split_to_account_with_rent_exempt_reserve(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_to_account_with_rent_exempt_reserve(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -5052,7 +5140,9 @@ mod tests {
}
}
fn do_test_split_from_larger_sized_account(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_from_larger_sized_account(feature_set: FeatureSet) {
let rent = Rent::default();
let source_larger_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of() + 100);
let split_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -5181,7 +5271,9 @@ mod tests {
}
}
fn do_test_split_from_smaller_sized_account(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_from_smaller_sized_account(feature_set: FeatureSet) {
let rent = Rent::default();
let source_smaller_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let split_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of() + 100);
@ -5258,7 +5350,9 @@ mod tests {
}
}
fn do_test_split_100_percent_of_source(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_100_percent_of_source(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -5352,7 +5446,9 @@ mod tests {
}
}
fn do_test_split_100_percent_of_source_to_account_with_lamports(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_100_percent_of_source_to_account_with_lamports(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
let minimum_delegation = crate::get_minimum_delegation(&feature_set);
@ -5446,7 +5542,9 @@ mod tests {
}
}
fn do_test_split_rent_exemptness(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_split_rent_exemptness(feature_set: FeatureSet) {
let rent = Rent::default();
let source_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of() + 100);
let split_rent_exempt_reserve = rent.minimum_balance(StakeState::size_of());
@ -5582,7 +5680,9 @@ mod tests {
}
}
fn do_test_merge(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_merge(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let merge_from_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
@ -5710,7 +5810,9 @@ mod tests {
}
}
fn do_test_merge_self_fails(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_merge_self_fails(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
let rent = Rent::default();
@ -5785,7 +5887,9 @@ mod tests {
);
}
fn do_test_merge_incorrect_authorized_staker(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_merge_incorrect_authorized_staker(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let merge_from_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
@ -5877,7 +5981,9 @@ mod tests {
}
}
fn do_test_merge_invalid_account_data(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_merge_invalid_account_data(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let merge_from_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
@ -5956,7 +6062,9 @@ mod tests {
}
}
fn do_test_merge_fake_stake_source(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_merge_fake_stake_source(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let merge_from_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
@ -6025,7 +6133,9 @@ mod tests {
);
}
fn do_test_merge_active_stake(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_merge_active_stake(feature_set: FeatureSet) {
let stake_address = solana_sdk::pubkey::new_rand();
let merge_from_address = solana_sdk::pubkey::new_rand();
let authorized_address = solana_sdk::pubkey::new_rand();
@ -6283,7 +6393,9 @@ mod tests {
);
}
fn do_test_stake_get_minimum_delegation(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_get_minimum_delegation(feature_set: FeatureSet) {
let stake_address = Pubkey::new_unique();
let stake_account = create_default_stake_account();
let instruction_data = serialize(&StakeInstruction::GetMinimumDelegation).unwrap();
@ -6336,7 +6448,9 @@ mod tests {
// disabled | bad | some || Err InvalidInstructionData
// disabled | good | none || Err NotEnoughAccountKeys
// disabled | bad | none || Err NotEnoughAccountKeys
fn do_test_stake_process_instruction_error_ordering(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_stake_process_instruction_error_ordering(feature_set: FeatureSet) {
let rent = Rent::default();
let rent_address = sysvar::rent::id();
let rent_account = account::create_account_shared_data_for_test(&rent);
@ -6440,7 +6554,9 @@ mod tests {
}
}
fn do_test_deactivate_delinquent(feature_set: FeatureSet) {
#[test_case(feature_set_old_behavior(); "old_behavior")]
#[test_case(feature_set_new_behavior(); "new_behavior")]
fn test_deactivate_delinquent(feature_set: FeatureSet) {
let feature_set = Arc::new(feature_set);
let mut sysvar_cache_override = SysvarCache::default();
@ -6707,398 +6823,4 @@ mod tests {
Err(StakeError::MinimumDelinquentEpochsForDeactivationNotMet.into()),
);
}
mod old_behavior {
use super::*;
fn new_feature_set() -> FeatureSet {
let mut feature_set = FeatureSet::all_enabled();
feature_set.deactivate(&feature_set::stake_raise_minimum_delegation_to_1_sol::id());
feature_set
}
#[test]
fn test_stake_process_instruction() {
do_test_stake_process_instruction(new_feature_set());
}
#[test]
fn test_stake_process_instruction_decode_bail() {
do_test_stake_process_instruction_decode_bail(new_feature_set());
}
#[test]
fn test_stake_checked_instructions() {
do_test_stake_checked_instructions(new_feature_set());
}
#[test]
fn test_stake_initialize() {
do_test_stake_initialize(new_feature_set());
}
#[test]
fn test_authorize() {
do_test_authorize(new_feature_set());
}
#[test]
fn test_authorize_override() {
do_test_authorize_override(new_feature_set());
}
#[test]
fn test_authorize_with_seed() {
do_test_authorize_with_seed(new_feature_set());
}
#[test]
fn test_authorize_delegated_stake() {
do_test_authorize_delegated_stake(new_feature_set());
}
#[test]
fn test_stake_delegate() {
do_test_stake_delegate(new_feature_set());
}
#[test]
fn test_redelegate_consider_balance_changes() {
do_test_redelegate_consider_balance_changes(new_feature_set());
}
#[test]
fn test_split() {
do_test_split(new_feature_set());
}
#[test]
fn test_withdraw_stake() {
do_test_withdraw_stake(new_feature_set());
}
#[test]
fn test_withdraw_stake_before_warmup() {
do_test_withdraw_stake_before_warmup(new_feature_set());
}
#[test]
fn test_withdraw_lockup() {
do_test_withdraw_lockup(new_feature_set());
}
#[test]
fn test_withdraw_rent_exempt() {
do_test_withdraw_rent_exempt(new_feature_set());
}
#[test]
fn test_deactivate() {
do_test_deactivate(new_feature_set());
}
#[test]
fn test_set_lockup() {
do_test_set_lockup(new_feature_set());
}
#[test]
fn test_initialize_minimum_balance() {
do_test_initialize_minimum_balance(new_feature_set());
}
#[test]
fn test_delegate_minimum_stake_delegation() {
do_test_delegate_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_split_minimum_stake_delegation() {
do_test_split_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_split_full_amount_minimum_stake_delegation() {
do_test_split_full_amount_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_initialized_split_destination_minimum_balance() {
do_test_initialized_split_destination_minimum_balance(new_feature_set());
}
#[test]
fn test_staked_split_destination_minimum_balance() {
do_test_staked_split_destination_minimum_balance(new_feature_set(), &[Ok(()), Ok(())]);
}
#[test]
fn test_withdraw_minimum_stake_delegation() {
do_test_withdraw_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation() {
let mut feature_set = new_feature_set();
// The "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.
feature_set.deactivate(&feature_set::stake_allow_zero_undelegated_amount::id());
do_test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation(
feature_set,
Ok(()),
);
}
#[test]
fn test_split_source_uninitialized() {
do_test_split_source_uninitialized(new_feature_set());
}
#[test]
fn test_split_split_not_uninitialized() {
do_test_split_split_not_uninitialized(new_feature_set());
}
#[test]
fn test_split_more_than_staked() {
do_test_split_more_than_staked(new_feature_set());
}
#[test]
fn test_split_with_rent() {
do_test_split_with_rent(new_feature_set());
}
#[test]
fn test_split_to_account_with_rent_exempt_reserve() {
do_test_split_to_account_with_rent_exempt_reserve(new_feature_set());
}
#[test]
fn test_split_from_larger_sized_account() {
do_test_split_from_larger_sized_account(new_feature_set());
}
#[test]
fn test_split_from_smaller_sized_account() {
do_test_split_from_smaller_sized_account(new_feature_set());
}
#[test]
fn test_split_100_percent_of_source() {
do_test_split_100_percent_of_source(new_feature_set());
}
#[test]
fn test_split_100_percent_of_source_to_account_with_lamports() {
do_test_split_100_percent_of_source_to_account_with_lamports(new_feature_set());
}
#[test]
fn test_split_rent_exemptness() {
do_test_split_rent_exemptness(new_feature_set());
}
#[test]
fn test_merge() {
do_test_merge(new_feature_set());
}
#[test]
fn test_merge_self_fails() {
do_test_merge_self_fails(new_feature_set());
}
#[test]
fn test_merge_incorrect_authorized_staker() {
do_test_merge_incorrect_authorized_staker(new_feature_set());
}
#[test]
fn test_merge_invalid_account_data() {
do_test_merge_invalid_account_data(new_feature_set());
}
#[test]
fn test_merge_fake_stake_source() {
do_test_merge_fake_stake_source(new_feature_set());
}
#[test]
fn test_merge_active_stake() {
do_test_merge_active_stake(new_feature_set());
}
#[test]
fn test_stake_get_minimum_delegation() {
do_test_stake_get_minimum_delegation(new_feature_set());
}
#[test]
fn test_stake_process_instruction_error_ordering() {
do_test_stake_process_instruction_error_ordering(new_feature_set());
}
#[test]
fn test_deactivate_delinquent() {
do_test_deactivate_delinquent(new_feature_set());
}
}
mod new_behavior {
use super::*;
fn new_feature_set() -> FeatureSet {
FeatureSet::all_enabled()
}
#[test]
fn test_stake_process_instruction() {
do_test_stake_process_instruction(new_feature_set());
}
#[test]
fn test_spoofed_stake_accounts() {
do_test_spoofed_stake_accounts(new_feature_set());
}
#[test]
fn test_stake_process_instruction_decode_bail() {
do_test_stake_process_instruction_decode_bail(new_feature_set());
}
#[test]
fn test_stake_checked_instructions() {
do_test_stake_checked_instructions(new_feature_set());
}
#[test]
fn test_stake_initialize() {
do_test_stake_initialize(new_feature_set());
}
#[test]
fn test_authorize() {
do_test_authorize(new_feature_set());
}
#[test]
fn test_authorize_override() {
do_test_authorize_override(new_feature_set());
}
#[test]
fn test_authorize_with_seed() {
do_test_authorize_with_seed(new_feature_set());
}
#[test]
fn test_authorize_delegated_stake() {
do_test_authorize_delegated_stake(new_feature_set());
}
#[test]
fn test_stake_delegate() {
do_test_stake_delegate(new_feature_set());
}
#[test]
fn test_redelegate_consider_balance_changes() {
do_test_redelegate_consider_balance_changes(new_feature_set());
}
#[test]
fn test_split() {
do_test_split(new_feature_set());
}
#[test]
fn test_withdraw_stake() {
do_test_withdraw_stake(new_feature_set());
}
#[test]
fn test_withdraw_stake_before_warmup() {
do_test_withdraw_stake_before_warmup(new_feature_set());
}
#[test]
fn test_withdraw_lockup() {
do_test_withdraw_lockup(new_feature_set());
}
#[test]
fn test_withdraw_rent_exempt() {
do_test_withdraw_rent_exempt(new_feature_set());
}
#[test]
fn test_deactivate() {
do_test_deactivate(new_feature_set());
}
#[test]
fn test_set_lockup() {
do_test_set_lockup(new_feature_set());
}
#[test]
fn test_initialize_minimum_balance() {
do_test_initialize_minimum_balance(new_feature_set());
}
#[test]
fn test_delegate_minimum_stake_delegation() {
do_test_delegate_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_split_minimum_stake_delegation() {
do_test_split_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_split_full_amount_minimum_stake_delegation() {
do_test_split_full_amount_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_initialized_split_destination_minimum_balance() {
do_test_initialized_split_destination_minimum_balance(new_feature_set());
}
#[test]
fn test_staked_split_destination_minimum_balance() {
do_test_staked_split_destination_minimum_balance(
new_feature_set(),
&[
Err(InstructionError::InsufficientFunds),
Err(InstructionError::InsufficientFunds),
],
);
}
#[test]
fn test_withdraw_minimum_stake_delegation() {
do_test_withdraw_minimum_stake_delegation(new_feature_set());
}
#[test]
fn test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation() {
do_test_behavior_withdrawal_then_redelegate_with_less_than_minimum_stake_delegation(
new_feature_set(),
Err(StakeError::InsufficientDelegation.into()),
);
}
#[test]
fn test_split_source_uninitialized() {
do_test_split_source_uninitialized(new_feature_set());
}
#[test]
fn test_split_split_not_uninitialized() {
do_test_split_split_not_uninitialized(new_feature_set());
}
#[test]
fn test_split_more_than_staked() {
do_test_split_more_than_staked(new_feature_set());
}
#[test]
fn test_split_with_rent() {
do_test_split_with_rent(new_feature_set());
}
#[test]
fn test_split_to_account_with_rent_exempt_reserve() {
do_test_split_to_account_with_rent_exempt_reserve(new_feature_set());
}
#[test]
fn test_split_from_larger_sized_account() {
do_test_split_from_larger_sized_account(new_feature_set());
}
#[test]
fn test_split_from_smaller_sized_account() {
do_test_split_from_smaller_sized_account(new_feature_set());
}
#[test]
fn test_split_100_percent_of_source() {
do_test_split_100_percent_of_source(new_feature_set());
}
#[test]
fn test_split_100_percent_of_source_to_account_with_lamports() {
do_test_split_100_percent_of_source_to_account_with_lamports(new_feature_set());
}
#[test]
fn test_split_rent_exemptness() {
do_test_split_rent_exemptness(new_feature_set());
}
#[test]
fn test_merge() {
do_test_merge(new_feature_set());
}
#[test]
fn test_merge_self_fails() {
do_test_merge_self_fails(new_feature_set());
}
#[test]
fn test_merge_incorrect_authorized_staker() {
do_test_merge_incorrect_authorized_staker(new_feature_set());
}
#[test]
fn test_merge_invalid_account_data() {
do_test_merge_invalid_account_data(new_feature_set());
}
#[test]
fn test_merge_fake_stake_source() {
do_test_merge_fake_stake_source(new_feature_set());
}
#[test]
fn test_merge_active_stake() {
do_test_merge_active_stake(new_feature_set());
}
#[test]
fn test_stake_get_minimum_delegation() {
do_test_stake_get_minimum_delegation(new_feature_set());
}
#[test]
fn test_stake_process_instruction_error_ordering() {
do_test_stake_process_instruction_error_ordering(new_feature_set());
}
#[test]
fn test_deactivate_delinquent() {
do_test_deactivate_delinquent(new_feature_set());
}
}
}