solana_runtime/bank/
sysvar_cache.rs1use {
2 super::Bank, solana_program_runtime::sysvar_cache::SysvarCache,
3 solana_sdk::account::ReadableAccount,
4};
5
6impl Bank {
7 pub(crate) fn fill_missing_sysvar_cache_entries(&self) {
8 let mut sysvar_cache = self.sysvar_cache.write().unwrap();
9 sysvar_cache.fill_missing_entries(|pubkey, callback| {
10 if let Some(account) = self.get_account_with_fixed_root(pubkey) {
11 callback(account.data());
12 }
13 });
14 }
15
16 pub(crate) fn reset_sysvar_cache(&self) {
17 let mut sysvar_cache = self.sysvar_cache.write().unwrap();
18 sysvar_cache.reset();
19 }
20
21 pub fn get_sysvar_cache_for_tests(&self) -> SysvarCache {
22 self.sysvar_cache.read().unwrap().clone()
23 }
24}
25
26#[cfg(test)]
27mod tests {
28 use {
29 super::*,
30 solana_sdk::{genesis_config::create_genesis_config, pubkey::Pubkey},
31 std::sync::Arc,
32 };
33
34 #[test]
35 #[allow(deprecated)]
36 fn test_sysvar_cache_initialization() {
37 let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
38 let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
39
40 let bank0_sysvar_cache = bank0.sysvar_cache.read().unwrap();
41 let bank0_cached_clock = bank0_sysvar_cache.get_clock();
42 let bank0_cached_epoch_schedule = bank0_sysvar_cache.get_epoch_schedule();
43 let bank0_cached_fees = bank0_sysvar_cache.get_fees();
44 let bank0_cached_rent = bank0_sysvar_cache.get_rent();
45
46 assert!(bank0_cached_clock.is_ok());
47 assert!(bank0_cached_epoch_schedule.is_ok());
48 assert!(bank0_cached_fees.is_ok());
49 assert!(bank0_cached_rent.is_ok());
50 assert!(bank0_sysvar_cache.get_slot_hashes().is_err());
51
52 let bank1 = Arc::new(Bank::new_from_parent(
53 &bank0,
54 &Pubkey::default(),
55 bank0.slot() + 1,
56 ));
57
58 let bank1_sysvar_cache = bank1.sysvar_cache.read().unwrap();
59 let bank1_cached_clock = bank1_sysvar_cache.get_clock();
60 let bank1_cached_epoch_schedule = bank1_sysvar_cache.get_epoch_schedule();
61 let bank1_cached_fees = bank1_sysvar_cache.get_fees();
62 let bank1_cached_rent = bank1_sysvar_cache.get_rent();
63
64 assert!(bank1_cached_clock.is_ok());
65 assert!(bank1_cached_epoch_schedule.is_ok());
66 assert!(bank1_cached_fees.is_ok());
67 assert!(bank1_cached_rent.is_ok());
68 assert!(bank1_sysvar_cache.get_slot_hashes().is_ok());
69
70 assert_ne!(bank0_cached_clock, bank1_cached_clock);
71 assert_eq!(bank0_cached_epoch_schedule, bank1_cached_epoch_schedule);
72 assert_ne!(bank0_cached_fees, bank1_cached_fees);
73 assert_eq!(bank0_cached_rent, bank1_cached_rent);
74
75 let bank2 = Bank::new_from_parent(&bank1, &Pubkey::default(), bank1.slot() + 1);
76
77 let bank2_sysvar_cache = bank2.sysvar_cache.read().unwrap();
78 let bank2_cached_clock = bank2_sysvar_cache.get_clock();
79 let bank2_cached_epoch_schedule = bank2_sysvar_cache.get_epoch_schedule();
80 let bank2_cached_fees = bank2_sysvar_cache.get_fees();
81 let bank2_cached_rent = bank2_sysvar_cache.get_rent();
82
83 assert!(bank2_cached_clock.is_ok());
84 assert!(bank2_cached_epoch_schedule.is_ok());
85 assert!(bank2_cached_fees.is_ok());
86 assert!(bank2_cached_rent.is_ok());
87 assert!(bank2_sysvar_cache.get_slot_hashes().is_ok());
88
89 assert_ne!(bank1_cached_clock, bank2_cached_clock);
90 assert_eq!(bank1_cached_epoch_schedule, bank2_cached_epoch_schedule);
91 assert_eq!(bank1_cached_fees, bank2_cached_fees);
92 assert_eq!(bank1_cached_rent, bank2_cached_rent);
93 assert_ne!(
94 bank1_sysvar_cache.get_slot_hashes(),
95 bank2_sysvar_cache.get_slot_hashes(),
96 );
97 }
98
99 #[test]
100 #[allow(deprecated)]
101 fn test_reset_and_fill_sysvar_cache() {
102 let (genesis_config, _mint_keypair) = create_genesis_config(100_000);
103 let bank0 = Arc::new(Bank::new_for_tests(&genesis_config));
104 let bank1 = Bank::new_from_parent(&bank0, &Pubkey::default(), bank0.slot() + 1);
105
106 let bank1_sysvar_cache = bank1.sysvar_cache.read().unwrap();
107 let bank1_cached_clock = bank1_sysvar_cache.get_clock();
108 let bank1_cached_epoch_schedule = bank1_sysvar_cache.get_epoch_schedule();
109 let bank1_cached_fees = bank1_sysvar_cache.get_fees();
110 let bank1_cached_rent = bank1_sysvar_cache.get_rent();
111 let bank1_cached_slot_hashes = bank1_sysvar_cache.get_slot_hashes();
112
113 assert!(bank1_cached_clock.is_ok());
114 assert!(bank1_cached_epoch_schedule.is_ok());
115 assert!(bank1_cached_fees.is_ok());
116 assert!(bank1_cached_rent.is_ok());
117 assert!(bank1_cached_slot_hashes.is_ok());
118
119 drop(bank1_sysvar_cache);
120 bank1.reset_sysvar_cache();
121
122 let bank1_sysvar_cache = bank1.sysvar_cache.read().unwrap();
123 assert!(bank1_sysvar_cache.get_clock().is_err());
124 assert!(bank1_sysvar_cache.get_epoch_schedule().is_err());
125 assert!(bank1_sysvar_cache.get_fees().is_err());
126 assert!(bank1_sysvar_cache.get_rent().is_err());
127 assert!(bank1_sysvar_cache.get_slot_hashes().is_err());
128
129 drop(bank1_sysvar_cache);
130 bank1.fill_missing_sysvar_cache_entries();
131
132 let bank1_sysvar_cache = bank1.sysvar_cache.read().unwrap();
133 assert_eq!(bank1_sysvar_cache.get_clock(), bank1_cached_clock);
134 assert_eq!(
135 bank1_sysvar_cache.get_epoch_schedule(),
136 bank1_cached_epoch_schedule
137 );
138 assert_eq!(bank1_sysvar_cache.get_fees(), bank1_cached_fees);
139 assert_eq!(bank1_sysvar_cache.get_rent(), bank1_cached_rent);
140 assert_eq!(
141 bank1_sysvar_cache.get_slot_hashes(),
142 bank1_cached_slot_hashes
143 );
144 }
145}