2020-08-22 01:54:50 +00:00
|
|
|
use crate::{
|
|
|
|
bank::{Builtin, Entrypoint},
|
2020-09-26 17:49:53 +00:00
|
|
|
feature_set, system_instruction_processor,
|
2020-08-22 01:54:50 +00:00
|
|
|
};
|
2020-08-25 19:00:41 +00:00
|
|
|
use solana_sdk::{
|
|
|
|
clock::{Epoch, GENESIS_EPOCH},
|
2020-09-08 23:54:54 +09:00
|
|
|
genesis_config::ClusterType,
|
2020-09-26 17:49:53 +00:00
|
|
|
pubkey::Pubkey,
|
2020-08-25 19:00:41 +00:00
|
|
|
system_program,
|
|
|
|
};
|
|
|
|
|
|
|
|
use log::*;
|
|
|
|
|
2020-09-26 17:49:53 +00:00
|
|
|
/// 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);
|
2020-08-25 19:00:41 +00:00
|
|
|
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<_>>(),
|
|
|
|
);
|
|
|
|
|
2020-09-08 23:54:54 +09:00
|
|
|
// repurpose Testnet for test_get_builtins because the Development is overloaded...
|
2020-08-25 19:00:41 +00:00
|
|
|
#[cfg(test)]
|
2020-09-08 23:54:54 +09:00
|
|
|
if cluster_type == ClusterType::Testnet {
|
2020-09-26 17:49:53 +00:00
|
|
|
use solana_sdk::account::KeyedAccount;
|
2020-08-25 19:00:41 +00:00
|
|
|
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();
|
2020-09-26 17:49:53 +00:00
|
|
|
builtins.push((
|
2020-08-25 19:00:41 +00:00
|
|
|
Builtin::new("mock", program_id, Entrypoint::Program(mock_ix_processor)),
|
|
|
|
2,
|
2020-09-26 17:49:53 +00:00
|
|
|
));
|
2020-08-25 19:00:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
builtins
|
2020-08-22 01:54:50 +00:00
|
|
|
}
|
|
|
|
|
2020-09-26 17:49:53 +00:00
|
|
|
/// Builtin programs that are activated dynamically by feature
|
|
|
|
pub fn get_feature_builtins() -> Vec<(Builtin, Pubkey)> {
|
|
|
|
vec![(
|
|
|
|
Builtin::new(
|
|
|
|
"secp256k1_program",
|
|
|
|
solana_sdk::secp256k1_program::id(),
|
|
|
|
Entrypoint::Program(solana_secp256k1_program::process_instruction),
|
|
|
|
),
|
|
|
|
feature_set::secp256k1_program_enabled::id(),
|
|
|
|
)]
|
|
|
|
}
|
|
|
|
|
2020-08-25 19:00:41 +00:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use crate::bank::Bank;
|
2020-09-26 17:49:53 +00:00
|
|
|
use solana_sdk::genesis_config::create_genesis_config;
|
|
|
|
use std::{collections::HashSet, str::FromStr, sync::Arc};
|
2020-08-25 19:00:41 +00:00
|
|
|
|
2020-09-01 09:54:27 +00:00
|
|
|
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() {
|
2020-09-26 17:49:53 +00:00
|
|
|
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));
|
2020-09-01 09:54:27 +00:00
|
|
|
}
|
|
|
|
|
2020-08-25 19:00:41 +00:00
|
|
|
#[test]
|
|
|
|
fn test_get_builtins() {
|
2020-09-21 18:09:05 +00:00
|
|
|
let mock_program_id =
|
|
|
|
Pubkey::from_str("7saCc6X5a2syoYANA5oUUnPZLcLMfKoSjiDhFU5fbpoK").unwrap();
|
|
|
|
|
2020-08-25 19:00:41 +00:00
|
|
|
let (mut genesis_config, _mint_keypair) = create_genesis_config(100_000);
|
2020-09-08 23:54:54 +09:00
|
|
|
genesis_config.cluster_type = ClusterType::Testnet;
|
2020-08-25 19:00:41 +00:00
|
|
|
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(),
|
2020-09-21 18:09:05 +00:00
|
|
|
mock_program_id,
|
2020-08-25 19:00:41 +00:00
|
|
|
]
|
|
|
|
);
|
|
|
|
|
|
|
|
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(),
|
2020-09-21 18:09:05 +00:00
|
|
|
mock_program_id,
|
2020-08-25 19:00:41 +00:00
|
|
|
]
|
|
|
|
);
|
|
|
|
|
|
|
|
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(),
|
2020-09-21 18:09:05 +00:00
|
|
|
mock_program_id,
|
2020-08-25 19:00:41 +00:00
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
2020-08-22 01:54:50 +00:00
|
|
|
}
|