From 36627fb8b39376def361a4e3c34f7eac25d9ebc2 Mon Sep 17 00:00:00 2001 From: Jack May Date: Tue, 19 May 2020 19:45:30 -0700 Subject: [PATCH] move builtin programs out of bank (#10132) automerge --- bench-exchange/tests/bench_exchange.rs | 2 +- programs/budget/src/budget_processor.rs | 2 +- programs/exchange/src/exchange_processor.rs | 2 +- programs/ownable/src/ownable_processor.rs | 2 +- programs/vest/src/vest_processor.rs | 2 +- runtime/benches/bank.rs | 2 +- runtime/src/bank.rs | 55 ++++++++------------- runtime/src/builtin_programs.rs | 42 ++++++++++++++++ runtime/src/lib.rs | 1 + runtime/src/message_processor.rs | 28 +++-------- 10 files changed, 77 insertions(+), 61 deletions(-) create mode 100644 runtime/src/builtin_programs.rs diff --git a/bench-exchange/tests/bench_exchange.rs b/bench-exchange/tests/bench_exchange.rs index 7c7e0fdcd..ea24fffd1 100644 --- a/bench-exchange/tests/bench_exchange.rs +++ b/bench-exchange/tests/bench_exchange.rs @@ -86,7 +86,7 @@ fn test_exchange_bank_client() { solana_logger::setup(); let (genesis_config, identity) = create_genesis_config(100_000_000_000_000); let mut bank = Bank::new(&genesis_config); - bank.add_static_program("exchange_program", id(), process_instruction); + bank.add_builtin_program("exchange_program", id(), process_instruction); let clients = vec![BankClient::new(bank)]; let mut config = Config::default(); diff --git a/programs/budget/src/budget_processor.rs b/programs/budget/src/budget_processor.rs index 26c8aba8a..c82bebcde 100644 --- a/programs/budget/src/budget_processor.rs +++ b/programs/budget/src/budget_processor.rs @@ -238,7 +238,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_static_program("budget_program", id(), process_instruction); + bank.add_builtin_program("budget_program", id(), process_instruction); (bank, mint_keypair) } diff --git a/programs/exchange/src/exchange_processor.rs b/programs/exchange/src/exchange_processor.rs index 4c930f57a..b004aed05 100644 --- a/programs/exchange/src/exchange_processor.rs +++ b/programs/exchange/src/exchange_processor.rs @@ -578,7 +578,7 @@ mod test { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_static_program("exchange_program", id(), process_instruction); + bank.add_builtin_program("exchange_program", id(), process_instruction); (bank, mint_keypair) } diff --git a/programs/ownable/src/ownable_processor.rs b/programs/ownable/src/ownable_processor.rs index 5abbf9e36..0d07d5489 100644 --- a/programs/ownable/src/ownable_processor.rs +++ b/programs/ownable/src/ownable_processor.rs @@ -71,7 +71,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_static_program("ownable_program", crate::id(), process_instruction); + bank.add_builtin_program("ownable_program", crate::id(), process_instruction); (bank, mint_keypair) } diff --git a/programs/vest/src/vest_processor.rs b/programs/vest/src/vest_processor.rs index 6f79d8582..5fda3f35c 100644 --- a/programs/vest/src/vest_processor.rs +++ b/programs/vest/src/vest_processor.rs @@ -161,7 +161,7 @@ mod tests { fn create_bank(lamports: u64) -> (Bank, Keypair) { let (genesis_config, mint_keypair) = create_genesis_config(lamports); let mut bank = Bank::new(&genesis_config); - bank.add_static_program("vest_program", id(), process_instruction); + bank.add_builtin_program("vest_program", id(), process_instruction); (bank, mint_keypair) } diff --git a/runtime/benches/bank.rs b/runtime/benches/bank.rs index d829e0580..c2f8753e0 100644 --- a/runtime/benches/bank.rs +++ b/runtime/benches/bank.rs @@ -122,7 +122,7 @@ fn do_bench_transactions( let (mut genesis_config, mint_keypair) = create_genesis_config(100_000_000); genesis_config.ticks_per_slot = 100; let mut bank = Bank::new(&genesis_config); - bank.add_static_program( + bank.add_builtin_program( "builtin_program", Pubkey::new(&BUILTIN_PROGRAM_ID), process_instruction, diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index ae7e6da7b..b5d7f22f5 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -10,13 +10,14 @@ use crate::{ accounts_db::{AccountsDBSerialize, ErrorCounters, SnapshotStorage, SnapshotStorages}, accounts_index::Ancestors, blockhash_queue::BlockhashQueue, + builtin_programs::get_builtin_programs, epoch_stakes::{EpochStakes, NodeVoteAccounts}, message_processor::{MessageProcessor, ProcessInstruction}, nonce_utils, rent_collector::RentCollector, stakes::Stakes, status_cache::{SlotDelta, StatusCache}, - system_instruction_processor::{self, get_system_account_kind, SystemAccountKind}, + system_instruction_processor::{get_system_account_kind, SystemAccountKind}, transaction_batch::TransactionBatch, transaction_utils::OrderedIterator, }; @@ -2086,26 +2087,10 @@ impl Bank { } pub fn finish_init(&mut self) { - self.add_static_program( - "system_program", - solana_sdk::system_program::id(), - system_instruction_processor::process_instruction, - ); - self.add_static_program( - "config_program", - solana_config_program::id(), - solana_config_program::config_processor::process_instruction, - ); - self.add_static_program( - "stake_program", - solana_stake_program::id(), - solana_stake_program::stake_instruction::process_instruction, - ); - self.add_static_program( - "vote_program", - solana_vote_program::id(), - solana_vote_program::vote_instruction::process_instruction, - ); + let builtin_programs = get_builtin_programs(); + for program in builtin_programs.iter() { + self.add_builtin_program(&program.name, program.id, program.process_instruction); + } } pub fn set_parent(&mut self, parent: &Arc) { @@ -2488,7 +2473,7 @@ impl Bank { } /// Add an instruction processor to intercept instructions before the dynamic loader. - pub fn add_static_program( + pub fn add_builtin_program( &mut self, name: &str, program_id: Pubkey, @@ -2509,7 +2494,7 @@ impl Bank { } } self.message_processor - .add_instruction_processor(program_id, process_instruction); + .add_program(program_id, process_instruction); debug!("Added static program {} under {:?}", name, program_id); } @@ -3051,7 +3036,7 @@ mod tests { ) as u64, ); bank.rent_collector.slots_per_year = 421_812.0; - bank.add_static_program("mock_program", mock_program_id, mock_process_instruction); + bank.add_builtin_program("mock_program", mock_program_id, mock_process_instruction); bank } @@ -5904,7 +5889,7 @@ mod tests { } #[test] - fn test_add_static_program() { + fn test_add_builtin_program() { let (genesis_config, mint_keypair) = create_genesis_config(500); let mut bank = Bank::new(&genesis_config); @@ -5923,7 +5908,7 @@ mod tests { } assert!(bank.get_account(&mock_vote_program_id()).is_none()); - bank.add_static_program( + bank.add_builtin_program( "mock_vote_program", mock_vote_program_id(), mock_vote_processor, @@ -5994,7 +5979,7 @@ mod tests { ); let vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap(); - bank.add_static_program( + bank.add_builtin_program( "solana_vote_program", solana_vote_program::id(), mock_vote_processor, @@ -6026,7 +6011,7 @@ mod tests { } // Non-native loader accounts can not be used for instruction processing - bank.add_static_program("mock_program", mint_keypair.pubkey(), mock_ix_processor); + bank.add_builtin_program("mock_program", mint_keypair.pubkey(), mock_ix_processor); } #[test] fn test_recent_blockhashes_sysvar() { @@ -6578,7 +6563,7 @@ mod tests { } let mock_program_id = Pubkey::new(&[2u8; 32]); - bank.add_static_program("mock_program", mock_program_id, mock_process_instruction); + bank.add_builtin_program("mock_program", mock_program_id, mock_process_instruction); let from_pubkey = Pubkey::new_rand(); let to_pubkey = Pubkey::new_rand(); @@ -6621,7 +6606,7 @@ mod tests { } let mock_program_id = Pubkey::new(&[2u8; 32]); - bank.add_static_program("mock_program", mock_program_id, mock_process_instruction); + bank.add_builtin_program("mock_program", mock_program_id, mock_process_instruction); let from_pubkey = Pubkey::new_rand(); let to_pubkey = Pubkey::new_rand(); @@ -6673,7 +6658,7 @@ mod tests { tx.message.account_keys.push(Pubkey::new_rand()); - bank.add_static_program( + bank.add_builtin_program( "mock_vote", solana_vote_program::id(), mock_ok_vote_processor, @@ -6727,7 +6712,7 @@ mod tests { AccountMeta::new(to_pubkey, false), ]; - bank.add_static_program( + bank.add_builtin_program( "mock_vote", solana_vote_program::id(), mock_ok_vote_processor, @@ -6760,7 +6745,7 @@ mod tests { AccountMeta::new(to_pubkey, false), ]; - bank.add_static_program( + bank.add_builtin_program( "mock_vote", solana_vote_program::id(), mock_ok_vote_processor, @@ -6815,7 +6800,7 @@ mod tests { AccountMeta::new(to_pubkey, false), ]; - bank.add_static_program( + bank.add_builtin_program( "mock_vote", solana_vote_program::id(), mock_ok_vote_processor, @@ -6851,7 +6836,7 @@ mod tests { .map(|i| { let key = Pubkey::new_rand(); let name = format!("program{:?}", i); - bank.add_static_program(&name, key, mock_ok_vote_processor); + bank.add_builtin_program(&name, key, mock_ok_vote_processor); (key, name.as_bytes().to_vec()) }) .collect(); diff --git a/runtime/src/builtin_programs.rs b/runtime/src/builtin_programs.rs new file mode 100644 index 000000000..180854990 --- /dev/null +++ b/runtime/src/builtin_programs.rs @@ -0,0 +1,42 @@ +use crate::{message_processor::ProcessInstruction, system_instruction_processor}; +use solana_sdk::{pubkey::Pubkey, system_program}; + +pub struct BuiltinProgram { + pub name: String, + pub id: Pubkey, + pub process_instruction: ProcessInstruction, +} +impl BuiltinProgram { + pub fn new(name: &str, id: Pubkey, process_instruction: ProcessInstruction) -> Self { + Self { + name: name.to_string(), + id, + process_instruction, + } + } +} + +pub fn get_builtin_programs() -> Vec { + vec![ + BuiltinProgram::new( + "system_program", + system_program::id(), + system_instruction_processor::process_instruction, + ), + BuiltinProgram::new( + "config_program", + solana_config_program::id(), + solana_config_program::config_processor::process_instruction, + ), + BuiltinProgram::new( + "stake_program", + solana_stake_program::id(), + solana_stake_program::stake_instruction::process_instruction, + ), + BuiltinProgram::new( + "vote_program", + solana_vote_program::id(), + solana_vote_program::vote_instruction::process_instruction, + ), + ] +} diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 106324237..55768daea 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -6,6 +6,7 @@ pub mod bank; pub mod bank_client; mod blockhash_queue; pub mod bloom; +pub mod builtin_programs; pub mod epoch_stakes; pub mod genesis_utils; pub mod loader_utils; diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 3a533a8df..e4874cda7 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -243,34 +243,24 @@ pub type ProcessInstructionWithContext = #[derive(Default, Deserialize, Serialize)] pub struct MessageProcessor { #[serde(skip)] - instruction_processors: Vec<(Pubkey, ProcessInstruction)>, + programs: Vec<(Pubkey, ProcessInstruction)>, #[serde(skip)] native_loader: NativeLoader, } impl Clone for MessageProcessor { fn clone(&self) -> Self { MessageProcessor { - instruction_processors: self.instruction_processors.clone(), + programs: self.programs.clone(), native_loader: NativeLoader::default(), } } } impl MessageProcessor { /// Add a static entrypoint to intercept instructions before the dynamic loader. - pub fn add_instruction_processor( - &mut self, - program_id: Pubkey, - process_instruction: ProcessInstruction, - ) { - match self - .instruction_processors - .iter_mut() - .find(|(key, _)| program_id == *key) - { + pub fn add_program(&mut self, program_id: Pubkey, process_instruction: ProcessInstruction) { + match self.programs.iter_mut().find(|(key, _)| program_id == *key) { Some((_, processor)) => *processor = process_instruction, - None => self - .instruction_processors - .push((program_id, process_instruction)), + None => self.programs.push((program_id, process_instruction)), } } @@ -315,7 +305,7 @@ impl MessageProcessor { let keyed_accounts = Self::create_keyed_accounts(message, instruction, executable_accounts, accounts)?; - for (id, process_instruction) in &self.instruction_processors { + for (id, process_instruction) in &self.programs { let root_program_id = keyed_accounts[0].unsigned_key(); if id == root_program_id { return process_instruction( @@ -1178,8 +1168,7 @@ mod tests { let mock_system_program_id = Pubkey::new(&[2u8; 32]); let rent_collector = RentCollector::default(); let mut message_processor = MessageProcessor::default(); - message_processor - .add_instruction_processor(mock_system_program_id, mock_system_process_instruction); + message_processor.add_program(mock_system_program_id, mock_system_process_instruction); let mut accounts: Vec>> = Vec::new(); let account = Account::new_ref(100, 1, &mock_system_program_id); @@ -1301,8 +1290,7 @@ mod tests { let mock_program_id = Pubkey::new(&[2u8; 32]); let rent_collector = RentCollector::default(); let mut message_processor = MessageProcessor::default(); - message_processor - .add_instruction_processor(mock_program_id, mock_system_process_instruction); + message_processor.add_program(mock_program_id, mock_system_process_instruction); let mut accounts: Vec>> = Vec::new(); let account = Account::new_ref(100, 1, &mock_program_id);