Simplify code for bank::load_program() (#34093)
* Simplify code for bank::load_program() * address review comments
This commit is contained in:
parent
061883ebce
commit
bc2c98bfde
|
@ -112,8 +112,9 @@ use {
|
||||||
compute_budget_processor::process_compute_budget_instructions,
|
compute_budget_processor::process_compute_budget_instructions,
|
||||||
invoke_context::BuiltinFunctionWithContext,
|
invoke_context::BuiltinFunctionWithContext,
|
||||||
loaded_programs::{
|
loaded_programs::{
|
||||||
LoadProgramMetrics, LoadedProgram, LoadedProgramMatchCriteria, LoadedProgramType,
|
ExtractedPrograms, LoadProgramMetrics, LoadedProgram, LoadedProgramMatchCriteria,
|
||||||
LoadedPrograms, LoadedProgramsForTxBatch, WorkingSlot, DELAY_VISIBILITY_SLOT_OFFSET,
|
LoadedProgramType, LoadedPrograms, LoadedProgramsForTxBatch, ProgramRuntimeEnvironment,
|
||||||
|
ProgramRuntimeEnvironments, WorkingSlot, DELAY_VISIBILITY_SLOT_OFFSET,
|
||||||
},
|
},
|
||||||
log_collector::LogCollector,
|
log_collector::LogCollector,
|
||||||
message_processor::MessageProcessor,
|
message_processor::MessageProcessor,
|
||||||
|
@ -278,7 +279,6 @@ pub struct BankRc {
|
||||||
|
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
use solana_frozen_abi::abi_example::AbiExample;
|
use solana_frozen_abi::abi_example::AbiExample;
|
||||||
use solana_program_runtime::loaded_programs::ExtractedPrograms;
|
|
||||||
|
|
||||||
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
#[cfg(RUSTC_WITH_SPECIALIZATION)]
|
||||||
impl AbiExample for BankRc {
|
impl AbiExample for BankRc {
|
||||||
|
@ -307,8 +307,7 @@ impl BankRc {
|
||||||
|
|
||||||
enum ProgramAccountLoadResult {
|
enum ProgramAccountLoadResult {
|
||||||
AccountNotFound,
|
AccountNotFound,
|
||||||
InvalidAccountData,
|
InvalidAccountData(ProgramRuntimeEnvironment),
|
||||||
InvalidV4Program,
|
|
||||||
ProgramOfLoaderV1orV2(AccountSharedData),
|
ProgramOfLoaderV1orV2(AccountSharedData),
|
||||||
ProgramOfLoaderV3(AccountSharedData, AccountSharedData, Slot),
|
ProgramOfLoaderV3(AccountSharedData, AccountSharedData, Slot),
|
||||||
ProgramOfLoaderV4(AccountSharedData, Slot),
|
ProgramOfLoaderV4(AccountSharedData, Slot),
|
||||||
|
@ -4655,7 +4654,11 @@ impl Bank {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_program_accounts(&self, pubkey: &Pubkey) -> ProgramAccountLoadResult {
|
fn load_program_accounts(
|
||||||
|
&self,
|
||||||
|
pubkey: &Pubkey,
|
||||||
|
environments: &ProgramRuntimeEnvironments,
|
||||||
|
) -> ProgramAccountLoadResult {
|
||||||
let program_account = match self.get_account_with_fixed_root(pubkey) {
|
let program_account = match self.get_account_with_fixed_root(pubkey) {
|
||||||
None => return ProgramAccountLoadResult::AccountNotFound,
|
None => return ProgramAccountLoadResult::AccountNotFound,
|
||||||
Some(account) => account,
|
Some(account) => account,
|
||||||
|
@ -4672,7 +4675,9 @@ impl Bank {
|
||||||
(!matches!(state.status, LoaderV4Status::Retracted)).then_some(state.slot)
|
(!matches!(state.status, LoaderV4Status::Retracted)).then_some(state.slot)
|
||||||
})
|
})
|
||||||
.map(|slot| ProgramAccountLoadResult::ProgramOfLoaderV4(program_account, slot))
|
.map(|slot| ProgramAccountLoadResult::ProgramOfLoaderV4(program_account, slot))
|
||||||
.unwrap_or(ProgramAccountLoadResult::InvalidV4Program);
|
.unwrap_or(ProgramAccountLoadResult::InvalidAccountData(
|
||||||
|
environments.program_runtime_v2.clone(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bpf_loader_upgradeable::check_id(program_account.owner()) {
|
if !bpf_loader_upgradeable::check_id(program_account.owner()) {
|
||||||
|
@ -4700,7 +4705,44 @@ impl Bank {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ProgramAccountLoadResult::InvalidAccountData
|
ProgramAccountLoadResult::InvalidAccountData(environments.program_runtime_v1.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_program_from_bytes(
|
||||||
|
load_program_metrics: &mut LoadProgramMetrics,
|
||||||
|
programdata: &[u8],
|
||||||
|
loader_key: &Pubkey,
|
||||||
|
account_size: usize,
|
||||||
|
deployment_slot: Slot,
|
||||||
|
program_runtime_environment: ProgramRuntimeEnvironment,
|
||||||
|
reloading: bool,
|
||||||
|
) -> std::result::Result<LoadedProgram, Box<dyn std::error::Error>> {
|
||||||
|
if reloading {
|
||||||
|
// Safety: this is safe because the program is being reloaded in the cache.
|
||||||
|
unsafe {
|
||||||
|
LoadedProgram::reload(
|
||||||
|
loader_key,
|
||||||
|
program_runtime_environment.clone(),
|
||||||
|
deployment_slot,
|
||||||
|
deployment_slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET),
|
||||||
|
None,
|
||||||
|
programdata,
|
||||||
|
account_size,
|
||||||
|
load_program_metrics,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LoadedProgram::new(
|
||||||
|
loader_key,
|
||||||
|
program_runtime_environment.clone(),
|
||||||
|
deployment_slot,
|
||||||
|
deployment_slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET),
|
||||||
|
None,
|
||||||
|
programdata,
|
||||||
|
account_size,
|
||||||
|
load_program_metrics,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_program(
|
pub fn load_program(
|
||||||
|
@ -4721,19 +4763,16 @@ impl Bank {
|
||||||
..LoadProgramMetrics::default()
|
..LoadProgramMetrics::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut loaded_program = match self.load_program_accounts(pubkey) {
|
let mut loaded_program = match self.load_program_accounts(pubkey, environments) {
|
||||||
ProgramAccountLoadResult::AccountNotFound => Ok(LoadedProgram::new_tombstone(
|
ProgramAccountLoadResult::AccountNotFound => Ok(LoadedProgram::new_tombstone(
|
||||||
self.slot,
|
self.slot,
|
||||||
LoadedProgramType::Closed,
|
LoadedProgramType::Closed,
|
||||||
)),
|
)),
|
||||||
|
|
||||||
ProgramAccountLoadResult::InvalidAccountData => {
|
ProgramAccountLoadResult::InvalidAccountData(env) => Err((self.slot, env)),
|
||||||
Err(InstructionError::InvalidAccountData)
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramAccountLoadResult::ProgramOfLoaderV1orV2(program_account) => {
|
ProgramAccountLoadResult::ProgramOfLoaderV1orV2(program_account) => {
|
||||||
solana_bpf_loader_program::load_program_from_bytes(
|
Self::load_program_from_bytes(
|
||||||
None,
|
|
||||||
&mut load_program_metrics,
|
&mut load_program_metrics,
|
||||||
program_account.data(),
|
program_account.data(),
|
||||||
program_account.owner(),
|
program_account.owner(),
|
||||||
|
@ -4742,6 +4781,7 @@ impl Bank {
|
||||||
environments.program_runtime_v1.clone(),
|
environments.program_runtime_v1.clone(),
|
||||||
reload,
|
reload,
|
||||||
)
|
)
|
||||||
|
.map_err(|_| (0, environments.program_runtime_v1.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
ProgramAccountLoadResult::ProgramOfLoaderV3(
|
ProgramAccountLoadResult::ProgramOfLoaderV3(
|
||||||
|
@ -4751,10 +4791,9 @@ impl Bank {
|
||||||
) => programdata_account
|
) => programdata_account
|
||||||
.data()
|
.data()
|
||||||
.get(UpgradeableLoaderState::size_of_programdata_metadata()..)
|
.get(UpgradeableLoaderState::size_of_programdata_metadata()..)
|
||||||
.ok_or(InstructionError::InvalidAccountData)
|
.ok_or(Box::new(InstructionError::InvalidAccountData).into())
|
||||||
.and_then(|programdata| {
|
.and_then(|programdata| {
|
||||||
solana_bpf_loader_program::load_program_from_bytes(
|
Self::load_program_from_bytes(
|
||||||
None,
|
|
||||||
&mut load_program_metrics,
|
&mut load_program_metrics,
|
||||||
programdata,
|
programdata,
|
||||||
program_account.owner(),
|
program_account.owner(),
|
||||||
|
@ -4766,60 +4805,28 @@ impl Bank {
|
||||||
environments.program_runtime_v1.clone(),
|
environments.program_runtime_v1.clone(),
|
||||||
reload,
|
reload,
|
||||||
)
|
)
|
||||||
}),
|
})
|
||||||
|
.map_err(|_| (slot, environments.program_runtime_v1.clone())),
|
||||||
|
|
||||||
ProgramAccountLoadResult::ProgramOfLoaderV4(program_account, slot) => {
|
ProgramAccountLoadResult::ProgramOfLoaderV4(program_account, slot) => program_account
|
||||||
let loaded_program = program_account
|
.data()
|
||||||
.data()
|
.get(LoaderV4State::program_data_offset()..)
|
||||||
.get(LoaderV4State::program_data_offset()..)
|
.ok_or(Box::new(InstructionError::InvalidAccountData).into())
|
||||||
.and_then(|elf_bytes| {
|
.and_then(|elf_bytes| {
|
||||||
if reload {
|
Self::load_program_from_bytes(
|
||||||
// Safety: this is safe because the program is being reloaded in the cache.
|
&mut load_program_metrics,
|
||||||
unsafe {
|
elf_bytes,
|
||||||
LoadedProgram::reload(
|
&loader_v4::id(),
|
||||||
&loader_v4::id(),
|
program_account.data().len(),
|
||||||
environments.program_runtime_v2.clone(),
|
slot,
|
||||||
slot,
|
environments.program_runtime_v2.clone(),
|
||||||
slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET),
|
reload,
|
||||||
None,
|
)
|
||||||
elf_bytes,
|
})
|
||||||
program_account.data().len(),
|
.map_err(|_| (slot, environments.program_runtime_v2.clone())),
|
||||||
&mut load_program_metrics,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LoadedProgram::new(
|
|
||||||
&loader_v4::id(),
|
|
||||||
environments.program_runtime_v2.clone(),
|
|
||||||
slot,
|
|
||||||
slot.saturating_add(DELAY_VISIBILITY_SLOT_OFFSET),
|
|
||||||
None,
|
|
||||||
elf_bytes,
|
|
||||||
program_account.data().len(),
|
|
||||||
&mut load_program_metrics,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.ok()
|
|
||||||
})
|
|
||||||
.unwrap_or(LoadedProgram::new_tombstone(
|
|
||||||
self.slot,
|
|
||||||
LoadedProgramType::FailedVerification(
|
|
||||||
environments.program_runtime_v2.clone(),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
Ok(loaded_program)
|
|
||||||
}
|
|
||||||
|
|
||||||
ProgramAccountLoadResult::InvalidV4Program => Ok(LoadedProgram::new_tombstone(
|
|
||||||
self.slot,
|
|
||||||
LoadedProgramType::FailedVerification(environments.program_runtime_v2.clone()),
|
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
.unwrap_or_else(|_| {
|
.unwrap_or_else(|(slot, env)| {
|
||||||
LoadedProgram::new_tombstone(
|
LoadedProgram::new_tombstone(slot, LoadedProgramType::FailedVerification(env))
|
||||||
self.slot,
|
|
||||||
LoadedProgramType::FailedVerification(environments.program_runtime_v1.clone()),
|
|
||||||
)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut timings = ExecuteDetailsTimings::default();
|
let mut timings = ExecuteDetailsTimings::default();
|
||||||
|
|
Loading…
Reference in New Issue