use lazy_static::lazy_static; use solana_sdk::{ hash::{Hash, Hasher}, pubkey::Pubkey, }; use std::collections::{HashMap, HashSet}; pub mod instructions_sysvar_enabled { solana_sdk::declare_id!("EnvhHCLvg55P7PDtbvR1NwuTuAeodqpusV3MR5QEK8gs"); } pub mod secp256k1_program_enabled { solana_sdk::declare_id!("E3PHP7w8kB7np3CTQ1qQ2tW3KCtjRSXBQgW9vM2mWv2Y"); } pub mod consistent_recent_blockhashes_sysvar { solana_sdk::declare_id!("3h1BQWPDS5veRsq6mDBWruEpgPxRJkfwGexg5iiQ9mYg"); } pub mod pico_inflation { solana_sdk::declare_id!("GaBtBJvmS4Arjj5W1NmFcyvPjsHN38UGYDq2MDwbs9Qu"); } pub mod inflation_kill_switch { solana_sdk::declare_id!("SECCKV5UVUsr8sTVSVAzULjdm87r7mLPaqH2FGZjevR"); } pub mod spl_token_v2_multisig_fix { solana_sdk::declare_id!("E5JiFDQCwyC6QfT9REFyMpfK2mHcmv1GUDySU1Ue7TYv"); } pub mod bpf_loader2_program { solana_sdk::declare_id!("DFBnrgThdzH4W6wZ12uGPoWcMnvfZj11EHnxHcVxLPhD"); } pub mod compute_budget_config2 { solana_sdk::declare_id!("HxvjqDSiF5sYdSYuCXsUnS8UeAoWsMT9iGoFP8pgV1mB"); } pub mod sha256_syscall_enabled { solana_sdk::declare_id!("D7KfP7bZxpkYtD4Pc38t9htgs1k5k47Yhxe4rp6WDVi8"); } pub mod no_overflow_rent_distribution { solana_sdk::declare_id!("4kpdyrcj5jS47CZb2oJGfVxjYbsMm2Kx97gFyZrxxwXz"); } pub mod ristretto_mul_syscall_enabled { solana_sdk::declare_id!("HRe7A6aoxgjKzdjbBv6HTy7tJ4YWqE6tVmYCGho6S9Aq"); } lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ (instructions_sysvar_enabled::id(), "instructions sysvar"), (secp256k1_program_enabled::id(), "secp256k1 program"), (consistent_recent_blockhashes_sysvar::id(), "consistent recentblockhashes sysvar"), (pico_inflation::id(), "pico-inflation"), (inflation_kill_switch::id(), "inflation kill switch"), (spl_token_v2_multisig_fix::id(), "spl-token multisig fix"), (bpf_loader2_program::id(), "bpf_loader2 program"), (compute_budget_config2::id(), "1ms compute budget"), (sha256_syscall_enabled::id(), "sha256 syscall"), (no_overflow_rent_distribution::id(), "no overflow rent distribution"), (ristretto_mul_syscall_enabled::id(), "ristretto multiply syscall"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter() .cloned() .collect(); /// Unique identifier of the current software's feature set pub static ref ID: Hash = { let mut hasher = Hasher::default(); let mut feature_ids = FEATURE_NAMES.keys().collect::>(); feature_ids.sort(); for feature in feature_ids { hasher.hash(feature.as_ref()); } hasher.result() }; } /// `FeatureSet` holds the set of currently active/inactive runtime features #[derive(AbiExample, Clone)] pub struct FeatureSet { pub active: HashSet, pub inactive: HashSet, } impl Default for FeatureSet { fn default() -> Self { // All features disabled Self { active: HashSet::new(), inactive: FEATURE_NAMES.keys().cloned().collect(), } } } impl FeatureSet { pub fn is_active(&self, feature_id: &Pubkey) -> bool { self.active.contains(feature_id) } /// All features enabled, useful for testing pub fn all_enabled() -> Self { Self { active: FEATURE_NAMES.keys().cloned().collect(), inactive: HashSet::new(), } } }