Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
Adjusts the runtimes built-ins to use Arc<LoadedProgram>.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lichtso committed May 1, 2023
1 parent ea4d2c1 commit d5f10e3
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 89 deletions.
45 changes: 18 additions & 27 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ use {
solana_perf::perf_libs,
solana_program_runtime::{
accounts_data_meter::MAX_ACCOUNTS_DATA_LEN,
builtin_program::{BuiltinProgram, BuiltinPrograms, ProcessInstructionWithContext},
builtin_program::BuiltinPrograms,
compute_budget::{self, ComputeBudget},
executor_cache::{BankExecutorCache, TransactionExecutorCache, MAX_CACHED_EXECUTORS},
loaded_programs::{
Expand Down Expand Up @@ -6328,12 +6328,8 @@ impl Bank {
.extend_from_slice(&additional_builtins.feature_transitions);
}
if !debug_do_not_add_builtins {
for builtin in builtins.genesis_builtins {
self.add_builtin(
&builtin.name,
&builtin.program_id,
builtin.process_instruction,
);
for (program_id, builtin) in builtins.genesis_builtins {
self.add_builtin(program_id, builtin);
}
for precompile in get_precompiles() {
if precompile.feature.is_none() {
Expand Down Expand Up @@ -7357,27 +7353,24 @@ impl Bank {
}

/// Add an instruction processor to intercept instructions before the dynamic loader.
pub fn add_builtin(
&mut self,
name: &str,
program_id: &Pubkey,
process_instruction: ProcessInstructionWithContext,
) {
pub fn add_builtin(&mut self, program_id: Pubkey, builtin: Arc<LoadedProgram>) {
let name = match &builtin.program {
LoadedProgramType::Builtin(name, _) => name,
_ => unreachable!(),
};
debug!("Adding program {} under {:?}", name, program_id);
self.add_builtin_account(name, program_id, false);
self.add_builtin_account(name.as_str(), &program_id, false);
if let Some(entry) = self
.builtin_programs
.vec
.iter_mut()
.find(|entry| entry.program_id == *program_id)
.find(|entry| entry.0 == program_id)
{
entry.process_instruction = process_instruction;
entry.1 = builtin.clone();
} else {
self.builtin_programs.vec.push(BuiltinProgram {
name: name.to_string(),
program_id: *program_id,
process_instruction,
});
self.builtin_programs
.vec
.push((program_id, builtin.clone()));
}
debug!("Added program {} under {:?}", name, program_id);
}
Expand All @@ -7391,7 +7384,7 @@ impl Bank {
.builtin_programs
.vec
.iter()
.position(|entry| entry.program_id == *program_id)
.position(|entry| entry.0 == *program_id)
{
self.builtin_programs.vec.remove(position);
}
Expand Down Expand Up @@ -7643,11 +7636,9 @@ impl Bank {
transition.to_action(&should_apply_action_for_feature_transition)
{
match builtin_action {
BuiltinAction::Add(builtin) => self.add_builtin(
&builtin.name,
&builtin.program_id,
builtin.process_instruction,
),
BuiltinAction::Add(program_id, builtin) => {
self.add_builtin(program_id, builtin)
}
BuiltinAction::Remove(program_id) => self.remove_builtin(&program_id),
}
}
Expand Down
150 changes: 88 additions & 62 deletions runtime/src/builtins.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use {
solana_program_runtime::builtin_program::BuiltinProgram,
solana_program_runtime::{builtin_program::create_builtin, loaded_programs::LoadedProgram},
solana_sdk::{
bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, feature_set, pubkey::Pubkey,
},
std::sync::Arc,
};

#[derive(Clone, Debug)]
pub struct Builtins {
/// Builtin programs that are always available
pub genesis_builtins: Vec<BuiltinProgram>,
pub genesis_builtins: Vec<(Pubkey, Arc<LoadedProgram>)>,

/// Dynamic feature transitions for builtin programs
pub feature_transitions: Vec<BuiltinFeatureTransition>,
Expand All @@ -17,7 +18,7 @@ pub struct Builtins {
/// Actions taken by a bank when managing the list of active builtin programs.
#[derive(Debug, Clone)]
pub enum BuiltinAction {
Add(BuiltinProgram),
Add(Pubkey, Arc<LoadedProgram>),
Remove(Pubkey),
}

Expand All @@ -27,13 +28,15 @@ pub enum BuiltinAction {
pub enum BuiltinFeatureTransition {
/// Add a builtin program if a feature is activated.
Add {
builtin: BuiltinProgram,
program_id: Pubkey,
builtin: Arc<LoadedProgram>,
feature_id: Pubkey,
},
/// Remove a builtin program if a feature is activated or
/// retain a previously added builtin.
RemoveOrRetain {
previously_added_builtin: BuiltinProgram,
program_id: Pubkey,
previously_added_builtin: Arc<LoadedProgram>,
addition_feature_id: Pubkey,
removal_feature_id: Pubkey,
},
Expand All @@ -46,25 +49,30 @@ impl BuiltinFeatureTransition {
) -> Option<BuiltinAction> {
match self {
Self::Add {
program_id,
builtin,
feature_id,
} => {
if should_apply_action_for_feature(feature_id) {
Some(BuiltinAction::Add(builtin.clone()))
Some(BuiltinAction::Add(*program_id, builtin.clone()))
} else {
None
}
}
Self::RemoveOrRetain {
program_id,
previously_added_builtin,
addition_feature_id,
removal_feature_id,
} => {
if should_apply_action_for_feature(removal_feature_id) {
Some(BuiltinAction::Remove(previously_added_builtin.program_id))
Some(BuiltinAction::Remove(*program_id))
} else if should_apply_action_for_feature(addition_feature_id) {
// Retaining is no different from adding a new builtin.
Some(BuiltinAction::Add(previously_added_builtin.clone()))
Some(BuiltinAction::Add(
*program_id,
previously_added_builtin.clone(),
))
} else {
None
}
Expand All @@ -74,72 +82,85 @@ impl BuiltinFeatureTransition {
}

/// Built-in programs that are always available
fn genesis_builtins() -> Vec<BuiltinProgram> {
fn genesis_builtins() -> Vec<(Pubkey, Arc<LoadedProgram>)> {
vec![
BuiltinProgram {
name: "system_program".to_string(),
program_id: solana_system_program::id(),
process_instruction: solana_system_program::system_processor::process_instruction,
},
BuiltinProgram {
name: "vote_program".to_string(),
program_id: solana_vote_program::id(),
process_instruction: solana_vote_program::vote_processor::process_instruction,
},
BuiltinProgram {
name: "stake_program".to_string(),
program_id: solana_stake_program::id(),
process_instruction: solana_stake_program::stake_instruction::process_instruction,
},
BuiltinProgram {
name: "config_program".to_string(),
program_id: solana_config_program::id(),
process_instruction: solana_config_program::config_processor::process_instruction,
},
BuiltinProgram {
name: "solana_bpf_loader_deprecated_program".to_string(),
program_id: bpf_loader_deprecated::id(),
process_instruction: solana_bpf_loader_program::process_instruction,
},
BuiltinProgram {
name: "solana_bpf_loader_program".to_string(),
program_id: bpf_loader::id(),
process_instruction: solana_bpf_loader_program::process_instruction,
},
BuiltinProgram {
name: "solana_bpf_loader_upgradeable_program".to_string(),
program_id: bpf_loader_upgradeable::id(),
process_instruction: solana_bpf_loader_program::process_instruction,
},
(
solana_system_program::id(),
create_builtin(
"system_program".to_string(),
solana_system_program::system_processor::process_instruction,
),
),
(
solana_vote_program::id(),
create_builtin(
"vote_program".to_string(),
solana_vote_program::vote_processor::process_instruction,
),
),
(
solana_stake_program::id(),
create_builtin(
"stake_program".to_string(),
solana_stake_program::stake_instruction::process_instruction,
),
),
(
solana_config_program::id(),
create_builtin(
"config_program".to_string(),
solana_config_program::config_processor::process_instruction,
),
),
(
bpf_loader_deprecated::id(),
create_builtin(
"solana_bpf_loader_deprecated_program".to_string(),
solana_bpf_loader_program::process_instruction,
),
),
(
bpf_loader::id(),
create_builtin(
"solana_bpf_loader_program".to_string(),
solana_bpf_loader_program::process_instruction,
),
),
(
bpf_loader_upgradeable::id(),
create_builtin(
"solana_bpf_loader_upgradeable_program".to_string(),
solana_bpf_loader_program::process_instruction,
),
),
]
}

/// Dynamic feature transitions for builtin programs
fn builtin_feature_transitions() -> Vec<BuiltinFeatureTransition> {
vec![
BuiltinFeatureTransition::Add {
builtin: BuiltinProgram {
name: "compute_budget_program".to_string(),
program_id: solana_sdk::compute_budget::id(),
process_instruction: solana_compute_budget_program::process_instruction,
},
program_id: solana_sdk::compute_budget::id(),
builtin: create_builtin(
"compute_budget_program".to_string(),
solana_compute_budget_program::process_instruction,
),
feature_id: feature_set::add_compute_budget_program::id(),
},
BuiltinFeatureTransition::Add {
builtin: BuiltinProgram {
name: "address_lookup_table_program".to_string(),
program_id: solana_address_lookup_table_program::id(),
process_instruction:
solana_address_lookup_table_program::processor::process_instruction,
},
program_id: solana_address_lookup_table_program::id(),
builtin: create_builtin(
"address_lookup_table_program".to_string(),
solana_address_lookup_table_program::processor::process_instruction,
),
feature_id: feature_set::versioned_tx_message_enabled::id(),
},
BuiltinFeatureTransition::Add {
builtin: BuiltinProgram {
name: "zk_token_proof_program".to_string(),
program_id: solana_zk_token_sdk::zk_token_proof_program::id(),
process_instruction: solana_zk_token_proof_program::process_instruction,
},
program_id: solana_zk_token_sdk::zk_token_proof_program::id(),
builtin: create_builtin(
"zk_token_proof_program".to_string(),
solana_zk_token_proof_program::process_instruction,
),
feature_id: feature_set::zk_token_sdk_enabled::id(),
},
]
Expand All @@ -157,9 +178,14 @@ pub fn get_pubkeys() -> Vec<Pubkey> {
let builtins = get();

let mut pubkeys = Vec::new();
pubkeys.extend(builtins.genesis_builtins.iter().map(|b| b.program_id));
pubkeys.extend(
builtins
.genesis_builtins
.iter()
.map(|(program_id, _builtin)| program_id),
);
pubkeys.extend(builtins.feature_transitions.iter().filter_map(|f| match f {
BuiltinFeatureTransition::Add { builtin, .. } => Some(builtin.program_id),
BuiltinFeatureTransition::Add { program_id, .. } => Some(program_id),
BuiltinFeatureTransition::RemoveOrRetain { .. } => None,
}));
pubkeys
Expand Down

0 comments on commit d5f10e3

Please sign in to comment.