| @@ -86,7 +86,7 @@ fn test_exchange_bank_client() { | |||||||
|     solana_logger::setup(); |     solana_logger::setup(); | ||||||
|     let (genesis_config, identity) = create_genesis_config(100_000_000_000_000); |     let (genesis_config, identity) = create_genesis_config(100_000_000_000_000); | ||||||
|     let mut bank = Bank::new(&genesis_config); |     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 clients = vec![BankClient::new(bank)]; | ||||||
|  |  | ||||||
|     let mut config = Config::default(); |     let mut config = Config::default(); | ||||||
|   | |||||||
| @@ -238,7 +238,7 @@ mod tests { | |||||||
|     fn create_bank(lamports: u64) -> (Bank, Keypair) { |     fn create_bank(lamports: u64) -> (Bank, Keypair) { | ||||||
|         let (genesis_config, mint_keypair) = create_genesis_config(lamports); |         let (genesis_config, mint_keypair) = create_genesis_config(lamports); | ||||||
|         let mut bank = Bank::new(&genesis_config); |         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) |         (bank, mint_keypair) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -578,7 +578,7 @@ mod test { | |||||||
|     fn create_bank(lamports: u64) -> (Bank, Keypair) { |     fn create_bank(lamports: u64) -> (Bank, Keypair) { | ||||||
|         let (genesis_config, mint_keypair) = create_genesis_config(lamports); |         let (genesis_config, mint_keypair) = create_genesis_config(lamports); | ||||||
|         let mut bank = Bank::new(&genesis_config); |         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) |         (bank, mint_keypair) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -71,7 +71,7 @@ mod tests { | |||||||
|     fn create_bank(lamports: u64) -> (Bank, Keypair) { |     fn create_bank(lamports: u64) -> (Bank, Keypair) { | ||||||
|         let (genesis_config, mint_keypair) = create_genesis_config(lamports); |         let (genesis_config, mint_keypair) = create_genesis_config(lamports); | ||||||
|         let mut bank = Bank::new(&genesis_config); |         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) |         (bank, mint_keypair) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -161,7 +161,7 @@ mod tests { | |||||||
|     fn create_bank(lamports: u64) -> (Bank, Keypair) { |     fn create_bank(lamports: u64) -> (Bank, Keypair) { | ||||||
|         let (genesis_config, mint_keypair) = create_genesis_config(lamports); |         let (genesis_config, mint_keypair) = create_genesis_config(lamports); | ||||||
|         let mut bank = Bank::new(&genesis_config); |         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) |         (bank, mint_keypair) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -122,7 +122,7 @@ fn do_bench_transactions( | |||||||
|     let (mut genesis_config, mint_keypair) = create_genesis_config(100_000_000); |     let (mut genesis_config, mint_keypair) = create_genesis_config(100_000_000); | ||||||
|     genesis_config.ticks_per_slot = 100; |     genesis_config.ticks_per_slot = 100; | ||||||
|     let mut bank = Bank::new(&genesis_config); |     let mut bank = Bank::new(&genesis_config); | ||||||
|     bank.add_static_program( |     bank.add_builtin_program( | ||||||
|         "builtin_program", |         "builtin_program", | ||||||
|         Pubkey::new(&BUILTIN_PROGRAM_ID), |         Pubkey::new(&BUILTIN_PROGRAM_ID), | ||||||
|         process_instruction, |         process_instruction, | ||||||
|   | |||||||
| @@ -10,13 +10,14 @@ use crate::{ | |||||||
|     accounts_db::{AccountsDBSerialize, ErrorCounters, SnapshotStorage, SnapshotStorages}, |     accounts_db::{AccountsDBSerialize, ErrorCounters, SnapshotStorage, SnapshotStorages}, | ||||||
|     accounts_index::Ancestors, |     accounts_index::Ancestors, | ||||||
|     blockhash_queue::BlockhashQueue, |     blockhash_queue::BlockhashQueue, | ||||||
|  |     builtin_programs::get_builtin_programs, | ||||||
|     epoch_stakes::{EpochStakes, NodeVoteAccounts}, |     epoch_stakes::{EpochStakes, NodeVoteAccounts}, | ||||||
|     message_processor::{MessageProcessor, ProcessInstruction}, |     message_processor::{MessageProcessor, ProcessInstruction}, | ||||||
|     nonce_utils, |     nonce_utils, | ||||||
|     rent_collector::RentCollector, |     rent_collector::RentCollector, | ||||||
|     stakes::Stakes, |     stakes::Stakes, | ||||||
|     status_cache::{SlotDelta, StatusCache}, |     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_batch::TransactionBatch, | ||||||
|     transaction_utils::OrderedIterator, |     transaction_utils::OrderedIterator, | ||||||
| }; | }; | ||||||
| @@ -2086,26 +2087,10 @@ impl Bank { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn finish_init(&mut self) { |     pub fn finish_init(&mut self) { | ||||||
|         self.add_static_program( |         let builtin_programs = get_builtin_programs(); | ||||||
|             "system_program", |         for program in builtin_programs.iter() { | ||||||
|             solana_sdk::system_program::id(), |             self.add_builtin_program(&program.name, program.id, program.process_instruction); | ||||||
|             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, |  | ||||||
|         ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     pub fn set_parent(&mut self, parent: &Arc<Bank>) { |     pub fn set_parent(&mut self, parent: &Arc<Bank>) { | ||||||
| @@ -2488,7 +2473,7 @@ impl Bank { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /// Add an instruction processor to intercept instructions before the dynamic loader. |     /// Add an instruction processor to intercept instructions before the dynamic loader. | ||||||
|     pub fn add_static_program( |     pub fn add_builtin_program( | ||||||
|         &mut self, |         &mut self, | ||||||
|         name: &str, |         name: &str, | ||||||
|         program_id: Pubkey, |         program_id: Pubkey, | ||||||
| @@ -2509,7 +2494,7 @@ impl Bank { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         self.message_processor |         self.message_processor | ||||||
|             .add_instruction_processor(program_id, process_instruction); |             .add_program(program_id, process_instruction); | ||||||
|         debug!("Added static program {} under {:?}", name, program_id); |         debug!("Added static program {} under {:?}", name, program_id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -3051,7 +3036,7 @@ mod tests { | |||||||
|             ) as u64, |             ) as u64, | ||||||
|         ); |         ); | ||||||
|         bank.rent_collector.slots_per_year = 421_812.0; |         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 |         bank | ||||||
|     } |     } | ||||||
| @@ -5904,7 +5889,7 @@ mod tests { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_add_static_program() { |     fn test_add_builtin_program() { | ||||||
|         let (genesis_config, mint_keypair) = create_genesis_config(500); |         let (genesis_config, mint_keypair) = create_genesis_config(500); | ||||||
|         let mut bank = Bank::new(&genesis_config); |         let mut bank = Bank::new(&genesis_config); | ||||||
|  |  | ||||||
| @@ -5923,7 +5908,7 @@ mod tests { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         assert!(bank.get_account(&mock_vote_program_id()).is_none()); |         assert!(bank.get_account(&mock_vote_program_id()).is_none()); | ||||||
|         bank.add_static_program( |         bank.add_builtin_program( | ||||||
|             "mock_vote_program", |             "mock_vote_program", | ||||||
|             mock_vote_program_id(), |             mock_vote_program_id(), | ||||||
|             mock_vote_processor, |             mock_vote_processor, | ||||||
| @@ -5994,7 +5979,7 @@ mod tests { | |||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         let vote_loader_account = bank.get_account(&solana_vote_program::id()).unwrap(); |         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", | ||||||
|             solana_vote_program::id(), |             solana_vote_program::id(), | ||||||
|             mock_vote_processor, |             mock_vote_processor, | ||||||
| @@ -6026,7 +6011,7 @@ mod tests { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         // Non-native loader accounts can not be used for instruction processing |         // 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] |     #[test] | ||||||
|     fn test_recent_blockhashes_sysvar() { |     fn test_recent_blockhashes_sysvar() { | ||||||
| @@ -6578,7 +6563,7 @@ mod tests { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         let mock_program_id = Pubkey::new(&[2u8; 32]); |         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 from_pubkey = Pubkey::new_rand(); | ||||||
|         let to_pubkey = Pubkey::new_rand(); |         let to_pubkey = Pubkey::new_rand(); | ||||||
| @@ -6621,7 +6606,7 @@ mod tests { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         let mock_program_id = Pubkey::new(&[2u8; 32]); |         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 from_pubkey = Pubkey::new_rand(); | ||||||
|         let to_pubkey = Pubkey::new_rand(); |         let to_pubkey = Pubkey::new_rand(); | ||||||
| @@ -6673,7 +6658,7 @@ mod tests { | |||||||
|  |  | ||||||
|         tx.message.account_keys.push(Pubkey::new_rand()); |         tx.message.account_keys.push(Pubkey::new_rand()); | ||||||
|  |  | ||||||
|         bank.add_static_program( |         bank.add_builtin_program( | ||||||
|             "mock_vote", |             "mock_vote", | ||||||
|             solana_vote_program::id(), |             solana_vote_program::id(), | ||||||
|             mock_ok_vote_processor, |             mock_ok_vote_processor, | ||||||
| @@ -6727,7 +6712,7 @@ mod tests { | |||||||
|             AccountMeta::new(to_pubkey, false), |             AccountMeta::new(to_pubkey, false), | ||||||
|         ]; |         ]; | ||||||
|  |  | ||||||
|         bank.add_static_program( |         bank.add_builtin_program( | ||||||
|             "mock_vote", |             "mock_vote", | ||||||
|             solana_vote_program::id(), |             solana_vote_program::id(), | ||||||
|             mock_ok_vote_processor, |             mock_ok_vote_processor, | ||||||
| @@ -6760,7 +6745,7 @@ mod tests { | |||||||
|             AccountMeta::new(to_pubkey, false), |             AccountMeta::new(to_pubkey, false), | ||||||
|         ]; |         ]; | ||||||
|  |  | ||||||
|         bank.add_static_program( |         bank.add_builtin_program( | ||||||
|             "mock_vote", |             "mock_vote", | ||||||
|             solana_vote_program::id(), |             solana_vote_program::id(), | ||||||
|             mock_ok_vote_processor, |             mock_ok_vote_processor, | ||||||
| @@ -6815,7 +6800,7 @@ mod tests { | |||||||
|             AccountMeta::new(to_pubkey, false), |             AccountMeta::new(to_pubkey, false), | ||||||
|         ]; |         ]; | ||||||
|  |  | ||||||
|         bank.add_static_program( |         bank.add_builtin_program( | ||||||
|             "mock_vote", |             "mock_vote", | ||||||
|             solana_vote_program::id(), |             solana_vote_program::id(), | ||||||
|             mock_ok_vote_processor, |             mock_ok_vote_processor, | ||||||
| @@ -6851,7 +6836,7 @@ mod tests { | |||||||
|             .map(|i| { |             .map(|i| { | ||||||
|                 let key = Pubkey::new_rand(); |                 let key = Pubkey::new_rand(); | ||||||
|                 let name = format!("program{:?}", i); |                 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()) |                 (key, name.as_bytes().to_vec()) | ||||||
|             }) |             }) | ||||||
|             .collect(); |             .collect(); | ||||||
|   | |||||||
							
								
								
									
										42
									
								
								runtime/src/builtin_programs.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								runtime/src/builtin_programs.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -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<BuiltinProgram> { | ||||||
|  |     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, | ||||||
|  |         ), | ||||||
|  |     ] | ||||||
|  | } | ||||||
| @@ -6,6 +6,7 @@ pub mod bank; | |||||||
| pub mod bank_client; | pub mod bank_client; | ||||||
| mod blockhash_queue; | mod blockhash_queue; | ||||||
| pub mod bloom; | pub mod bloom; | ||||||
|  | pub mod builtin_programs; | ||||||
| pub mod epoch_stakes; | pub mod epoch_stakes; | ||||||
| pub mod genesis_utils; | pub mod genesis_utils; | ||||||
| pub mod loader_utils; | pub mod loader_utils; | ||||||
|   | |||||||
| @@ -243,34 +243,24 @@ pub type ProcessInstructionWithContext = | |||||||
| #[derive(Default, Deserialize, Serialize)] | #[derive(Default, Deserialize, Serialize)] | ||||||
| pub struct MessageProcessor { | pub struct MessageProcessor { | ||||||
|     #[serde(skip)] |     #[serde(skip)] | ||||||
|     instruction_processors: Vec<(Pubkey, ProcessInstruction)>, |     programs: Vec<(Pubkey, ProcessInstruction)>, | ||||||
|     #[serde(skip)] |     #[serde(skip)] | ||||||
|     native_loader: NativeLoader, |     native_loader: NativeLoader, | ||||||
| } | } | ||||||
| impl Clone for MessageProcessor { | impl Clone for MessageProcessor { | ||||||
|     fn clone(&self) -> Self { |     fn clone(&self) -> Self { | ||||||
|         MessageProcessor { |         MessageProcessor { | ||||||
|             instruction_processors: self.instruction_processors.clone(), |             programs: self.programs.clone(), | ||||||
|             native_loader: NativeLoader::default(), |             native_loader: NativeLoader::default(), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| impl MessageProcessor { | impl MessageProcessor { | ||||||
|     /// Add a static entrypoint to intercept instructions before the dynamic loader. |     /// Add a static entrypoint to intercept instructions before the dynamic loader. | ||||||
|     pub fn add_instruction_processor( |     pub fn add_program(&mut self, program_id: Pubkey, process_instruction: ProcessInstruction) { | ||||||
|         &mut self, |         match self.programs.iter_mut().find(|(key, _)| program_id == *key) { | ||||||
|         program_id: Pubkey, |  | ||||||
|         process_instruction: ProcessInstruction, |  | ||||||
|     ) { |  | ||||||
|         match self |  | ||||||
|             .instruction_processors |  | ||||||
|             .iter_mut() |  | ||||||
|             .find(|(key, _)| program_id == *key) |  | ||||||
|         { |  | ||||||
|             Some((_, processor)) => *processor = process_instruction, |             Some((_, processor)) => *processor = process_instruction, | ||||||
|             None => self |             None => self.programs.push((program_id, process_instruction)), | ||||||
|                 .instruction_processors |  | ||||||
|                 .push((program_id, process_instruction)), |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -315,7 +305,7 @@ impl MessageProcessor { | |||||||
|         let keyed_accounts = |         let keyed_accounts = | ||||||
|             Self::create_keyed_accounts(message, instruction, executable_accounts, 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(); |             let root_program_id = keyed_accounts[0].unsigned_key(); | ||||||
|             if id == root_program_id { |             if id == root_program_id { | ||||||
|                 return process_instruction( |                 return process_instruction( | ||||||
| @@ -1178,8 +1168,7 @@ mod tests { | |||||||
|         let mock_system_program_id = Pubkey::new(&[2u8; 32]); |         let mock_system_program_id = Pubkey::new(&[2u8; 32]); | ||||||
|         let rent_collector = RentCollector::default(); |         let rent_collector = RentCollector::default(); | ||||||
|         let mut message_processor = MessageProcessor::default(); |         let mut message_processor = MessageProcessor::default(); | ||||||
|         message_processor |         message_processor.add_program(mock_system_program_id, mock_system_process_instruction); | ||||||
|             .add_instruction_processor(mock_system_program_id, mock_system_process_instruction); |  | ||||||
|  |  | ||||||
|         let mut accounts: Vec<Rc<RefCell<Account>>> = Vec::new(); |         let mut accounts: Vec<Rc<RefCell<Account>>> = Vec::new(); | ||||||
|         let account = Account::new_ref(100, 1, &mock_system_program_id); |         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 mock_program_id = Pubkey::new(&[2u8; 32]); | ||||||
|         let rent_collector = RentCollector::default(); |         let rent_collector = RentCollector::default(); | ||||||
|         let mut message_processor = MessageProcessor::default(); |         let mut message_processor = MessageProcessor::default(); | ||||||
|         message_processor |         message_processor.add_program(mock_program_id, mock_system_process_instruction); | ||||||
|             .add_instruction_processor(mock_program_id, mock_system_process_instruction); |  | ||||||
|  |  | ||||||
|         let mut accounts: Vec<Rc<RefCell<Account>>> = Vec::new(); |         let mut accounts: Vec<Rc<RefCell<Account>>> = Vec::new(); | ||||||
|         let account = Account::new_ref(100, 1, &mock_program_id); |         let account = Account::new_ref(100, 1, &mock_program_id); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user