solana_runtime/
program_cache_utils.rs1use {
4 crate::bank::Bank,
5 solana_program_runtime::{
6 loaded_programs::ProgramRuntimeEnvironment,
7 program_cache_entry::{ProgramCacheEntry, ProgramCacheEntryType},
8 },
9 solana_pubkey::Pubkey,
10 std::sync::Arc,
11};
12
13pub enum EntryType {
14 FailedVerification,
15 Loaded,
16}
17
18pub struct ExpectedEntry<'a> {
19 pub entry_type: EntryType,
20 pub deployment_slot: u64,
21 pub environment: &'a ProgramRuntimeEnvironment,
22}
23
24pub fn current_env(bank: &Bank) -> ProgramRuntimeEnvironment {
25 bank.get_transaction_processor()
26 .program_runtime_environment_for_epoch(bank.epoch())
27}
28
29fn get_entry_env(entry: &ProgramCacheEntry) -> &ProgramRuntimeEnvironment {
30 entry
31 .program
32 .get_environment()
33 .expect("entry carries an environment")
34}
35
36fn find_all_cached_entries_for_key(
37 bank: &Bank,
38 program_id: &Pubkey,
39) -> Vec<Arc<ProgramCacheEntry>> {
40 let processor = bank.get_transaction_processor();
41 let cache = processor.global_program_cache.read().unwrap();
42 cache
43 .get_flattened_entries_for_tests()
44 .into_iter()
45 .filter_map(|(key, entry)| (key == *program_id).then_some(entry))
46 .collect()
47}
48
49pub fn assert_cache_contents(bank: &Bank, program_id: &Pubkey, expected_entries: &[ExpectedEntry]) {
50 let entries = find_all_cached_entries_for_key(bank, program_id);
51
52 let len = entries.len();
53 let expected_len = expected_entries.len();
54 assert_eq!(
55 len, expected_len,
56 "program should have {expected_len} entries. Got {len}: {entries:?}",
57 );
58
59 for (i, expected_entry) in expected_entries.iter().enumerate() {
60 let entry = entries.get(i).unwrap();
61 match expected_entry.entry_type {
62 EntryType::FailedVerification => {
63 assert!(
64 matches!(entry.program, ProgramCacheEntryType::FailedVerification(_)),
65 "Entry {i} should be cached as a failed verification entry",
66 );
67 }
68 EntryType::Loaded => {
69 assert!(
70 matches!(entry.program, ProgramCacheEntryType::Loaded(_)),
71 "Entry {i} should be cached as a loaded entry",
72 );
73 }
74 }
75 let deployment_slot = entry.deployment_slot;
76 let expected_deployment_slot = expected_entry.deployment_slot;
77 assert_eq!(
78 deployment_slot, expected_deployment_slot,
79 "Entry {i} should have deployment slot of {expected_deployment_slot}. Got \
80 {deployment_slot}",
81 );
82 let environment = get_entry_env(entry);
83 let expected_environment = expected_entry.environment;
84 assert_eq!(
85 environment, expected_environment,
86 "Entry {i} has unexpected environment",
87 );
88 }
89}