2020-08-14 12:32:45 -07:00
|
|
|
use crate::{
|
|
|
|
bank::{Builtin, Entrypoint},
|
|
|
|
system_instruction_processor,
|
|
|
|
};
|
2020-08-25 09:49:15 -07:00
|
|
|
use solana_sdk::{
|
|
|
|
clock::{Epoch, GENESIS_EPOCH},
|
|
|
|
genesis_config::OperatingMode,
|
|
|
|
system_program,
|
|
|
|
};
|
|
|
|
|
|
|
|
use log::*;
|
|
|
|
|
|
|
|
/// The entire set of available builtin programs that should be active at the given operating_mode
|
|
|
|
pub fn get_builtins(operating_mode: OperatingMode) -> Vec<(Builtin, Epoch)> {
|
|
|
|
trace!("get_builtins: {:?}", operating_mode);
|
|
|
|
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 Preview for test_get_builtins because the Development is overloaded...
|
|
|
|
#[cfg(test)]
|
|
|
|
if operating_mode == OperatingMode::Preview {
|
|
|
|
use solana_sdk::instruction::InstructionError;
|
|
|
|
use solana_sdk::{account::KeyedAccount, pubkey::Pubkey};
|
|
|
|
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.extend(vec![(
|
|
|
|
Builtin::new("mock", program_id, Entrypoint::Program(mock_ix_processor)),
|
|
|
|
2,
|
|
|
|
)]);
|
|
|
|
}
|
|
|
|
|
|
|
|
builtins
|
2020-08-14 12:32:45 -07:00
|
|
|
}
|
|
|
|
|
2020-08-25 09:49:15 -07:00
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
use crate::bank::Bank;
|
|
|
|
use solana_sdk::{
|
|
|
|
genesis_config::{create_genesis_config, OperatingMode},
|
|
|
|
pubkey::Pubkey,
|
|
|
|
};
|
|
|
|
|
2020-09-01 17:48:25 +09:00
|
|
|
use std::collections::HashSet;
|
2020-08-25 09:49:15 -07:00
|
|
|
use std::str::FromStr;
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
2020-09-01 17:48:25 +09: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() {
|
|
|
|
do_test_uniqueness(get_builtins(OperatingMode::Development));
|
|
|
|
do_test_uniqueness(get_builtins(OperatingMode::Preview));
|
|
|
|
do_test_uniqueness(get_builtins(OperatingMode::Stable));
|
|
|
|
}
|
|
|
|
|
2020-08-25 09:49:15 -07:00
|
|
|
#[test]
|
|
|
|
fn test_get_builtins() {
|
|
|
|
let (mut genesis_config, _mint_keypair) = create_genesis_config(100_000);
|
|
|
|
genesis_config.operating_mode = OperatingMode::Preview;
|
|
|
|
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(),
|
|
|
|
Pubkey::from_str("7saCc6X5a2syoYANA5oUUnPZLcLMfKoSjiDhFU5fbpoK").unwrap(),
|
|
|
|
]
|
|
|
|
);
|
|
|
|
|
|
|
|
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(),
|
|
|
|
Pubkey::from_str("7saCc6X5a2syoYANA5oUUnPZLcLMfKoSjiDhFU5fbpoK").unwrap(),
|
|
|
|
]
|
|
|
|
);
|
|
|
|
|
|
|
|
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(),
|
|
|
|
Pubkey::from_str("7saCc6X5a2syoYANA5oUUnPZLcLMfKoSjiDhFU5fbpoK").unwrap(),
|
|
|
|
]
|
|
|
|
);
|
|
|
|
}
|
2020-08-14 12:32:45 -07:00
|
|
|
}
|