Skip to content

Commit

Permalink
Adds LoadedProgram::account_owner() and LoadedProgramOwner.
Browse files Browse the repository at this point in the history
Merges LoadedProgramTypes LegacyV0, LegacyV1, Typed and TestLoaded into Loaded.
  • Loading branch information
Lichtso committed Apr 8, 2024
1 parent 55c05c5 commit 9aa7c05
Show file tree
Hide file tree
Showing 8 changed files with 192 additions and 121 deletions.
2 changes: 1 addition & 1 deletion ledger-tool/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ fn load_program<'a>(
);
match result {
Ok(loaded_program) => match loaded_program.program {
LoadedProgramType::LegacyV1(program) => Ok(program),
LoadedProgramType::Loaded(program) => Ok(program),
_ => unreachable!(),
},
Err(err) => Err(format!("Loading executable failed: {err:?}")),
Expand Down
207 changes: 120 additions & 87 deletions program-runtime/src/loaded_programs.rs

Large diffs are not rendered by default.

9 changes: 6 additions & 3 deletions programs/bpf_loader/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ use {
ic_logger_msg, ic_msg,
invoke_context::{BpfAllocator, InvokeContext, SerializedAccountMetadata, SyscallContext},
loaded_programs::{
LoadProgramMetrics, LoadedProgram, LoadedProgramType, DELAY_VISIBILITY_SLOT_OFFSET,
LoadProgramMetrics, LoadedProgram, LoadedProgramOwner, LoadedProgramType,
DELAY_VISIBILITY_SLOT_OFFSET,
},
log_collector::LogCollector,
stable_log,
Expand Down Expand Up @@ -456,8 +457,7 @@ pub fn process_instruction_inner(
ic_logger_msg!(log_collector, "Program is not deployed");
Err(Box::new(InstructionError::InvalidAccountData) as Box<dyn std::error::Error>)
}
LoadedProgramType::LegacyV0(executable) => execute(executable, invoke_context),
LoadedProgramType::LegacyV1(executable) => execute(executable, invoke_context),
LoadedProgramType::Loaded(executable) => execute(executable, invoke_context),
_ => Err(Box::new(InstructionError::IncorrectProgramId) as Box<dyn std::error::Error>),
}
.map(|_| 0)
Expand Down Expand Up @@ -1113,6 +1113,7 @@ fn process_loader_upgradeable_instruction(
program_key,
Arc::new(LoadedProgram::new_tombstone(
clock.slot,
LoadedProgramOwner::LoaderV3,
LoadedProgramType::Closed,
)),
);
Expand Down Expand Up @@ -3761,6 +3762,7 @@ mod tests {
let env = Arc::new(BuiltinProgram::new_mock());
let program = LoadedProgram {
program: LoadedProgramType::Unloaded(env),
account_owner: LoadedProgramOwner::LoaderV2,
account_size: 0,
deployment_slot: 0,
effective_slot: 0,
Expand Down Expand Up @@ -3804,6 +3806,7 @@ mod tests {
let env = Arc::new(BuiltinProgram::new_mock());
let program = LoadedProgram {
program: LoadedProgramType::Unloaded(env),
account_owner: LoadedProgramOwner::LoaderV2,
account_size: 0,
deployment_slot: 0,
effective_slot: 0,
Expand Down
2 changes: 1 addition & 1 deletion programs/loader-v4/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@ pub fn process_instruction_inner(
ic_logger_msg!(log_collector, "Program is not deployed");
Err(Box::new(InstructionError::InvalidAccountData) as Box<dyn std::error::Error>)
}
LoadedProgramType::Typed(executable) => execute(invoke_context, executable),
LoadedProgramType::Loaded(executable) => execute(invoke_context, executable),
_ => Err(Box::new(InstructionError::IncorrectProgramId) as Box<dyn std::error::Error>),
}
}
Expand Down
9 changes: 7 additions & 2 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,8 @@ use {
compute_budget_processor::process_compute_budget_instructions,
invoke_context::BuiltinFunctionWithContext,
loaded_programs::{
LoadedProgram, LoadedProgramMatchCriteria, LoadedProgramType, ProgramCache,
LoadedProgram, LoadedProgramMatchCriteria, LoadedProgramOwner, LoadedProgramType,
ProgramCache,
},
runtime_config::RuntimeConfig,
timings::{ExecuteTimingType, ExecuteTimings},
Expand Down Expand Up @@ -6468,7 +6469,11 @@ impl Bank {
self.add_builtin(
program_id,
name,
LoadedProgram::new_tombstone(self.slot, LoadedProgramType::Closed),
LoadedProgram::new_tombstone(
self.slot,
LoadedProgramOwner::NativeLoader,
LoadedProgramType::Closed,
),
);
debug!("Removed program {}", program_id);
}
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/bank/builtins/core_bpf_migration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ mod tests {
assert_eq!(target_entry.latest_access_slot.load(Relaxed), bank.slot());

// The target program entry should now be a BPF program.
assert_matches!(target_entry.program, LoadedProgramType::LegacyV1(..));
assert_matches!(target_entry.program, LoadedProgramType::Loaded(..));
}
}

Expand Down
2 changes: 1 addition & 1 deletion runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7138,7 +7138,7 @@ fn test_bank_load_program() {
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, false, bank.epoch()).unwrap();
assert_matches!(program.program, LoadedProgramType::LegacyV1(_));
assert_matches!(program.program, LoadedProgramType::Loaded(_));
assert_eq!(
program.account_size,
program_account.data().len() + programdata_account.data().len()
Expand Down
80 changes: 55 additions & 25 deletions svm/src/transaction_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ use {
invoke_context::InvokeContext,
loaded_programs::{
ForkGraph, LoadProgramMetrics, LoadedProgram, LoadedProgramMatchCriteria,
LoadedProgramType, LoadedProgramsForTxBatch, ProgramCache, ProgramRuntimeEnvironment,
DELAY_VISIBILITY_SLOT_OFFSET,
LoadedProgramOwner, LoadedProgramType, LoadedProgramsForTxBatch, ProgramCache,
ProgramRuntimeEnvironment, DELAY_VISIBILITY_SLOT_OFFSET,
},
log_collector::LogCollector,
runtime_config::RuntimeConfig,
Expand All @@ -30,6 +30,7 @@ use {
solana_sdk::{
account::{AccountSharedData, ReadableAccount, PROGRAM_OWNERS},
account_utils::StateMut,
bpf_loader, bpf_loader_deprecated,
bpf_loader_upgradeable::{self, UpgradeableLoaderState},
clock::{Epoch, Slot},
epoch_schedule::EpochSchedule,
Expand Down Expand Up @@ -112,8 +113,9 @@ pub trait TransactionProcessingCallback {

#[derive(Debug)]
enum ProgramAccountLoadResult {
InvalidAccountData,
ProgramOfLoaderV1orV2(AccountSharedData),
InvalidAccountData(LoadedProgramOwner),
ProgramOfLoaderV1(AccountSharedData),
ProgramOfLoaderV2(AccountSharedData),
ProgramOfLoaderV3(AccountSharedData, AccountSharedData, Slot),
ProgramOfLoaderV4(AccountSharedData, Slot),
}
Expand Down Expand Up @@ -404,12 +406,11 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
};

let mut loaded_program = match self.load_program_accounts(callbacks, pubkey)? {
ProgramAccountLoadResult::InvalidAccountData => Ok(LoadedProgram::new_tombstone(
self.slot,
LoadedProgramType::Closed,
)),
ProgramAccountLoadResult::InvalidAccountData(owner) => Ok(
LoadedProgram::new_tombstone(self.slot, owner, LoadedProgramType::Closed),
),

ProgramAccountLoadResult::ProgramOfLoaderV1orV2(program_account) => {
ProgramAccountLoadResult::ProgramOfLoaderV1(program_account) => {
Self::load_program_from_bytes(
&mut load_program_metrics,
program_account.data(),
Expand All @@ -419,7 +420,20 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
environments.program_runtime_v1.clone(),
reload,
)
.map_err(|_| (0, environments.program_runtime_v1.clone()))
.map_err(|_| (0, LoadedProgramOwner::LoaderV1))
}

ProgramAccountLoadResult::ProgramOfLoaderV2(program_account) => {
Self::load_program_from_bytes(
&mut load_program_metrics,
program_account.data(),
program_account.owner(),
program_account.data().len(),
0,
environments.program_runtime_v1.clone(),
reload,
)
.map_err(|_| (0, LoadedProgramOwner::LoaderV2))
}

ProgramAccountLoadResult::ProgramOfLoaderV3(
Expand All @@ -444,7 +458,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
reload,
)
})
.map_err(|_| (slot, environments.program_runtime_v1.clone())),
.map_err(|_| (slot, LoadedProgramOwner::LoaderV3)),

ProgramAccountLoadResult::ProgramOfLoaderV4(program_account, slot) => program_account
.data()
Expand All @@ -461,10 +475,15 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
reload,
)
})
.map_err(|_| (slot, environments.program_runtime_v2.clone())),
.map_err(|_| (slot, LoadedProgramOwner::LoaderV4)),
}
.unwrap_or_else(|(slot, env)| {
LoadedProgram::new_tombstone(slot, LoadedProgramType::FailedVerification(env))
.unwrap_or_else(|(slot, owner)| {
let env = if let LoadedProgramOwner::LoaderV4 = &owner {
environments.program_runtime_v2.clone()
} else {
environments.program_runtime_v1.clone()
};
LoadedProgram::new_tombstone(slot, owner, LoadedProgramType::FailedVerification(env))
});

let mut timings = ExecuteDetailsTimings::default();
Expand Down Expand Up @@ -849,14 +868,18 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
(!matches!(state.status, LoaderV4Status::Retracted)).then_some(state.slot)
})
.map(|slot| ProgramAccountLoadResult::ProgramOfLoaderV4(program_account, slot))
.unwrap_or(ProgramAccountLoadResult::InvalidAccountData),
.unwrap_or(ProgramAccountLoadResult::InvalidAccountData(
LoadedProgramOwner::LoaderV4,
)),
);
}

if !bpf_loader_upgradeable::check_id(program_account.owner()) {
return Some(ProgramAccountLoadResult::ProgramOfLoaderV1orV2(
program_account,
));
if bpf_loader_deprecated::check_id(program_account.owner()) {
return Some(ProgramAccountLoadResult::ProgramOfLoaderV1(program_account));
}

if bpf_loader::check_id(program_account.owner()) {
return Some(ProgramAccountLoadResult::ProgramOfLoaderV2(program_account));
}

if let Ok(UpgradeableLoaderState::Program {
Expand All @@ -879,7 +902,9 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
}
}
}
Some(ProgramAccountLoadResult::InvalidAccountData)
Some(ProgramAccountLoadResult::InvalidAccountData(
LoadedProgramOwner::LoaderV3,
))
}

/// Extract the InnerInstructionsList from a TransactionContext
Expand Down Expand Up @@ -1097,7 +1122,7 @@ mod tests {
let result = batch_processor.load_program_accounts(&mock_bank, &key);
assert!(matches!(
result,
Some(ProgramAccountLoadResult::InvalidAccountData)
Some(ProgramAccountLoadResult::InvalidAccountData(_))
));

account_data.set_data(Vec::new());
Expand All @@ -1107,7 +1132,7 @@ mod tests {

assert!(matches!(
result,
Some(ProgramAccountLoadResult::InvalidAccountData)
Some(ProgramAccountLoadResult::InvalidAccountData(_))
));
}

Expand All @@ -1125,7 +1150,7 @@ mod tests {
let result = batch_processor.load_program_accounts(&mock_bank, &key);
assert!(matches!(
result,
Some(ProgramAccountLoadResult::InvalidAccountData)
Some(ProgramAccountLoadResult::InvalidAccountData(_))
));

account_data.set_data(vec![0; 64]);
Expand All @@ -1135,7 +1160,7 @@ mod tests {
let result = batch_processor.load_program_accounts(&mock_bank, &key);
assert!(matches!(
result,
Some(ProgramAccountLoadResult::InvalidAccountData)
Some(ProgramAccountLoadResult::InvalidAccountData(_))
));

let loader_data = LoaderV4State {
Expand Down Expand Up @@ -1178,7 +1203,8 @@ mod tests {

let result = batch_processor.load_program_accounts(&mock_bank, &key);
match result {
Some(ProgramAccountLoadResult::ProgramOfLoaderV1orV2(data)) => {
Some(ProgramAccountLoadResult::ProgramOfLoaderV1(data))
| Some(ProgramAccountLoadResult::ProgramOfLoaderV2(data)) => {
assert_eq!(data, account_data);
}
_ => panic!("Invalid result"),
Expand Down Expand Up @@ -1299,6 +1325,7 @@ mod tests {

let loaded_program = LoadedProgram::new_tombstone(
0,
LoadedProgramOwner::LoaderV4,
LoadedProgramType::FailedVerification(
batch_processor
.program_cache
Expand Down Expand Up @@ -1327,6 +1354,7 @@ mod tests {
let result = batch_processor.load_program_with_pubkey(&mock_bank, &key, false, 20);
let loaded_program = LoadedProgram::new_tombstone(
0,
LoadedProgramOwner::LoaderV2,
LoadedProgramType::FailedVerification(
batch_processor
.program_cache
Expand Down Expand Up @@ -1394,6 +1422,7 @@ mod tests {
let result = batch_processor.load_program_with_pubkey(&mock_bank, &key1, false, 0);
let loaded_program = LoadedProgram::new_tombstone(
0,
LoadedProgramOwner::LoaderV3,
LoadedProgramType::FailedVerification(
batch_processor
.program_cache
Expand Down Expand Up @@ -1468,6 +1497,7 @@ mod tests {
let result = batch_processor.load_program_with_pubkey(&mock_bank, &key, false, 0);
let loaded_program = LoadedProgram::new_tombstone(
0,
LoadedProgramOwner::LoaderV4,
LoadedProgramType::FailedVerification(
batch_processor
.program_cache
Expand Down

0 comments on commit 9aa7c05

Please sign in to comment.