Port BPFLoader2 activation to FeatureSet and rework built-in program activation
This commit is contained in:
@@ -1,76 +1,37 @@
|
||||
use crate::{
|
||||
bank::{Builtin, Entrypoint},
|
||||
bank::{Builtin, Builtins, Entrypoint},
|
||||
feature_set, system_instruction_processor,
|
||||
};
|
||||
use solana_sdk::{
|
||||
clock::{Epoch, GENESIS_EPOCH},
|
||||
genesis_config::ClusterType,
|
||||
pubkey::Pubkey,
|
||||
system_program,
|
||||
};
|
||||
use solana_sdk::{pubkey::Pubkey, system_program};
|
||||
|
||||
use log::*;
|
||||
|
||||
/// Builtin programs that should be active for the given cluster_type
|
||||
///
|
||||
/// Old style. Use `get_feature_builtins()` instead
|
||||
pub fn get_cluster_builtins(cluster_type: ClusterType) -> Vec<(Builtin, Epoch)> {
|
||||
trace!("get_cluster_builtins: {:?}", cluster_type);
|
||||
let mut builtins = vec![];
|
||||
|
||||
builtins.extend(
|
||||
vec![
|
||||
Builtin::new(
|
||||
"system_program",
|
||||
system_program::id(),
|
||||
Entrypoint::Program(system_instruction_processor::process_instruction),
|
||||
),
|
||||
Builtin::new(
|
||||
"config_program",
|
||||
solana_config_program::id(),
|
||||
Entrypoint::Program(solana_config_program::config_processor::process_instruction),
|
||||
),
|
||||
Builtin::new(
|
||||
"stake_program",
|
||||
solana_stake_program::id(),
|
||||
Entrypoint::Program(solana_stake_program::stake_instruction::process_instruction),
|
||||
),
|
||||
Builtin::new(
|
||||
"vote_program",
|
||||
solana_vote_program::id(),
|
||||
Entrypoint::Program(solana_vote_program::vote_instruction::process_instruction),
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.map(|program| (program, GENESIS_EPOCH))
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
// repurpose Testnet for test_get_builtins because the Development is overloaded...
|
||||
#[cfg(test)]
|
||||
if cluster_type == ClusterType::Testnet {
|
||||
use solana_sdk::account::KeyedAccount;
|
||||
use solana_sdk::instruction::InstructionError;
|
||||
use std::str::FromStr;
|
||||
fn mock_ix_processor(
|
||||
_pubkey: &Pubkey,
|
||||
_ka: &[KeyedAccount],
|
||||
_data: &[u8],
|
||||
) -> std::result::Result<(), InstructionError> {
|
||||
Err(InstructionError::Custom(42))
|
||||
}
|
||||
let program_id = Pubkey::from_str("7saCc6X5a2syoYANA5oUUnPZLcLMfKoSjiDhFU5fbpoK").unwrap();
|
||||
builtins.push((
|
||||
Builtin::new("mock", program_id, Entrypoint::Program(mock_ix_processor)),
|
||||
2,
|
||||
));
|
||||
}
|
||||
|
||||
builtins
|
||||
/// Builtin programs that are always available
|
||||
fn genesis_builtins() -> Vec<Builtin> {
|
||||
vec![
|
||||
Builtin::new(
|
||||
"system_program",
|
||||
system_program::id(),
|
||||
Entrypoint::Program(system_instruction_processor::process_instruction),
|
||||
),
|
||||
Builtin::new(
|
||||
"vote_program",
|
||||
solana_vote_program::id(),
|
||||
Entrypoint::Program(solana_vote_program::vote_instruction::process_instruction),
|
||||
),
|
||||
Builtin::new(
|
||||
"stake_program",
|
||||
solana_stake_program::id(),
|
||||
Entrypoint::Program(solana_stake_program::stake_instruction::process_instruction),
|
||||
),
|
||||
Builtin::new(
|
||||
"config_program",
|
||||
solana_config_program::id(),
|
||||
Entrypoint::Program(solana_config_program::config_processor::process_instruction),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
/// Builtin programs that are activated dynamically by feature
|
||||
pub fn get_feature_builtins() -> Vec<(Builtin, Pubkey)> {
|
||||
/// Builtin programs activated dynamically by feature
|
||||
fn feature_builtins() -> Vec<(Builtin, Pubkey)> {
|
||||
vec![(
|
||||
Builtin::new(
|
||||
"secp256k1_program",
|
||||
@@ -81,108 +42,9 @@ pub fn get_feature_builtins() -> Vec<(Builtin, Pubkey)> {
|
||||
)]
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::bank::Bank;
|
||||
use solana_sdk::genesis_config::create_genesis_config;
|
||||
use std::{collections::HashSet, str::FromStr, sync::Arc};
|
||||
|
||||
fn do_test_uniqueness(builtins: Vec<(Builtin, Epoch)>) {
|
||||
let mut unique_ids = HashSet::new();
|
||||
let mut unique_names = HashSet::new();
|
||||
let mut prev_start_epoch = 0;
|
||||
for (builtin, next_start_epoch) in builtins {
|
||||
assert!(next_start_epoch >= prev_start_epoch);
|
||||
assert!(unique_ids.insert(builtin.name));
|
||||
assert!(unique_names.insert(builtin.id));
|
||||
prev_start_epoch = next_start_epoch;
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uniqueness() {
|
||||
do_test_uniqueness(get_cluster_builtins(ClusterType::Development));
|
||||
do_test_uniqueness(get_cluster_builtins(ClusterType::Devnet));
|
||||
do_test_uniqueness(get_cluster_builtins(ClusterType::Testnet));
|
||||
do_test_uniqueness(get_cluster_builtins(ClusterType::MainnetBeta));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_get_builtins() {
|
||||
let mock_program_id =
|
||||
Pubkey::from_str("7saCc6X5a2syoYANA5oUUnPZLcLMfKoSjiDhFU5fbpoK").unwrap();
|
||||
|
||||
let (mut genesis_config, _mint_keypair) = create_genesis_config(100_000);
|
||||
genesis_config.cluster_type = ClusterType::Testnet;
|
||||
let bank0 = Arc::new(Bank::new(&genesis_config));
|
||||
|
||||
let restored_slot1 = genesis_config.epoch_schedule.get_first_slot_in_epoch(2);
|
||||
let bank1 = Arc::new(Bank::new_from_parent(
|
||||
&bank0,
|
||||
&Pubkey::default(),
|
||||
restored_slot1,
|
||||
));
|
||||
|
||||
let restored_slot2 = genesis_config.epoch_schedule.get_first_slot_in_epoch(3);
|
||||
let bank2 = Arc::new(Bank::new_from_parent(
|
||||
&bank1,
|
||||
&Pubkey::default(),
|
||||
restored_slot2,
|
||||
));
|
||||
|
||||
let warped_slot = genesis_config.epoch_schedule.get_first_slot_in_epoch(999);
|
||||
let warped_bank = Arc::new(Bank::warp_from_parent(
|
||||
&bank0,
|
||||
&Pubkey::default(),
|
||||
warped_slot,
|
||||
));
|
||||
|
||||
assert_eq!(bank0.slot(), 0);
|
||||
assert_eq!(
|
||||
bank0.builtin_program_ids(),
|
||||
vec![
|
||||
system_program::id(),
|
||||
solana_config_program::id(),
|
||||
solana_stake_program::id(),
|
||||
solana_vote_program::id(),
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(bank1.slot(), restored_slot1);
|
||||
assert_eq!(
|
||||
bank1.builtin_program_ids(),
|
||||
vec![
|
||||
system_program::id(),
|
||||
solana_config_program::id(),
|
||||
solana_stake_program::id(),
|
||||
solana_vote_program::id(),
|
||||
mock_program_id,
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(bank2.slot(), restored_slot2);
|
||||
assert_eq!(
|
||||
bank2.builtin_program_ids(),
|
||||
vec![
|
||||
system_program::id(),
|
||||
solana_config_program::id(),
|
||||
solana_stake_program::id(),
|
||||
solana_vote_program::id(),
|
||||
mock_program_id,
|
||||
]
|
||||
);
|
||||
|
||||
assert_eq!(warped_bank.slot(), warped_slot);
|
||||
assert_eq!(
|
||||
warped_bank.builtin_program_ids(),
|
||||
vec![
|
||||
system_program::id(),
|
||||
solana_config_program::id(),
|
||||
solana_stake_program::id(),
|
||||
solana_vote_program::id(),
|
||||
mock_program_id,
|
||||
]
|
||||
);
|
||||
pub(crate) fn get() -> Builtins {
|
||||
Builtins {
|
||||
genesis_builtins: genesis_builtins(),
|
||||
feature_builtins: feature_builtins(),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user