solana_runtime/bank/
sysvar_cache.rs

1use {
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}