solana_feature_set_interface/
lib.rs

1#![cfg_attr(feature = "frozen-abi", feature(min_specialization))]
2
3use {
4    ahash::{AHashMap, AHashSet},
5    solana_pubkey::Pubkey,
6};
7
8/// `FeatureSet` holds the set of currently active/inactive runtime features
9#[cfg_attr(feature = "frozen-abi", derive(solana_frozen_abi_macro::AbiExample))]
10#[derive(Debug, Clone, Eq, PartialEq)]
11pub struct FeatureSet {
12    pub active: AHashMap<Pubkey, u64>,
13    pub inactive: AHashSet<Pubkey>,
14}
15
16impl FeatureSet {
17    pub fn is_active(&self, feature_id: &Pubkey) -> bool {
18        self.active.contains_key(feature_id)
19    }
20
21    pub fn activated_slot(&self, feature_id: &Pubkey) -> Option<u64> {
22        self.active.get(feature_id).copied()
23    }
24
25    /// Activate a feature
26    pub fn activate(&mut self, feature_id: &Pubkey, slot: u64) {
27        self.inactive.remove(feature_id);
28        self.active.insert(*feature_id, slot);
29    }
30
31    /// Deactivate a feature
32    pub fn deactivate(&mut self, feature_id: &Pubkey) {
33        self.active.remove(feature_id);
34        self.inactive.insert(*feature_id);
35    }
36}
37
38#[cfg(test)]
39mod test {
40    use super::*;
41
42    #[test]
43    fn test_feature_set_activate_deactivate() {
44        let mut feature_set = FeatureSet {
45            active: AHashMap::new(),
46            inactive: AHashSet::new(),
47        };
48
49        let feature = Pubkey::new_unique();
50        assert!(!feature_set.is_active(&feature));
51        feature_set.activate(&feature, 0);
52        assert!(feature_set.is_active(&feature));
53        feature_set.deactivate(&feature);
54        assert!(!feature_set.is_active(&feature));
55    }
56}