diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 4aefc7654fc77d..b69bfe8a5f927d 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -115,7 +115,7 @@ pub struct InvokeContext<'a> { rent: Rent, pre_accounts: Vec, builtin_programs: &'a [BuiltinProgram], - pub sysvar_cache: &'a SysvarCache, + sysvar_cache: &'a SysvarCache, pub trace_log_stack: Vec, log_collector: Option>>, compute_budget: ComputeBudget, @@ -900,18 +900,16 @@ macro_rules! with_mock_invoke_context { }; } -pub fn mock_process_instruction( +pub fn mock_process_instruction( loader_id: &Pubkey, mut program_indices: Vec, instruction_data: &[u8], mut transaction_accounts: Vec, instruction_account_metas: Vec, - sysvar_cache_override: Option<&SysvarCache>, - feature_set_override: Option>, expected_result: Result<(), InstructionError>, process_instruction: ProcessInstructionWithContext, + mut pre_adjustments: F, ) -> Vec { - program_indices.insert(0, transaction_accounts.len() as IndexOfAccount); let mut instruction_accounts: Vec = Vec::with_capacity(instruction_account_metas.len()); for (instruction_account_index, account_meta) in instruction_account_metas.iter().enumerate() { @@ -936,20 +934,16 @@ pub fn mock_process_instruction( is_writable: account_meta.is_writable, }); } + program_indices.insert(0, transaction_accounts.len() as IndexOfAccount); let processor_account = AccountSharedData::new(0, 0, &native_loader::id()); transaction_accounts.push((*loader_id, processor_account)); with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts); - if let Some(sysvar_cache) = sysvar_cache_override { - invoke_context.sysvar_cache = &sysvar_cache; - } - if let Some(feature_set) = feature_set_override { - invoke_context.feature_set = feature_set; - } let builtin_programs = &[BuiltinProgram { program_id: *loader_id, process_instruction, }]; invoke_context.builtin_programs = builtin_programs; + pre_adjustments(&mut invoke_context); let result = invoke_context.process_instruction( instruction_data, &instruction_accounts, diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index cfc8b9303065a4..a2a4fb465ea39f 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -1725,10 +1725,9 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - None, - None, expected_result, super::process_instruction, + |_invoke_context| {}, ) } @@ -2011,12 +2010,10 @@ mod tests { &[], vec![(program_id, program_account.clone())], Vec::new(), - None, - None, Err(InstructionError::ProgramFailedToComplete), - |invoke_context: &mut InvokeContext| { + super::process_instruction, + |invoke_context| { invoke_context.mock_set_remaining(0); - super::process_instruction(invoke_context) }, ); @@ -2557,10 +2554,9 @@ mod tests { &instruction_data, transaction_accounts, instruction_accounts, - None, - None, expected_result, super::process_instruction, + |_invoke_context| {}, ) } diff --git a/programs/bpf_loader/src/syscalls/mod.rs b/programs/bpf_loader/src/syscalls/mod.rs index aa5bcb835f46b2..bdeef057c3764d 100644 --- a/programs/bpf_loader/src/syscalls/mod.rs +++ b/programs/bpf_loader/src/syscalls/mod.rs @@ -1820,14 +1820,14 @@ mod tests { vm::{BuiltInFunction, Config}, }, solana_sdk::{ - account::AccountSharedData, + account::{create_account_shared_data_for_test, AccountSharedData}, bpf_loader, fee_calculator::FeeCalculator, hash::hashv, instruction::Instruction, program::check_type_assumptions, stable_layout::stable_instruction::StableInstruction, - sysvar::{clock::Clock, epoch_schedule::EpochSchedule}, + sysvar::{self, clock::Clock, epoch_schedule::EpochSchedule}, }, std::{mem, str::FromStr}, }; @@ -3299,8 +3299,25 @@ mod tests { sysvar_cache.set_fees(src_fees.clone()); sysvar_cache.set_rent(src_rent); - prepare_mockup!(invoke_context, program_id, bpf_loader::id()); - invoke_context.sysvar_cache = &sysvar_cache; + let transaction_accounts = vec![ + ( + sysvar::clock::id(), + create_account_shared_data_for_test(&src_clock), + ), + ( + sysvar::epoch_schedule::id(), + create_account_shared_data_for_test(&src_epochschedule), + ), + ( + sysvar::fees::id(), + create_account_shared_data_for_test(&src_fees), + ), + ( + sysvar::rent::id(), + create_account_shared_data_for_test(&src_rent), + ), + ]; + with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts); // Test clock sysvar { diff --git a/programs/config/src/config_processor.rs b/programs/config/src/config_processor.rs index 0c15896701fe01..3550d03f645f57 100644 --- a/programs/config/src/config_processor.rs +++ b/programs/config/src/config_processor.rs @@ -170,10 +170,9 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - None, - None, expected_result, super::process_instruction, + |_invoke_context| {}, ) } diff --git a/programs/loader-v3/src/lib.rs b/programs/loader-v3/src/lib.rs index 81eee362a3d608..474454c1af4b0a 100644 --- a/programs/loader-v3/src/lib.rs +++ b/programs/loader-v3/src/lib.rs @@ -642,10 +642,9 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - None, - None, expected_result, super::process_instruction, + |_invoke_context| {}, ) } diff --git a/programs/sbf/tests/programs.rs b/programs/sbf/tests/programs.rs index 95192ba9108b02..007cbde7bb2b84 100644 --- a/programs/sbf/tests/programs.rs +++ b/programs/sbf/tests/programs.rs @@ -1433,8 +1433,6 @@ fn assert_instruction_count() { &[], transaction_accounts, instruction_accounts, - None, - None, Ok(()), |invoke_context: &mut InvokeContext| { let expected_consumption: u64 = invoke_context @@ -1458,6 +1456,7 @@ fn assert_instruction_count() { assert_eq!(consumption, expected_consumption); Ok(()) }, + |_invoke_context| {}, ); } } diff --git a/programs/stake/src/stake_instruction.rs b/programs/stake/src/stake_instruction.rs index a99407f73c137e..8b681ec6e51856 100644 --- a/programs/stake/src/stake_instruction.rs +++ b/programs/stake/src/stake_instruction.rs @@ -518,6 +518,7 @@ mod tests { }, stake_history::{StakeHistory, StakeHistoryEntry}, system_program, sysvar, + sysvar::{clock, rent, stake_history}, }, solana_vote_program::vote_state::{self, VoteState, VoteStateVersions}, std::{ @@ -530,22 +531,26 @@ mod tests { }; /// The "new" behavior enables all features - fn feature_set_new_behavior() -> FeatureSet { - FeatureSet::all_enabled() + fn feature_set_new_behavior() -> Arc { + Arc::new(FeatureSet::all_enabled()) } /// The "old" behavior is before the stake minimum delegation was raised - fn feature_set_old_behavior() -> FeatureSet { + fn feature_set_old_behavior() -> Arc { let mut feature_set = feature_set_new_behavior(); - feature_set.deactivate(&feature_set::stake_raise_minimum_delegation_to_1_sol::id()); + Arc::get_mut(&mut feature_set) + .unwrap() + .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 { + fn feature_set_old_old_behavior() -> Arc { let mut feature_set = feature_set_old_behavior(); - feature_set.deactivate(&feature_set::stake_allow_zero_undelegated_amount::id()); + Arc::get_mut(&mut feature_set) + .unwrap() + .deactivate(&feature_set::stake_allow_zero_undelegated_amount::id()); feature_set } @@ -574,29 +579,11 @@ mod tests { } fn process_instruction( - feature_set: &FeatureSet, + feature_set: Arc, instruction_data: &[u8], transaction_accounts: Vec<(Pubkey, AccountSharedData)>, instruction_accounts: Vec, expected_result: Result<(), InstructionError>, - ) -> Vec { - process_instruction_with_overrides( - instruction_data, - transaction_accounts, - instruction_accounts, - None, - Some(Arc::new(feature_set.clone())), - expected_result, - ) - } - - fn process_instruction_with_overrides( - instruction_data: &[u8], - transaction_accounts: Vec<(Pubkey, AccountSharedData)>, - instruction_accounts: Vec, - sysvar_cache_override: Option<&SysvarCache>, - feature_set_override: Option>, - expected_result: Result<(), InstructionError>, ) -> Vec { mock_process_instruction( &id(), @@ -604,15 +591,16 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - sysvar_cache_override, - feature_set_override, expected_result, super::process_instruction, + |invoke_context| { + invoke_context.feature_set = Arc::clone(&feature_set); + }, ) } fn process_instruction_as_one_arg( - feature_set: &FeatureSet, + feature_set: Arc, instruction: &Instruction, expected_result: Result<(), InstructionError>, ) -> Vec { @@ -654,7 +642,7 @@ mod tests { }) .collect(); process_instruction( - feature_set, + Arc::clone(&feature_set), &instruction.data, transaction_accounts, instruction.accounts.clone(), @@ -677,9 +665,9 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_stake_process_instruction(feature_set: FeatureSet) { + fn test_stake_process_instruction(feature_set: Arc) { process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::initialize( &Pubkey::new_unique(), &Authorized::default(), @@ -688,7 +676,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::authorize( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -699,7 +687,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::split( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -709,7 +697,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::merge( &Pubkey::new_unique(), &invalid_stake_state_pubkey(), @@ -718,7 +706,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::split_with_seed( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -730,7 +718,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::delegate_stake( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -739,7 +727,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::withdraw( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -750,12 +738,12 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::deactivate_stake(&Pubkey::new_unique(), &Pubkey::new_unique()), Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::set_lockup( &Pubkey::new_unique(), &LockupArgs::default(), @@ -764,7 +752,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::deactivate_delinquent_stake( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -773,7 +761,7 @@ mod tests { Err(InstructionError::IncorrectProgramId), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::deactivate_delinquent_stake( &Pubkey::new_unique(), &invalid_vote_state_pubkey(), @@ -782,7 +770,7 @@ mod tests { Err(InstructionError::InvalidAccountData), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::deactivate_delinquent_stake( &Pubkey::new_unique(), &invalid_vote_state_pubkey(), @@ -794,9 +782,9 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_spoofed_stake_accounts(feature_set: FeatureSet) { + fn test_spoofed_stake_accounts(feature_set: Arc) { process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::initialize( &spoofed_stake_state_pubkey(), &Authorized::default(), @@ -805,7 +793,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::authorize( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -816,7 +804,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::split( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -826,7 +814,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::split( &Pubkey::new_unique(), &Pubkey::new_unique(), @@ -836,7 +824,7 @@ mod tests { Err(InstructionError::IncorrectProgramId), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::merge( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -845,7 +833,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::merge( &Pubkey::new_unique(), &spoofed_stake_state_pubkey(), @@ -854,7 +842,7 @@ mod tests { Err(InstructionError::IncorrectProgramId), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::split_with_seed( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -866,7 +854,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::delegate_stake( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -875,7 +863,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::withdraw( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -886,12 +874,12 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::deactivate_stake(&spoofed_stake_state_pubkey(), &Pubkey::new_unique()), Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::set_lockup( &spoofed_stake_state_pubkey(), &LockupArgs::default(), @@ -900,7 +888,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::deactivate_delinquent_stake( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -909,7 +897,7 @@ mod tests { Err(InstructionError::InvalidAccountOwner), ); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction::redelegate( &spoofed_stake_state_pubkey(), &Pubkey::new_unique(), @@ -922,7 +910,7 @@ mod tests { #[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) { + fn test_stake_process_instruction_decode_bail(feature_set: Arc) { // these will not call stake_state, have bogus contents let stake_address = Pubkey::new_unique(); let stake_account = create_default_stake_account(); @@ -948,7 +936,7 @@ mod tests { // gets the "is_empty()" check process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default(), @@ -961,7 +949,7 @@ mod tests { // no account for rent process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default(), @@ -978,7 +966,7 @@ mod tests { // fails to deserialize stake state process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Initialize( Authorized::default(), Lockup::default(), @@ -1005,7 +993,7 @@ mod tests { // gets the first check in delegate, wrong number of accounts process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), vec![(stake_address, stake_account.clone())], vec![AccountMeta { @@ -1018,7 +1006,7 @@ mod tests { // gets the sub-check for number of args process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), vec![(stake_address, stake_account.clone())], vec![AccountMeta { @@ -1031,7 +1019,7 @@ mod tests { // gets the check non-deserialize-able account in delegate_stake process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), vec![ (stake_address, stake_account.clone()), @@ -1072,7 +1060,7 @@ mod tests { // Tests 3rd keyed account is of correct type (Clock instead of rewards) in withdraw process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(withdrawal_amount)).unwrap(), vec![ (stake_address, stake_account.clone()), @@ -1107,7 +1095,7 @@ mod tests { // Tests correct number of accounts are provided in withdraw process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(withdrawal_amount)).unwrap(), vec![(stake_address, stake_account.clone())], vec![AccountMeta { @@ -1120,7 +1108,7 @@ mod tests { // Tests 2nd keyed account is of correct type (Clock instead of rewards) in deactivate process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), vec![ (stake_address, stake_account.clone()), @@ -1143,7 +1131,7 @@ mod tests { // Tests correct number of accounts are provided in deactivate process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), Vec::new(), Vec::new(), @@ -1152,14 +1140,14 @@ mod tests { // Tests correct number of accounts are provided in deactivate_delinquent process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DeactivateDelinquent).unwrap(), Vec::new(), Vec::new(), Err(InstructionError::NotEnoughAccountKeys), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DeactivateDelinquent).unwrap(), vec![(stake_address, stake_account.clone())], vec![AccountMeta { @@ -1170,7 +1158,7 @@ mod tests { Err(InstructionError::NotEnoughAccountKeys), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DeactivateDelinquent).unwrap(), vec![(stake_address, stake_account), (vote_address, vote_account)], vec![ @@ -1191,7 +1179,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_stake_checked_instructions(feature_set: FeatureSet) { + fn test_stake_checked_instructions(feature_set: Arc) { let stake_address = Pubkey::new_unique(); let staker = Pubkey::new_unique(); let staker_account = create_default_account(); @@ -1215,7 +1203,7 @@ mod tests { initialize_checked(&stake_address, &Authorized { staker, withdrawer }); instruction.accounts[3] = AccountMeta::new_readonly(withdrawer, false); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction, Err(InstructionError::MissingRequiredSignature), ); @@ -1227,7 +1215,7 @@ mod tests { &id(), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::InitializeChecked).unwrap(), vec![ (stake_address, stake_account), @@ -1270,7 +1258,7 @@ mod tests { ); instruction.accounts[3] = AccountMeta::new_readonly(staker, false); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction, Err(InstructionError::MissingRequiredSignature), ); @@ -1284,7 +1272,7 @@ mod tests { ); instruction.accounts[3] = AccountMeta::new_readonly(withdrawer, false); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction, Err(InstructionError::MissingRequiredSignature), ); @@ -1298,7 +1286,7 @@ mod tests { ) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::AuthorizeChecked(StakeAuthorize::Staker)).unwrap(), vec![ (stake_address, stake_account.clone()), @@ -1332,7 +1320,7 @@ mod tests { ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::AuthorizeChecked( StakeAuthorize::Withdrawer, )) @@ -1384,7 +1372,7 @@ mod tests { ); instruction.accounts[3] = AccountMeta::new_readonly(staker, false); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction, Err(InstructionError::MissingRequiredSignature), ); @@ -1400,7 +1388,7 @@ mod tests { ); instruction.accounts[3] = AccountMeta::new_readonly(staker, false); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction, Err(InstructionError::MissingRequiredSignature), ); @@ -1414,7 +1402,7 @@ mod tests { ) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::AuthorizeCheckedWithSeed( AuthorizeCheckedWithSeedArgs { stake_authorize: StakeAuthorize::Staker, @@ -1455,7 +1443,7 @@ mod tests { ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::AuthorizeCheckedWithSeed( AuthorizeCheckedWithSeedArgs { stake_authorize: StakeAuthorize::Withdrawer, @@ -1507,7 +1495,7 @@ mod tests { ); instruction.accounts[2] = AccountMeta::new_readonly(custodian, false); process_instruction_as_one_arg( - &feature_set, + Arc::clone(&feature_set), &instruction, Err(InstructionError::MissingRequiredSignature), ); @@ -1522,7 +1510,7 @@ mod tests { .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction.data, vec![ (clock_address, clock_account), @@ -1553,7 +1541,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_stake_initialize(feature_set: FeatureSet) { + fn test_stake_initialize(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let stake_lamports = rent_exempt_reserve; @@ -1592,7 +1580,7 @@ mod tests { // should pass let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -1611,7 +1599,7 @@ mod tests { // 2nd time fails, can't move it from anything other than uninit->init transaction_accounts[0] = (stake_address, accounts[0].clone()); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -1628,7 +1616,7 @@ mod tests { }), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -1640,7 +1628,7 @@ mod tests { AccountSharedData::new(stake_lamports, StakeState::size_of() + 1, &id()); transaction_accounts[0] = (stake_address, stake_account); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -1651,7 +1639,7 @@ mod tests { AccountSharedData::new(stake_lamports, StakeState::size_of() - 1, &id()); transaction_accounts[0] = (stake_address, stake_account); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts, instruction_accounts, @@ -1661,7 +1649,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_authorize(feature_set: FeatureSet) { + fn test_authorize(feature_set: Arc) { 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(); @@ -1708,7 +1696,7 @@ mod tests { // should fail, uninit process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Staker, @@ -1729,7 +1717,7 @@ mod tests { .unwrap(); transaction_accounts[0] = (stake_address, stake_account); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Staker, @@ -1741,7 +1729,7 @@ mod tests { ); transaction_accounts[0] = (stake_address, accounts[0].clone()); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Withdrawer, @@ -1761,7 +1749,7 @@ mod tests { // A second authorization signed by the stake account should fail process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address_2, StakeAuthorize::Staker, @@ -1776,7 +1764,7 @@ mod tests { instruction_accounts[0].is_signer = false; instruction_accounts[2].is_signer = true; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address_2, StakeAuthorize::Staker, @@ -1821,7 +1809,7 @@ mod tests { }, ]; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -1832,7 +1820,7 @@ mod tests { // Test that withdrawal to account fails without authorized withdrawer instruction_accounts[4].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts, @@ -1842,7 +1830,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_authorize_override(feature_set: FeatureSet) { + fn test_authorize_override(feature_set: Arc) { let authority_address = solana_sdk::pubkey::new_rand(); let mallory_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand(); @@ -1882,7 +1870,7 @@ mod tests { // Authorize a staker pubkey and move the withdrawer key into cold storage. let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Staker, @@ -1898,7 +1886,7 @@ mod tests { instruction_accounts[0].is_signer = false; instruction_accounts[2].is_signer = true; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( mallory_address, StakeAuthorize::Staker, @@ -1912,7 +1900,7 @@ mod tests { // Verify the original staker no longer has access. process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Staker, @@ -1927,7 +1915,7 @@ mod tests { instruction_accounts[0].is_signer = true; instruction_accounts[2].is_signer = false; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Withdrawer, @@ -1947,7 +1935,7 @@ mod tests { is_writable: false, }; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Withdrawer, @@ -1961,7 +1949,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_authorize_with_seed(feature_set: FeatureSet) { + fn test_authorize_with_seed(feature_set: Arc) { let authority_base_address = solana_sdk::pubkey::new_rand(); let authority_address = solana_sdk::pubkey::new_rand(); let seed = "42"; @@ -2002,7 +1990,7 @@ mod tests { // Wrong seed process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::AuthorizeWithSeed( AuthorizeWithSeedArgs { new_authorized_pubkey: authority_address, @@ -2029,7 +2017,7 @@ mod tests { )) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -2039,7 +2027,7 @@ mod tests { // Set stake authority let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -2058,7 +2046,7 @@ mod tests { )) .unwrap(); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -2068,7 +2056,7 @@ mod tests { // No longer withdraw authority process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts, instruction_accounts, @@ -2078,7 +2066,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_authorize_delegated_stake(feature_set: FeatureSet) { + fn test_authorize_delegated_stake(feature_set: Arc) { 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); @@ -2148,7 +2136,7 @@ mod tests { // delegate stake let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2158,7 +2146,7 @@ mod tests { // deactivate, so we can re-delegate let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), vec![ @@ -2179,7 +2167,7 @@ mod tests { // authorize let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authority_address, StakeAuthorize::Staker, @@ -2215,7 +2203,7 @@ mod tests { instruction_accounts[0].is_signer = false; instruction_accounts[1].pubkey = vote_address_2; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2229,7 +2217,7 @@ mod tests { is_writable: false, }); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts, @@ -2243,7 +2231,7 @@ mod tests { // Test another staking action process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts, vec![ @@ -2269,7 +2257,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_stake_delegate(feature_set: FeatureSet) { + fn test_stake_delegate(feature_set: Arc) { let mut vote_state = VoteState::default(); for i in 0..1000 { vote_state::process_slot_vote_unchecked(&mut vote_state, i); @@ -2355,7 +2343,7 @@ mod tests { // should fail, unsigned stake account instruction_accounts[0].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2365,7 +2353,7 @@ mod tests { // should pass let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2394,7 +2382,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2403,7 +2391,7 @@ mod tests { // deactivate let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), vec![ @@ -2426,7 +2414,7 @@ mod tests { transaction_accounts[0] = (stake_address, accounts[0].clone()); instruction_accounts[1].pubkey = vote_address_2; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2437,7 +2425,7 @@ mod tests { // verify that delegate succeeds to same vote account // when stake is deactivating let accounts_2 = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2452,7 +2440,7 @@ mod tests { transaction_accounts[0] = (stake_address, accounts_2[0].clone()); instruction_accounts[1].pubkey = vote_address_2; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2469,7 +2457,7 @@ mod tests { // verify that delegate can be called to new vote account, 2nd is redelegate transaction_accounts[0] = (stake_address, accounts[0].clone()); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2497,7 +2485,7 @@ mod tests { .1 .set_owner(solana_sdk::pubkey::new_rand()); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2509,7 +2497,7 @@ mod tests { stake_account.set_state(&stake_state).unwrap(); transaction_accounts[0] = (stake_address, stake_account); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts, instruction_accounts, @@ -2519,7 +2507,7 @@ mod tests { #[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) { + fn test_redelegate_consider_balance_changes(feature_set: Arc) { let mut clock = Clock::default(); let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); @@ -2613,7 +2601,7 @@ mod tests { ]; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), delegate_instruction_accounts.clone(), @@ -2627,7 +2615,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), deactivate_instruction_accounts.clone(), @@ -2643,7 +2631,7 @@ mod tests { ); let withdraw_lamports = initial_lamports / 2; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(withdraw_lamports)).unwrap(), transaction_accounts.clone(), vec![ @@ -2685,7 +2673,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), delegate_instruction_accounts.clone(), @@ -2703,7 +2691,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), deactivate_instruction_accounts, @@ -2723,7 +2711,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts, delegate_instruction_accounts, @@ -2737,7 +2725,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_split(feature_set: FeatureSet) { + fn test_split(feature_set: Arc) { let stake_address = solana_sdk::pubkey::new_rand(); let minimum_delegation = crate::get_minimum_delegation(&feature_set); let stake_lamports = minimum_delegation * 2; @@ -2752,6 +2740,13 @@ mod tests { let mut transaction_accounts = vec![ (stake_address, AccountSharedData::default()), (split_to_address, split_to_account), + ( + rent::id(), + account::create_account_shared_data_for_test(&Rent { + lamports_per_byte_year: 0, + ..Rent::default() + }), + ), ]; let instruction_accounts = vec![ AccountMeta { @@ -2766,13 +2761,6 @@ mod tests { }, ]; - // Define rent here so that it's used consistently for setting the rent exempt reserve - // and in the sysvar cache used for mock instruction processing. - let mut sysvar_cache_override = SysvarCache::default(); - sysvar_cache_override.set_rent(Rent { - lamports_per_byte_year: 0, - ..Rent::default() - }); let feature_set = Arc::new(feature_set); for state in [ @@ -2789,22 +2777,20 @@ mod tests { transaction_accounts[0] = (stake_address, stake_account); // should fail, split more than available - process_instruction_with_overrides( + process_instruction( + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports + 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), - Some(&sysvar_cache_override), - Some(Arc::clone(&feature_set)), Err(InstructionError::InsufficientFunds), ); // should pass - let accounts = process_instruction_with_overrides( + let accounts = process_instruction( + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), - Some(&sysvar_cache_override), - Some(Arc::clone(&feature_set)), Ok(()), ); // no lamport leakage @@ -2835,19 +2821,18 @@ mod tests { ) .unwrap(); transaction_accounts[1] = (split_to_address, split_to_account); - process_instruction_with_overrides( + process_instruction( + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts, instruction_accounts, - Some(&sysvar_cache_override), - Some(Arc::clone(&feature_set)), Err(InstructionError::IncorrectProgramId), ); } #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_withdraw_stake(feature_set: FeatureSet) { + fn test_withdraw_stake(feature_set: Arc) { let recipient_address = solana_sdk::pubkey::new_rand(); let authority_address = solana_sdk::pubkey::new_rand(); let custodian_address = solana_sdk::pubkey::new_rand(); @@ -2924,7 +2909,7 @@ mod tests { // should fail, no signer instruction_accounts[4].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2934,7 +2919,7 @@ mod tests { // should pass, signed keyed account and uninitialized let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2950,7 +2935,7 @@ mod tests { custodian: custodian_address, }; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Initialize( Authorized::auto(&stake_address), lockup, @@ -2975,7 +2960,7 @@ mod tests { // should fail, signed keyed account and locked up, more than available process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports + 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -2984,7 +2969,7 @@ mod tests { // Stake some lamports (available lamports for withdrawals will reduce to zero) let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), vec![ @@ -3023,7 +3008,7 @@ mod tests { // withdrawal before deactivate works for rewards amount process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(10)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3032,7 +3017,7 @@ mod tests { // withdrawal of rewards fails if not in excess of stake process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(11)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3041,7 +3026,7 @@ mod tests { // deactivate the stake before withdrawal let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), vec![ @@ -3072,7 +3057,7 @@ mod tests { // Try to withdraw more than what's available process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports + 11)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3081,7 +3066,7 @@ mod tests { // Try to withdraw all lamports let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports + 10)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3111,7 +3096,7 @@ mod tests { transaction_accounts[2] = (recipient_address, stake_account); instruction_accounts[4].pubkey = authority_address; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(u64::MAX - 10)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3128,7 +3113,7 @@ mod tests { .unwrap(); transaction_accounts[0] = (stake_address, stake_account); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts, @@ -3138,7 +3123,7 @@ mod tests { #[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) { + fn test_withdraw_stake_before_warmup(feature_set: Arc) { 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); @@ -3208,7 +3193,7 @@ mod tests { // Stake some lamports (available lamports for withdrawals will reduce to zero) let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), vec![ @@ -3258,7 +3243,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw( total_lamports - stake_lamports + 1, )) @@ -3271,7 +3256,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_withdraw_lockup(feature_set: FeatureSet) { + fn test_withdraw_lockup(feature_set: Arc) { let recipient_address = solana_sdk::pubkey::new_rand(); let custodian_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand(); @@ -3335,7 +3320,7 @@ mod tests { // should fail, lockup is still in force process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(total_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3349,7 +3334,7 @@ mod tests { is_writable: false, }); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(total_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3369,7 +3354,7 @@ mod tests { .unwrap(); transaction_accounts[0] = (stake_address, stake_account_self_as_custodian); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(total_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3386,7 +3371,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(total_lamports)).unwrap(), transaction_accounts, instruction_accounts, @@ -3397,7 +3382,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_withdraw_rent_exempt(feature_set: FeatureSet) { + fn test_withdraw_rent_exempt(feature_set: Arc) { let recipient_address = solana_sdk::pubkey::new_rand(); let custodian_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand(); @@ -3458,7 +3443,7 @@ mod tests { // should pass, withdrawing initialized account down to minimum balance process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3467,7 +3452,7 @@ mod tests { // should fail, withdrawal that would leave less than rent-exempt reserve process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(stake_lamports + 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3476,7 +3461,7 @@ mod tests { // should pass, withdrawal of complete account process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw( stake_lamports + rent_exempt_reserve, )) @@ -3489,7 +3474,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_deactivate(feature_set: FeatureSet) { + fn test_deactivate(feature_set: Arc) { let stake_address = solana_sdk::pubkey::new_rand(); let minimum_delegation = crate::get_minimum_delegation(&feature_set); let stake_lamports = minimum_delegation; @@ -3538,7 +3523,7 @@ mod tests { // should fail, not signed instruction_accounts[0].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3548,7 +3533,7 @@ mod tests { // should fail, not staked yet process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3557,7 +3542,7 @@ mod tests { // Staking let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), vec![ @@ -3593,7 +3578,7 @@ mod tests { // should pass let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -3603,7 +3588,7 @@ mod tests { // should fail, only works once process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts, instruction_accounts, @@ -3613,7 +3598,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_set_lockup(feature_set: FeatureSet) { + fn test_set_lockup(feature_set: Arc) { let custodian_address = solana_sdk::pubkey::new_rand(); let authorized_address = solana_sdk::pubkey::new_rand(); let stake_address = solana_sdk::pubkey::new_rand(); @@ -3680,7 +3665,7 @@ mod tests { // should fail, wrong state process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3694,7 +3679,7 @@ mod tests { custodian: custodian_address, }; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Initialize( Authorized::auto(&stake_address), lockup, @@ -3720,7 +3705,7 @@ mod tests { // should fail, not signed instruction_accounts[2].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3730,7 +3715,7 @@ mod tests { // should pass process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3739,7 +3724,7 @@ mod tests { // Staking let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), vec![ @@ -3776,7 +3761,7 @@ mod tests { // should fail, not signed instruction_accounts[2].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3786,7 +3771,7 @@ mod tests { // should pass process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3805,7 +3790,7 @@ mod tests { instruction_accounts[0].is_signer = true; instruction_accounts[2].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3816,7 +3801,7 @@ mod tests { // should pass, custodian can change it process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3836,7 +3821,7 @@ mod tests { // should fail, custodian cannot change it process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3847,7 +3832,7 @@ mod tests { instruction_accounts[0].is_signer = true; instruction_accounts[2].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts.clone(), instruction_accounts.clone(), @@ -3856,7 +3841,7 @@ mod tests { // Change authorized withdrawer let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Authorize( authorized_address, StakeAuthorize::Withdrawer, @@ -3886,7 +3871,7 @@ mod tests { // should fail, previous authorized withdrawer cannot change the lockup anymore process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, transaction_accounts, instruction_accounts, @@ -3899,7 +3884,7 @@ mod tests { /// - Assert 2: accounts with a balance less-than the rent exemption do not initialize #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_initialize_minimum_balance(feature_set: FeatureSet) { + fn test_initialize_minimum_balance(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let stake_address = solana_sdk::pubkey::new_rand(); @@ -3929,7 +3914,7 @@ mod tests { ] { let stake_account = AccountSharedData::new(lamports, StakeState::size_of(), &id()); process_instruction( - &feature_set, + Arc::clone(&feature_set), &instruction_data, vec![ (stake_address, stake_account), @@ -3957,7 +3942,7 @@ mod tests { /// more information.) #[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) { + fn test_delegate_minimum_stake_delegation(feature_set: Arc) { let minimum_delegation = crate::get_minimum_delegation(&feature_set); let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); @@ -4015,7 +4000,7 @@ mod tests { ) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), vec![ (stake_address, stake_account), @@ -4052,7 +4037,7 @@ mod tests { /// LT | LT | Err #[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) { + fn test_split_minimum_stake_delegation(feature_set: Arc) { let minimum_delegation = crate::get_minimum_delegation(&feature_set); let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); @@ -4121,7 +4106,7 @@ mod tests { ) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(dest_reserve + delegation)).unwrap(), vec![ (source_address, source_account), @@ -4147,7 +4132,7 @@ mod tests { /// delegation is not OK #[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) { + fn test_split_full_amount_minimum_stake_delegation(feature_set: Arc) { let minimum_delegation = crate::get_minimum_delegation(&feature_set); let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); @@ -4198,7 +4183,7 @@ mod tests { ) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(source_account.lamports())).unwrap(), vec![ (source_address, source_account), @@ -4220,7 +4205,7 @@ mod tests { /// the minimum split amount reduces accordingly. #[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) { + fn test_initialized_split_destination_minimum_balance(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let source_address = Pubkey::new_unique(); @@ -4296,7 +4281,7 @@ mod tests { .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(split_amount)).unwrap(), vec![ (source_address, source_account), @@ -4318,7 +4303,7 @@ mod tests { #[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, + feature_set: Arc, expected_results: &[Result<(), InstructionError>], ) { let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -4427,7 +4412,7 @@ mod tests { ) .unwrap(); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(split_amount)).unwrap(), vec![ (source_address, source_account.clone()), @@ -4470,7 +4455,7 @@ mod tests { /// - Assert 2: withdrawing so remaining stake is less-than the minimum is not OK #[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) { + fn test_withdraw_minimum_stake_delegation(feature_set: Arc) { let minimum_delegation = crate::get_minimum_delegation(&feature_set); let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); @@ -4530,7 +4515,7 @@ mod tests { let withdraw_amount = (starting_stake_delegation + rewards_balance) - ending_stake_delegation; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(withdraw_amount)).unwrap(), vec![ (stake_address, stake_account), @@ -4581,7 +4566,7 @@ mod tests { #[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, + feature_set: Arc, expected_result: Result<(), InstructionError>, ) { let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -4651,7 +4636,7 @@ mod tests { ]; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Initialize( Authorized::auto(&stake_address), Lockup::default(), @@ -4675,7 +4660,7 @@ mod tests { transaction_accounts[0] = (stake_address, accounts[0].clone()); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -4690,7 +4675,7 @@ mod tests { account::create_account_shared_data_for_test(&clock), ); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Deactivate).unwrap(), transaction_accounts.clone(), vec![ @@ -4717,7 +4702,7 @@ mod tests { let withdraw_amount = accounts[0].lamports() - (rent_exempt_reserve + minimum_delegation - 1); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Withdraw(withdraw_amount)).unwrap(), transaction_accounts.clone(), vec![ @@ -4752,7 +4737,7 @@ mod tests { transaction_accounts[0] = (stake_address, accounts[0].clone()); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), transaction_accounts, instruction_accounts, @@ -4762,7 +4747,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_split_source_uninitialized(feature_set: FeatureSet) { + fn test_split_source_uninitialized(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -4809,28 +4794,28 @@ mod tests { // // and splitting should fail when the split amount is greater than the balance process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), Ok(()), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(0)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), Ok(()), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), Ok(()), ); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports + 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -4841,7 +4826,7 @@ mod tests { // this should work instruction_accounts[1].pubkey = split_to_address; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -4852,7 +4837,7 @@ mod tests { // no signers should fail instruction_accounts[0].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts, instruction_accounts, @@ -4862,7 +4847,7 @@ mod tests { #[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) { + fn test_split_split_not_uninitialized(feature_set: Arc) { let stake_lamports = 42; let stake_address = solana_sdk::pubkey::new_rand(); let stake_account = AccountSharedData::new_data_with_space( @@ -4899,7 +4884,7 @@ mod tests { ) .unwrap(); process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), vec![ (stake_address, stake_account.clone()), @@ -4913,7 +4898,7 @@ mod tests { #[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) { + fn test_split_more_than_staked(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -4962,7 +4947,7 @@ mod tests { ]; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts, instruction_accounts, @@ -4972,7 +4957,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_split_with_rent(feature_set: FeatureSet) { + fn test_split_with_rent(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -5030,7 +5015,7 @@ mod tests { // not enough to make a non-zero stake account process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(minimum_balance - 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -5039,7 +5024,7 @@ mod tests { // doesn't leave enough for initial stake to be non-zero process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split( stake_lamports - minimum_balance + 1, )) @@ -5052,7 +5037,7 @@ mod tests { // split account already has way enough lamports transaction_accounts[1].1.set_lamports(*minimum_balance); let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports - minimum_balance)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5082,7 +5067,7 @@ mod tests { #[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) { + fn test_split_to_account_with_rent_exempt_reserve(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -5144,7 +5129,7 @@ mod tests { // split more than available fails process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports + 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -5153,7 +5138,7 @@ mod tests { // should work let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5207,7 +5192,7 @@ mod tests { #[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) { + fn test_split_from_larger_sized_account(feature_set: Arc) { 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()); @@ -5270,7 +5255,7 @@ mod tests { // split more than available fails process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports + 1)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -5279,7 +5264,7 @@ mod tests { // should work let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports / 2)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -5338,7 +5323,7 @@ mod tests { #[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) { + fn test_split_from_smaller_sized_account(feature_set: Arc) { 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); @@ -5397,7 +5382,7 @@ mod tests { // should always return error when splitting to larger account process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(split_amount)).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -5406,7 +5391,7 @@ mod tests { // Splitting 100% of source should not make a difference process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5417,7 +5402,7 @@ mod tests { #[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) { + fn test_split_100_percent_of_source(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -5472,7 +5457,7 @@ mod tests { // split 100% over to dest let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5513,7 +5498,7 @@ mod tests { #[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) { + fn test_split_100_percent_of_source_to_account_with_lamports(feature_set: Arc) { let rent = Rent::default(); let rent_exempt_reserve = rent.minimum_balance(StakeState::size_of()); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -5575,7 +5560,7 @@ mod tests { // split 100% over to dest let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5609,7 +5594,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_split_rent_exemptness(feature_set: FeatureSet) { + fn test_split_rent_exemptness(feature_set: Arc) { 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()); @@ -5663,7 +5648,7 @@ mod tests { ), ]; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5695,7 +5680,7 @@ mod tests { ), ]; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Split(stake_lamports)).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5747,7 +5732,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_merge(feature_set: FeatureSet) { + fn test_merge(feature_set: Arc) { 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(); @@ -5820,7 +5805,7 @@ mod tests { // Authorized staker signature required... instruction_accounts[4].is_signer = false; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -5829,7 +5814,7 @@ mod tests { instruction_accounts[4].is_signer = true; let accounts = process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -5877,7 +5862,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_merge_self_fails(feature_set: FeatureSet) { + fn test_merge_self_fails(feature_set: Arc) { let stake_address = solana_sdk::pubkey::new_rand(); let authorized_address = solana_sdk::pubkey::new_rand(); let rent = Rent::default(); @@ -5944,7 +5929,7 @@ mod tests { ]; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts, instruction_accounts, @@ -5954,7 +5939,7 @@ mod tests { #[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) { + fn test_merge_incorrect_authorized_staker(feature_set: Arc) { 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(); @@ -6027,7 +6012,7 @@ mod tests { instruction_accounts[4].pubkey = wrong_authorized_address; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -6036,7 +6021,7 @@ mod tests { instruction_accounts[4].pubkey = authorized_address; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -6048,7 +6033,7 @@ mod tests { #[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) { + fn test_merge_invalid_account_data(feature_set: Arc) { 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(); @@ -6117,7 +6102,7 @@ mod tests { ]; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts, instruction_accounts.clone(), @@ -6129,7 +6114,7 @@ mod tests { #[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) { + fn test_merge_fake_stake_source(feature_set: Arc) { 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(); @@ -6190,7 +6175,7 @@ mod tests { ]; process_instruction( - &feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts, instruction_accounts, @@ -6200,7 +6185,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_merge_active_stake(feature_set: FeatureSet) { + fn test_merge_active_stake(feature_set: Arc) { 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(); @@ -6301,7 +6286,7 @@ mod tests { ]; fn try_merge( - feature_set: &FeatureSet, + feature_set: Arc, transaction_accounts: Vec<(Pubkey, AccountSharedData)>, mut instruction_accounts: Vec, expected_result: Result<(), InstructionError>, @@ -6311,7 +6296,7 @@ mod tests { instruction_accounts.swap(0, 1); } let accounts = process_instruction( - feature_set, + Arc::clone(&feature_set), &serialize(&StakeInstruction::Merge).unwrap(), transaction_accounts.clone(), instruction_accounts.clone(), @@ -6328,7 +6313,7 @@ mod tests { // stake activation epoch, source initialized succeeds try_merge( - &feature_set, + Arc::clone(&feature_set), transaction_accounts.clone(), instruction_accounts.clone(), Ok(()), @@ -6366,7 +6351,7 @@ mod tests { break; } try_merge( - &feature_set, + Arc::clone(&feature_set), transaction_accounts.clone(), instruction_accounts.clone(), Err(InstructionError::from(StakeError::MergeTransientStake)), @@ -6375,7 +6360,7 @@ mod tests { // Both fully activated works try_merge( - &feature_set, + Arc::clone(&feature_set), transaction_accounts.clone(), instruction_accounts.clone(), Ok(()), @@ -6442,7 +6427,7 @@ mod tests { break; } try_merge( - &feature_set, + Arc::clone(&feature_set), transaction_accounts.clone(), instruction_accounts.clone(), Err(InstructionError::from(StakeError::MergeTransientStake)), @@ -6451,7 +6436,7 @@ mod tests { // Both fully deactivated works try_merge( - &feature_set, + Arc::clone(&feature_set), transaction_accounts, instruction_accounts, Ok(()), @@ -6460,7 +6445,7 @@ mod tests { #[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) { + fn test_stake_get_minimum_delegation(feature_set: Arc) { let stake_address = Pubkey::new_unique(); let stake_account = create_default_stake_account(); let instruction_data = serialize(&StakeInstruction::GetMinimumDelegation).unwrap(); @@ -6477,8 +6462,6 @@ mod tests { &instruction_data, transaction_accounts, instruction_accounts, - None, - Some(Arc::new(feature_set)), Ok(()), |invoke_context| { super::process_instruction(invoke_context)?; @@ -6489,6 +6472,9 @@ mod tests { assert_eq!(expected_minimum_delegation, actual_minimum_delegation); Ok(()) }, + |invoke_context| { + invoke_context.feature_set = Arc::clone(&feature_set); + }, ); } @@ -6515,7 +6501,7 @@ mod tests { // disabled | bad | none || Err NotEnoughAccountKeys #[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) { + fn test_stake_process_instruction_error_ordering(feature_set: Arc) { let rent = Rent::default(); let rent_address = sysvar::rent::id(); let rent_account = account::create_account_shared_data_for_test(&rent); @@ -6598,33 +6584,26 @@ mod tests { Err(InstructionError::NotEnoughAccountKeys), ), ] { - let mut feature_set = feature_set.clone(); + let mut feature_set = Arc::new(FeatureSet::clone(&feature_set)); if !is_feature_enabled { - feature_set.deactivate( + Arc::get_mut(&mut feature_set).unwrap().deactivate( &feature_set::add_get_minimum_delegation_instruction_to_stake_program::id(), ); } - mock_process_instruction( - &id(), - Vec::new(), + process_instruction( + feature_set, &instruction.data, transaction_accounts.clone(), instruction_accounts.clone(), - None, - Some(Arc::new(feature_set)), expected_result, - super::process_instruction, ); } } #[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(); - + fn test_deactivate_delinquent(feature_set: Arc) { let reference_vote_address = Pubkey::new_unique(); let vote_address = Pubkey::new_unique(); let stake_address = Pubkey::new_unique(); @@ -6666,23 +6645,26 @@ mod tests { let current_epoch = 20; - sysvar_cache_override.set_clock(Clock { - epoch: current_epoch, - ..Clock::default() - }); - let process_instruction_deactivate_delinquent = |stake_address: &Pubkey, stake_account: &AccountSharedData, vote_account: &AccountSharedData, reference_vote_account: &AccountSharedData, expected_result| { - process_instruction_with_overrides( + process_instruction( + Arc::clone(&feature_set), &serialize(&StakeInstruction::DeactivateDelinquent).unwrap(), vec![ (*stake_address, stake_account.clone()), (vote_address, vote_account.clone()), (reference_vote_address, reference_vote_account.clone()), + ( + clock::id(), + account::create_account_shared_data_for_test(&Clock { + epoch: current_epoch, + ..Clock::default() + }), + ), ], vec![ AccountMeta { @@ -6701,8 +6683,6 @@ mod tests { is_writable: false, }, ], - Some(&sysvar_cache_override), - Some(Arc::clone(&feature_set)), expected_result, ) }; @@ -6891,7 +6871,7 @@ mod tests { #[test_case(feature_set_old_behavior(); "old_behavior")] #[test_case(feature_set_new_behavior(); "new_behavior")] - fn test_redelegate(feature_set: FeatureSet) { + fn test_redelegate(feature_set: Arc) { let feature_set = Arc::new(feature_set); let minimum_delegation = crate::get_minimum_delegation(&feature_set); @@ -6970,7 +6950,8 @@ mod tests { uninitialized_stake_address: &Pubkey, uninitialized_stake_account: &AccountSharedData, expected_result| { - process_instruction_with_overrides( + process_instruction( + Arc::clone(&feature_set), &serialize(&StakeInstruction::Redelegate).unwrap(), vec![ (*stake_address, stake_account.clone()), @@ -6979,11 +6960,26 @@ mod tests { uninitialized_stake_account.clone(), ), (*vote_address, vote_account.clone()), + (*authorized_staker, AccountSharedData::default()), ( stake_config::id(), config::create_account(0, &stake_config::Config::default()), ), - (*authorized_staker, AccountSharedData::default()), + ( + stake_history::id(), + account::create_account_shared_data_for_test(&stake_history), + ), + ( + rent::id(), + account::create_account_shared_data_for_test(&rent), + ), + ( + clock::id(), + account::create_account_shared_data_for_test(&Clock { + epoch: current_epoch, + ..Clock::default() + }), + ), ], vec![ AccountMeta { @@ -7012,8 +7008,6 @@ mod tests { is_writable: false, }, ], - Some(&sysvar_cache_override), - Some(Arc::clone(&feature_set)), expected_result, ) }; @@ -7132,24 +7126,32 @@ mod tests { ), ]; for (deactivated_stake_account, expected_result) in deactivated_stake_accounts { - let _ = process_instruction_with_overrides( + process_instruction( + Arc::clone(&feature_set), &serialize(&StakeInstruction::DelegateStake).unwrap(), vec![ (stake_address, deactivated_stake_account), (vote_address, new_vote_account.clone()), + (authorized_staker, AccountSharedData::default()), ( - sysvar::clock::id(), - account::create_account_shared_data_for_test(&Clock::default()), + stake_config::id(), + config::create_account(0, &stake_config::Config::default()), ), ( - sysvar::stake_history::id(), - account::create_account_shared_data_for_test(&StakeHistory::default()), + stake_history::id(), + account::create_account_shared_data_for_test(&stake_history), ), ( - stake_config::id(), - config::create_account(0, &stake_config::Config::default()), + rent::id(), + account::create_account_shared_data_for_test(&rent), + ), + ( + clock::id(), + account::create_account_shared_data_for_test(&Clock { + epoch: current_epoch, + ..Clock::default() + }), ), - (authorized_staker, AccountSharedData::default()), ], vec![ AccountMeta { @@ -7183,8 +7185,6 @@ mod tests { is_writable: false, }, ], - Some(&sysvar_cache_override), - Some(Arc::clone(&feature_set)), expected_result, ); } diff --git a/programs/vote/src/vote_processor.rs b/programs/vote/src/vote_processor.rs index 159eb8ac00fd6c..bcc3fb879d0947 100644 --- a/programs/vote/src/vote_processor.rs +++ b/programs/vote/src/vote_processor.rs @@ -326,10 +326,9 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - None, - None, expected_result, super::process_instruction, + |_invoke_context| {}, ) } @@ -345,10 +344,11 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - None, - Some(std::sync::Arc::new(FeatureSet::default())), expected_result, super::process_instruction, + |invoke_context| { + invoke_context.feature_set = std::sync::Arc::new(FeatureSet::default()); + }, ) } diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index 8d21a4d7bc30f4..f48638ea754ea0 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -8050,10 +8050,9 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() { (program_keypair.pubkey(), post_program_account), ], Vec::new(), - None, - None, Ok(()), solana_bpf_loader_program::process_instruction, + |_invoke_context| {}, ); // Test initialized program account diff --git a/runtime/src/system_instruction_processor.rs b/runtime/src/system_instruction_processor.rs index a50915df80a00f..058e91524066ec 100644 --- a/runtime/src/system_instruction_processor.rs +++ b/runtime/src/system_instruction_processor.rs @@ -646,10 +646,9 @@ mod tests { instruction_data, transaction_accounts, instruction_accounts, - None, - None, expected_result, process_instruction, + |_invoke_context| {}, ) }