Skip to content

Commit

Permalink
Adds parameter recompile to Bank::load_program().
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed Aug 17, 2023
1 parent cc305bd commit 63474b9
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 13 deletions.
2 changes: 1 addition & 1 deletion ledger-tool/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ pub fn program(ledger_path: &Path, matches: &ArgMatches<'_>) {
.clone(),
);
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;
Expand Down
53 changes: 43 additions & 10 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1445,8 +1445,16 @@ impl Bank {
new.update_epoch_stakes(leader_schedule_epoch);
// Recompile loaded programs one at a time before the next epoch hits
let (_epoch, slot_index) = new.get_epoch_and_slot_index(new.slot());
let loaded_programs_cache = new.loaded_programs_cache.write().unwrap();
let mut loaded_programs_cache = new.loaded_programs_cache.write().unwrap();
if !loaded_programs_cache.programs_to_recompile.is_empty() {
if let Some((key, program_to_recompile)) =
loaded_programs_cache.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)
Expand Down Expand Up @@ -4699,20 +4707,34 @@ impl Bank {
ProgramAccountLoadResult::InvalidAccountData
}

pub fn load_program(&self, pubkey: &Pubkey) -> Arc<LoadedProgram> {
pub fn load_program(
&self,
pubkey: &Pubkey,
recompile: Option<Arc<LoadedProgram>>,
) -> Arc<LoadedProgram> {
let environments = self
.loaded_programs_cache
.read()
.unwrap()
.environments
.clone();
let program_runtime_environment_v1 = if recompile.is_some() {
environments.upcoming_program_runtime_v1.as_ref().unwrap()
} else {
&environments.program_runtime_v1
};
let program_runtime_environment_v2 = if recompile.is_some() {
environments.upcoming_program_runtime_v2.as_ref().unwrap()
} else {
&environments.program_runtime_v2
};

let mut load_program_metrics = LoadProgramMetrics {
program_id: pubkey.to_string(),
..LoadProgramMetrics::default()
};

let loaded_program = match self.load_program_accounts(pubkey) {
let mut loaded_program = match self.load_program_accounts(pubkey) {
ProgramAccountLoadResult::AccountNotFound => Ok(LoadedProgram::new_tombstone(
self.slot,
LoadedProgramType::Closed,
Expand All @@ -4732,7 +4754,7 @@ impl Bank {
program_account.owner(),
program_account.data().len(),
0,
environments.program_runtime_v1.clone(),
program_runtime_environment_v1.clone(),
)
}

Expand All @@ -4757,7 +4779,7 @@ impl Bank {
.len()
.saturating_add(programdata_account.data().len()),
slot,
environments.program_runtime_v1.clone(),
program_runtime_environment_v1.clone(),
)
}),

Expand All @@ -4768,7 +4790,7 @@ impl Bank {
.and_then(|elf_bytes| {
LoadedProgram::new(
&loader_v4::id(),
environments.program_runtime_v2.clone(),
program_runtime_environment_v2.clone(),
slot,
slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET),
None,
Expand All @@ -4780,25 +4802,36 @@ impl Bank {
})
.unwrap_or(LoadedProgram::new_tombstone(
self.slot,
LoadedProgramType::FailedVerification(environments.program_runtime_v2),
LoadedProgramType::FailedVerification(
program_runtime_environment_v2.clone(),
),
));
Ok(loaded_program)
}

ProgramAccountLoadResult::InvalidV4Program => Ok(LoadedProgram::new_tombstone(
self.slot,
LoadedProgramType::FailedVerification(environments.program_runtime_v2),
LoadedProgramType::FailedVerification(program_runtime_environment_v2.clone()),
)),
}
.unwrap_or_else(|_| {
LoadedProgram::new_tombstone(
self.slot,
LoadedProgramType::FailedVerification(environments.program_runtime_v1),
LoadedProgramType::FailedVerification(program_runtime_environment_v1.clone()),
)
});

let mut timings = ExecuteDetailsTimings::default();
load_program_metrics.submit_datapoint(&mut timings);
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)
}

Expand Down Expand Up @@ -5042,7 +5075,7 @@ impl Bank {
let missing_programs: Vec<(Pubkey, Arc<LoadedProgram>)> = 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)
})
Expand Down
4 changes: 2 additions & 2 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7231,7 +7231,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,
Expand Down Expand Up @@ -7386,7 +7386,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(
Expand Down

0 comments on commit 63474b9

Please sign in to comment.