Skip to content

Commit

Permalink
load accounts for upgradeable programs
Browse files Browse the repository at this point in the history
  • Loading branch information
pgarg66 committed Mar 15, 2023
1 parent 66f1c22 commit 538acbe
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 33 deletions.
37 changes: 12 additions & 25 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,39 +454,26 @@ fn process_instruction_common(
ic_logger_msg!(log_collector, "Program is not executable");
return Err(InstructionError::IncorrectProgramId);
}
let programdata_account = if bpf_loader_upgradeable::check_id(program_account.get_owner()) {
instruction_context
.try_borrow_program_account(
transaction_context,
instruction_context
.get_number_of_program_accounts()
.saturating_sub(2),
)
.ok()
} else {
None
};

let mut get_or_create_executor_time = Measure::start("get_or_create_executor_time");
let (executor, load_program_metrics) = load_program_from_account(
&invoke_context.feature_set,
invoke_context.get_compute_budget(),
log_collector,
Some(invoke_context.tx_executor_cache.borrow_mut()),
&program_account,
programdata_account.as_ref().unwrap_or(&program_account),
use_jit,
)?;
let executor = invoke_context
.tx_executor_cache
.borrow()
.get(program_account.get_key())
.expect("Failed to find the program in the cache");

if executor.is_tombstone() {
// We cached that the Executor does not exist, abort
// This case can only happen once delay_visibility_of_program_deployment is active.
return Err(InstructionError::InvalidAccountData);
}

drop(program_account);
drop(programdata_account);
get_or_create_executor_time.stop();
saturating_add_assign!(
invoke_context.timings.get_or_create_executor_us,
get_or_create_executor_time.as_us()
);
if let Some(load_program_metrics) = load_program_metrics {
load_program_metrics.submit_datapoint(&mut invoke_context.timings);
}
match &executor.program {
LoadedProgramType::Invalid => Err(InstructionError::InvalidAccountData),
LoadedProgramType::LegacyV0(executable) => execute(executable, invoke_context),
Expand Down
19 changes: 11 additions & 8 deletions runtime/src/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -359,19 +359,22 @@ impl Accounts {
.is_active(&feature_set::instructions_sysvar_owned_by_sysvar::id()),
)
} else {
let upgradeable_program = program_accounts
.get(key)
.map_or(false, |owner| bpf_loader_upgradeable::check_id(owner));
let (account_size, mut account, rent) = if let Some(account_override) =
account_overrides.and_then(|overrides| overrides.get(key))
{
(account_override.data().len(), account_override.clone(), 0)
} else if let Some(program) =
loaded_programs.get(key).and_then(|maybe_program| {
// Return the program if it's not a tombstone.
// (If it's a tombstone let's return None, so that it can be loaded as a data account.
// Upgradeable loader could own data accounts, which do not contain executables.)
(!message.is_writable(i) && !maybe_program.is_tombstone())
.then_some(maybe_program)
})
} else if let Some(program) = (!upgradeable_program && !message.is_writable(i))
.then_some(())
.and_then(|_| loaded_programs.get(key))
{
// This condition block does special handling for upgradeable programs.
// It's been noticed that some upgradeable programs fail if their account is
// not loaded, even if the compiled program already exists in the cache.
// So, for now, the code flow will go to the else clause for such accounts
// and load them.
Self::account_shared_data_from_program(key, program, program_accounts)
.map(|program_account| (program.account_size, program_account, 0))?
} else {
Expand Down

0 comments on commit 538acbe

Please sign in to comment.