22 crate :: {
33 compute_budget:: ComputeBudget ,
44 ic_msg,
5- loaded_programs:: { LoadedProgram , LoadedProgramType , LoadedProgramsForTxBatch } ,
5+ loaded_programs:: {
6+ LoadedProgram , LoadedProgramType , LoadedProgramsForTxBatch , ProgramRuntimeEnvironments ,
7+ } ,
68 log_collector:: LogCollector ,
79 stable_log,
810 sysvar_cache:: SysvarCache ,
@@ -17,15 +19,18 @@ use {
1719 vm:: { Config , ContextObject , EbpfVm } ,
1820 } ,
1921 solana_sdk:: {
20- account:: AccountSharedData ,
22+ account:: { create_account_shared_data_for_test , AccountSharedData } ,
2123 bpf_loader_deprecated,
24+ clock:: Slot ,
25+ epoch_schedule:: EpochSchedule ,
2226 feature_set:: FeatureSet ,
2327 hash:: Hash ,
2428 instruction:: { AccountMeta , InstructionError } ,
2529 native_loader,
2630 pubkey:: Pubkey ,
2731 saturating_add_assign,
2832 stable_layout:: stable_instruction:: StableInstruction ,
33+ sysvar,
2934 transaction_context:: {
3035 IndexOfAccount , InstructionAccount , TransactionAccount , TransactionContext ,
3136 } ,
@@ -209,6 +214,17 @@ impl<'a> InvokeContext<'a> {
209214 . or_else ( || self . programs_loaded_for_tx_batch . find ( pubkey) )
210215 }
211216
217+ pub fn get_environments_for_slot (
218+ & self ,
219+ effective_slot : Slot ,
220+ ) -> Result < & ProgramRuntimeEnvironments , InstructionError > {
221+ let epoch_schedule = self . sysvar_cache . get_epoch_schedule ( ) ?;
222+ let epoch = epoch_schedule. get_epoch ( effective_slot) ;
223+ Ok ( self
224+ . programs_loaded_for_tx_batch
225+ . get_environments_for_epoch ( epoch) )
226+ }
227+
212228 /// Push a stack frame onto the invocation stack
213229 pub fn push ( & mut self ) -> Result < ( ) , InstructionError > {
214230 let instruction_context = self
@@ -713,6 +729,18 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
713729 program_indices. insert ( 0 , transaction_accounts. len ( ) as IndexOfAccount ) ;
714730 let processor_account = AccountSharedData :: new ( 0 , 0 , & native_loader:: id ( ) ) ;
715731 transaction_accounts. push ( ( * loader_id, processor_account) ) ;
732+ let pop_epoch_schedule_account = if !transaction_accounts
733+ . iter ( )
734+ . any ( |( key, _) | * key == sysvar:: epoch_schedule:: id ( ) )
735+ {
736+ transaction_accounts. push ( (
737+ sysvar:: epoch_schedule:: id ( ) ,
738+ create_account_shared_data_for_test ( & EpochSchedule :: default ( ) ) ,
739+ ) ) ;
740+ true
741+ } else {
742+ false
743+ } ;
716744 with_mock_invoke_context ! ( invoke_context, transaction_context, transaction_accounts) ;
717745 let mut programs_loaded_for_tx_batch = LoadedProgramsForTxBatch :: default ( ) ;
718746 programs_loaded_for_tx_batch. replenish (
@@ -731,6 +759,9 @@ pub fn mock_process_instruction<F: FnMut(&mut InvokeContext), G: FnMut(&mut Invo
731759 assert_eq ! ( result, expected_result) ;
732760 post_adjustments ( & mut invoke_context) ;
733761 let mut transaction_accounts = transaction_context. deconstruct_without_keys ( ) . unwrap ( ) ;
762+ if pop_epoch_schedule_account {
763+ transaction_accounts. pop ( ) ;
764+ }
734765 transaction_accounts. pop ( ) ;
735766 transaction_accounts
736767}
0 commit comments