From e1eb21dd206612854e52dec775384a1075ab89b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 24 Apr 2023 14:44:40 +0200 Subject: [PATCH] Moves BuiltinPrograms from bank.rs into the program runtime. --- program-runtime/src/builtin_program.rs | 27 +++++++++++++++++ program-runtime/src/invoke_context.rs | 41 ++++++++++---------------- program-test/src/lib.rs | 34 ++++++++++----------- runtime/src/bank.rs | 16 ++-------- runtime/src/message_processor.rs | 37 ++++++++--------------- 5 files changed, 74 insertions(+), 81 deletions(-) diff --git a/program-runtime/src/builtin_program.rs b/program-runtime/src/builtin_program.rs index a67e8aed3ce36c..cd876c3e81cf47 100644 --- a/program-runtime/src/builtin_program.rs +++ b/program-runtime/src/builtin_program.rs @@ -35,3 +35,30 @@ impl AbiExample for BuiltinProgram { } } } + +#[derive(Debug, Clone, Default)] +pub struct BuiltinPrograms { + pub vec: Vec, +} + +#[cfg(RUSTC_WITH_SPECIALIZATION)] +impl AbiExample for BuiltinPrograms { + fn example() -> Self { + Self::default() + } +} + +impl BuiltinPrograms { + pub fn new_mock( + program_id: Pubkey, + process_instruction: ProcessInstructionWithContext, + ) -> Self { + Self { + vec: vec![BuiltinProgram { + name: "mock instruction processor".to_string(), + program_id, + process_instruction, + }], + } + } +} diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 605126e0994b0d..d13104d948a896 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -1,7 +1,7 @@ use { crate::{ accounts_data_meter::AccountsDataMeter, - builtin_program::{BuiltinProgram, ProcessInstructionWithContext}, + builtin_program::{BuiltinPrograms, ProcessInstructionWithContext}, compute_budget::ComputeBudget, executor_cache::TransactionExecutorCache, ic_logger_msg, ic_msg, @@ -152,7 +152,7 @@ pub struct InvokeContext<'a> { pub transaction_context: &'a mut TransactionContext, rent: Rent, pre_accounts: Vec, - builtin_programs: &'a [BuiltinProgram], + builtin_programs: &'a BuiltinPrograms, sysvar_cache: &'a SysvarCache, log_collector: Option>>, compute_budget: ComputeBudget, @@ -172,7 +172,7 @@ impl<'a> InvokeContext<'a> { pub fn new( transaction_context: &'a mut TransactionContext, rent: Rent, - builtin_programs: &'a [BuiltinProgram], + builtin_programs: &'a BuiltinPrograms, sysvar_cache: &'a SysvarCache, log_collector: Option>>, compute_budget: ComputeBudget, @@ -714,7 +714,7 @@ impl<'a> InvokeContext<'a> { } }; - for entry in self.builtin_programs { + for entry in self.builtin_programs.vec.iter() { if entry.program_id == builtin_id { let program_id = *instruction_context.get_last_program_key(self.transaction_context)?; @@ -877,9 +877,9 @@ macro_rules! with_mock_invoke_context { }, std::{cell::RefCell, rc::Rc, sync::Arc}, $crate::{ - compute_budget::ComputeBudget, executor_cache::TransactionExecutorCache, - invoke_context::InvokeContext, log_collector::LogCollector, - sysvar_cache::SysvarCache, + builtin_program::BuiltinPrograms, compute_budget::ComputeBudget, + executor_cache::TransactionExecutorCache, invoke_context::InvokeContext, + log_collector::LogCollector, sysvar_cache::SysvarCache, }, }; let compute_budget = ComputeBudget::default(); @@ -890,6 +890,7 @@ macro_rules! with_mock_invoke_context { compute_budget.max_instruction_trace_length, ); $transaction_context.enable_cap_accounts_data_allocations_per_transaction(); + let builtin_programs = BuiltinPrograms::default(); let mut sysvar_cache = SysvarCache::default(); sysvar_cache.fill_missing_entries(|pubkey, callback| { for index in 0..$transaction_context.get_number_of_accounts() { @@ -911,7 +912,7 @@ macro_rules! with_mock_invoke_context { let mut $invoke_context = InvokeContext::new( &mut $transaction_context, Rent::default(), - &[], + &builtin_programs, &sysvar_cache, Some(LogCollector::new_ref()), compute_budget, @@ -963,12 +964,8 @@ pub fn mock_process_instruction>(); with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts); - let builtin_programs = &[BuiltinProgram { - name: "mock instruction processor".to_string(), - program_id: callee_program_id, - process_instruction, - }]; - invoke_context.builtin_programs = builtin_programs; + let builtin_programs = BuiltinPrograms::new_mock(callee_program_id, process_instruction); + invoke_context.builtin_programs = &builtin_programs; // Account modification tests let cases = vec![ @@ -1363,12 +1356,8 @@ mod tests { }, ]; with_mock_invoke_context!(invoke_context, transaction_context, transaction_accounts); - let builtin_programs = &[BuiltinProgram { - name: "mock instruction processor".to_string(), - program_id: program_key, - process_instruction, - }]; - invoke_context.builtin_programs = builtin_programs; + let builtin_programs = BuiltinPrograms::new_mock(program_key, process_instruction); + invoke_context.builtin_programs = &builtin_programs; // Test: Resize the account to *the same size*, so not consuming any additional size; this must succeed { diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index ab87bbd6a3766a..13f6e8b082fb64 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -11,14 +11,15 @@ use { solana_banks_server::banks_server::start_local_server, solana_bpf_loader_program::serialization::serialize_parameters, solana_program_runtime::{ - compute_budget::ComputeBudget, ic_msg, invoke_context::ProcessInstructionWithContext, - stable_log, timings::ExecuteTimings, + builtin_program::{BuiltinProgram, BuiltinPrograms, ProcessInstructionWithContext}, + compute_budget::ComputeBudget, + ic_msg, stable_log, + timings::ExecuteTimings, }, solana_runtime::{ accounts_background_service::{AbsRequestSender, SnapshotRequestType}, bank::Bank, bank_forks::BankForks, - builtins::Builtin, commitment::BlockCommitmentCache, epoch_accounts_hash::EpochAccountsHash, genesis_utils::{create_genesis_config_with_leader_ex, GenesisConfigInfo}, @@ -436,7 +437,7 @@ pub fn read_file>(path: P) -> Vec { pub struct ProgramTest { accounts: Vec<(Pubkey, AccountSharedData)>, - builtins: Vec, + builtin_programs: BuiltinPrograms, compute_max_units: Option, prefer_bpf: bool, use_bpf_jit: bool, @@ -474,7 +475,7 @@ impl Default for ProgramTest { Self { accounts: vec![], - builtins: vec![], + builtin_programs: BuiltinPrograms::default(), compute_max_units: None, prefer_bpf, use_bpf_jit: false, @@ -628,12 +629,6 @@ impl ProgramTest { ); }; - let add_native = |this: &mut ProgramTest, process_fn: ProcessInstructionWithContext| { - info!("\"{}\" program loaded as native code", program_name); - this.builtins - .push(Builtin::new(program_name, program_id, process_fn)); - }; - let warn_invalid_program_name = || { let valid_program_names = default_shared_object_dirs() .iter() @@ -679,7 +674,9 @@ impl ProgramTest { // processor function as is. // // TODO: figure out why tests hang if a processor panics when running native code. - (false, _, Some(process)) => add_native(self, process), + (false, _, Some(process)) => { + self.add_builtin_program(program_name, program_id, process) + } // Invalid: `test-sbf` invocation with no matching SBF shared object. (true, None, _) => { @@ -704,8 +701,11 @@ impl ProgramTest { process_instruction: ProcessInstructionWithContext, ) { info!("\"{}\" builtin program", program_name); - self.builtins - .push(Builtin::new(program_name, program_id, process_instruction)); + self.builtin_programs.vec.push(BuiltinProgram { + name: program_name.to_string(), + program_id, + process_instruction, + }); } /// Deactivate a runtime feature. @@ -816,11 +816,11 @@ impl ProgramTest { } // User-supplied additional builtins - for builtin in self.builtins.iter() { + for builtin in self.builtin_programs.vec.iter() { bank.add_builtin( &builtin.name, - &builtin.id, - builtin.process_instruction_with_context, + &builtin.program_id, + builtin.process_instruction, ); } diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 3f8417684be0a6..4b547b846ff611 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -94,7 +94,7 @@ use { solana_perf::perf_libs, solana_program_runtime::{ accounts_data_meter::MAX_ACCOUNTS_DATA_LEN, - builtin_program::{BuiltinProgram, ProcessInstructionWithContext}, + builtin_program::{BuiltinProgram, BuiltinPrograms, ProcessInstructionWithContext}, compute_budget::{self, ComputeBudget}, executor_cache::{BankExecutorCache, TransactionExecutorCache, MAX_CACHED_EXECUTORS}, loaded_programs::{LoadedProgram, LoadedProgramType, LoadedPrograms, WorkingSlot}, @@ -887,18 +887,6 @@ impl AbiExample for OptionalDropCallback { } } -#[derive(Debug, Clone, Default)] -pub struct BuiltinPrograms { - pub vec: Vec, -} - -#[cfg(RUSTC_WITH_SPECIALIZATION)] -impl AbiExample for BuiltinPrograms { - fn example() -> Self { - Self::default() - } -} - /// Manager for the state of all accounts and programs after processing its entries. /// AbiExample is needed even without Serialize/Deserialize; actual (de-)serialization /// are implemented elsewhere for versioning @@ -4282,7 +4270,7 @@ impl Bank { let mut process_message_time = Measure::start("process_message_time"); let process_result = MessageProcessor::process_message( - &self.builtin_programs.vec, + &self.builtin_programs, tx.message(), &loaded_transaction.program_indices, &mut transaction_context, diff --git a/runtime/src/message_processor.rs b/runtime/src/message_processor.rs index 53b3e3c58606e1..044314fdf78fbc 100644 --- a/runtime/src/message_processor.rs +++ b/runtime/src/message_processor.rs @@ -2,7 +2,7 @@ use { serde::{Deserialize, Serialize}, solana_measure::measure::Measure, solana_program_runtime::{ - builtin_program::BuiltinProgram, + builtin_program::BuiltinPrograms, compute_budget::ComputeBudget, executor_cache::TransactionExecutorCache, invoke_context::InvokeContext, @@ -52,7 +52,7 @@ impl MessageProcessor { /// The accounts are committed back to the bank only if every instruction succeeds. #[allow(clippy::too_many_arguments)] pub fn process_message( - builtin_programs: &[BuiltinProgram], + builtin_programs: &BuiltinPrograms, message: &SanitizedMessage, program_indices: &[Vec], transaction_context: &mut TransactionContext, @@ -252,11 +252,8 @@ mod tests { let mock_system_program_id = Pubkey::new_unique(); let rent_collector = RentCollector::default(); - let builtin_programs = &[BuiltinProgram { - name: "mock instruction processor".to_string(), - program_id: mock_system_program_id, - process_instruction, - }]; + let builtin_programs = + BuiltinPrograms::new_mock(mock_system_program_id, process_instruction); let accounts = vec![ ( @@ -305,7 +302,7 @@ mod tests { ))); let sysvar_cache = SysvarCache::default(); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &program_indices, &mut transaction_context, @@ -355,7 +352,7 @@ mod tests { ]), ))); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &program_indices, &mut transaction_context, @@ -395,7 +392,7 @@ mod tests { ]), ))); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &program_indices, &mut transaction_context, @@ -480,11 +477,7 @@ mod tests { let mock_program_id = Pubkey::from([2u8; 32]); let rent_collector = RentCollector::default(); - let builtin_programs = &[BuiltinProgram { - name: "mock instruction processor".to_string(), - program_id: mock_program_id, - process_instruction, - }]; + let builtin_programs = BuiltinPrograms::new_mock(mock_program_id, process_instruction); let accounts = vec![ ( @@ -530,7 +523,7 @@ mod tests { ))); let sysvar_cache = SysvarCache::default(); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &program_indices, &mut transaction_context, @@ -564,7 +557,7 @@ mod tests { Some(transaction_context.get_key_of_account_at_index(0).unwrap()), ))); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &program_indices, &mut transaction_context, @@ -595,7 +588,7 @@ mod tests { Some(transaction_context.get_key_of_account_at_index(0).unwrap()), ))); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &program_indices, &mut transaction_context, @@ -644,11 +637,7 @@ mod tests { declare_process_instruction!(process_instruction, 1, |_invoke_context| { Err(InstructionError::Custom(0xbabb1e)) }); - let builtin_programs = &[BuiltinProgram { - name: "mock instruction processor".to_string(), - program_id: mock_program_id, - process_instruction, - }]; + let builtin_programs = BuiltinPrograms::new_mock(mock_program_id, process_instruction); let mut secp256k1_account = AccountSharedData::new(1, 0, &native_loader::id()); secp256k1_account.set_executable(true); @@ -673,7 +662,7 @@ mod tests { ))); let sysvar_cache = SysvarCache::default(); let result = MessageProcessor::process_message( - builtin_programs, + &builtin_programs, &message, &[vec![0], vec![1]], &mut transaction_context,