diff --git a/program-runtime/src/loaded_programs.rs b/program-runtime/src/loaded_programs.rs index 1c29adc8c6c246..88e74b69c54dc6 100644 --- a/program-runtime/src/loaded_programs.rs +++ b/program-runtime/src/loaded_programs.rs @@ -1076,6 +1076,14 @@ impl LoadedPrograms { } } + /// Returns the `slot_versions` of the second level for the given program id. + pub fn get_slot_versions_for_tests(&self, key: &Pubkey) -> &[Arc] { + self.entries + .get(key) + .map(|second_level| second_level.slot_versions.as_ref()) + .unwrap_or(&[]) + } + /// This function removes the given entry for the given program from the cache. /// The function expects that the program and entry exists in the cache. Otherwise it'll panic. fn unload_program_entry(&mut self, program: &Pubkey, remove_entry: &Arc) { diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index f5f9860d6df15a..12e668f40ddee2 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -11935,10 +11935,48 @@ fn test_feature_activation_loaded_programs_recompilation_phase() { // Advance the bank to middle of epoch to start the recompilation phase. goto_end_of_slot(bank.clone()); let bank = new_bank_from_parent_with_bank_forks(&bank_forks, bank, &Pubkey::default(), 16); + let current_env = bank + .loaded_programs_cache + .read() + .unwrap() + .get_environments_for_epoch(0) + .program_runtime_v1 + .clone(); + let upcoming_env = bank + .loaded_programs_cache + .read() + .unwrap() + .get_environments_for_epoch(1) + .program_runtime_v1 + .clone(); // Advance the bank to recompile the program. + { + let loaded_programs_cache = bank.loaded_programs_cache.read().unwrap(); + let slot_versions = + loaded_programs_cache.get_slot_versions_for_tests(&program_keypair.pubkey()); + assert_eq!(slot_versions.len(), 1); + assert!(Arc::ptr_eq( + &slot_versions[0].program.get_environment().unwrap(), + ¤t_env + )); + } goto_end_of_slot(bank.clone()); let bank = new_from_parent_with_fork_next_slot(bank, bank_forks.as_ref()); + { + let loaded_programs_cache = bank.loaded_programs_cache.read().unwrap(); + let slot_versions = + loaded_programs_cache.get_slot_versions_for_tests(&program_keypair.pubkey()); + assert_eq!(slot_versions.len(), 2); + assert!(Arc::ptr_eq( + &slot_versions[0].program.get_environment().unwrap(), + ¤t_env + )); + assert!(Arc::ptr_eq( + &slot_versions[1].program.get_environment().unwrap(), + &upcoming_env + )); + } // Advance the bank to cross the epoch boundary and activate the feature. goto_end_of_slot(bank.clone());