From a2adeb5977772e1394d48c1bcedaae2e6e250eeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Mon, 12 Jun 2023 19:18:44 +0000 Subject: [PATCH] Adds parameter recompile to Bank::load_program(). --- ledger-tool/src/program.rs | 7 +++++-- programs/bpf_loader/src/lib.rs | 20 +++++++++---------- runtime/src/bank.rs | 35 ++++++++++++++++++++++++++-------- runtime/src/bank/tests.rs | 4 ++-- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/ledger-tool/src/program.rs b/ledger-tool/src/program.rs index fc87881d3b3058..4c0df1fe7d71e0 100644 --- a/ledger-tool/src/program.rs +++ b/ledger-tool/src/program.rs @@ -27,6 +27,7 @@ use { account::AccountSharedData, account_utils::StateMut, bpf_loader_upgradeable::{self, UpgradeableLoaderState}, + feature_set, pubkey::Pubkey, slot_history::Slot, transaction_context::{IndexOfAccount, InstructionAccount}, @@ -357,7 +358,9 @@ fn load_program<'a>( #[allow(unused_mut)] let mut verified_executable = if is_elf { let result = load_program_from_bytes( - &invoke_context.feature_set, + invoke_context + .feature_set + .is_active(&feature_set::delay_visibility_of_program_deployment::id()), log_collector, &mut load_program_metrics, &contents, @@ -538,7 +541,7 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) { let mut loaded_programs = LoadedProgramsForTxBatch::new(bank.slot() + DELAY_VISIBILITY_SLOT_OFFSET); for key in cached_account_keys { - loaded_programs.replenish(key, bank.load_program(&key)); + loaded_programs.replenish(key, bank.load_program(&key, None)); debug!("Loaded program {}", key); } invoke_context.programs_loaded_for_tx_batch = &loaded_programs; diff --git a/programs/bpf_loader/src/lib.rs b/programs/bpf_loader/src/lib.rs index 602602b051168d..4c4c3d182c6f3a 100644 --- a/programs/bpf_loader/src/lib.rs +++ b/programs/bpf_loader/src/lib.rs @@ -36,7 +36,7 @@ use { cap_bpf_program_instruction_accounts, delay_visibility_of_program_deployment, enable_bpf_loader_extend_program_ix, enable_bpf_loader_set_authority_checked_ix, enable_program_redeployment_cooldown, limit_max_instruction_trace_length, - native_programs_consume_cu, remove_bpf_loader_incorrect_program_id, FeatureSet, + native_programs_consume_cu, remove_bpf_loader_incorrect_program_id, }, instruction::{AccountMeta, InstructionError}, loader_instruction::LoaderInstruction, @@ -68,7 +68,7 @@ pub const UPGRADEABLE_LOADER_COMPUTE_UNITS: u64 = 2_370; #[allow(clippy::too_many_arguments)] pub fn load_program_from_bytes( - feature_set: &FeatureSet, + delay_visibility_of_program_deployment: bool, log_collector: Option>>, load_program_metrics: &mut LoadProgramMetrics, programdata: &[u8], @@ -77,7 +77,7 @@ pub fn load_program_from_bytes( deployment_slot: Slot, program_runtime_environment: Arc>>, ) -> Result { - let effective_slot = if feature_set.is_active(&delay_visibility_of_program_deployment::id()) { + let effective_slot = if delay_visibility_of_program_deployment { deployment_slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET) } else { deployment_slot @@ -100,12 +100,12 @@ pub fn load_program_from_bytes( } pub fn load_program_from_account( - feature_set: &FeatureSet, + delay_visibility_of_program_deployment: bool, log_collector: Option>>, program: &BorrowedAccount, programdata: &BorrowedAccount, program_runtime_environment: Arc>>, -) -> Result<(Arc, LoadProgramMetrics), InstructionError> { +) -> Result<(LoadedProgram, LoadProgramMetrics), InstructionError> { if !check_loader_id(program.get_owner()) { ic_logger_msg!( log_collector, @@ -149,8 +149,8 @@ pub fn load_program_from_account( ..LoadProgramMetrics::default() }; - let loaded_program = Arc::new(load_program_from_bytes( - feature_set, + let loaded_program = load_program_from_bytes( + delay_visibility_of_program_deployment, log_collector, &mut load_program_metrics, programdata @@ -161,7 +161,7 @@ pub fn load_program_from_account( program.get_data().len().saturating_add(programdata_size), deployment_slot, program_runtime_environment, - )?); + )?; Ok((loaded_program, load_program_metrics)) } @@ -195,7 +195,7 @@ macro_rules! deploy_program { register_syscalls_time.stop(); load_program_metrics.register_syscalls_us = register_syscalls_time.as_us(); let executor = load_program_from_bytes( - &$invoke_context.feature_set, + $invoke_context.feature_set.is_active(&delay_visibility_of_program_deployment::id()), $invoke_context.get_log_collector(), &mut load_program_metrics, $new_programdata, @@ -1731,7 +1731,7 @@ pub mod test_utils { .expect("Failed to get account key"); if let Ok(loaded_program) = load_program_from_bytes( - &FeatureSet::all_enabled(), + true, None, &mut load_program_metrics, account.data(), diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index d89fd7f175cb0a..d31f15bd73df31 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -1734,7 +1734,12 @@ impl Bank { if let Some((_env, ref mut programs_to_recompile)) = &mut loaded_programs_cache.upcoming_program_runtime_environment_v1 { - + if let Some((key, program_to_recompile)) = programs_to_recompile.pop() { + drop(loaded_programs_cache); + let recompiled = new.load_program(&key, Some(program_to_recompile)); + let mut loaded_programs_cache = new.loaded_programs_cache.write().unwrap(); + loaded_programs_cache.replenish(key, recompiled); + } } else if slot_index.saturating_add( solana_program_runtime::loaded_programs::MAX_LOADED_ENTRY_COUNT .checked_div(2) @@ -5138,7 +5143,11 @@ impl Bank { } } - pub fn load_program(&self, pubkey: &Pubkey) -> Arc { + pub fn load_program( + &self, + pubkey: &Pubkey, + recompile: Option>, + ) -> Arc { let program = if let Some(program) = self.get_account_with_fixed_root(pubkey) { program } else { @@ -5207,21 +5216,31 @@ impl Bank { &loaded_programs_cache.program_runtime_environment_v1 }; solana_bpf_loader_program::load_program_from_account( - &self.feature_set, + self.feature_set + .is_active(&feature_set::delay_visibility_of_program_deployment::id()), None, // log_collector &program, programdata.as_ref().unwrap_or(&program), - program_runtime_environment_v1.clone(), + program_runtime_environment.clone(), ) - .map(|(loaded_program, metrics)| { + .map(|(mut loaded_program, metrics)| { let mut timings = ExecuteDetailsTimings::default(); metrics.submit_datapoint(&mut timings); - loaded_program + if let Some(recompile) = recompile { + loaded_program.effective_slot = self + .epoch_schedule() + .get_first_slot_in_epoch(self.epoch.saturating_add(1)); + loaded_program.tx_usage_counter = + AtomicU64::new(recompile.tx_usage_counter.load(Ordering::Relaxed)); + loaded_program.ix_usage_counter = + AtomicU64::new(recompile.ix_usage_counter.load(Ordering::Relaxed)); + } + Arc::new(loaded_program) }) .unwrap_or_else(|_| { Arc::new(LoadedProgram::new_tombstone( self.slot, - LoadedProgramType::FailedVerification(program_runtime_environment_v1), + LoadedProgramType::FailedVerification(program_runtime_environment.clone()), )) }) } @@ -5469,7 +5488,7 @@ impl Bank { let missing_programs: Vec<(Pubkey, Arc)> = missing_programs .iter() .map(|(key, count)| { - let program = self.load_program(key); + let program = self.load_program(key, None); program.tx_usage_counter.store(*count, Ordering::Relaxed); (*key, program) }) diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index 70c423d17e33d6..3e832033177bbb 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -7416,7 +7416,7 @@ fn test_bank_load_program() { programdata_account.set_rent_epoch(1); bank.store_account_and_update_capitalization(&key1, &program_account); bank.store_account_and_update_capitalization(&programdata_key, &programdata_account); - let program = bank.load_program(&key1); + let program = bank.load_program(&key1, None); assert!(matches!(program.program, LoadedProgramType::LegacyV1(_))); assert_eq!( program.account_size, @@ -7571,7 +7571,7 @@ fn test_bpf_loader_upgradeable_deploy_with_max_len() { assert_eq!(*elf.get(i).unwrap(), *byte); } - let loaded_program = bank.load_program(&program_keypair.pubkey()); + let loaded_program = bank.load_program(&program_keypair.pubkey(), None); // Invoke deployed program mock_process_instruction(