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

Feature - Prune on feature set transition #31945

Merged
merged 2 commits into from
Jun 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions program-runtime/src/loaded_programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,36 @@ impl LoadedPrograms {
entry
}

/// On the epoch boundary this removes all programs of the outdated feature set
pub fn prune_feature_set_transition(&mut self) {
for second_level in self.entries.values_mut() {
second_level.retain(|entry| {
let retain = match &entry.program {
LoadedProgramType::Builtin(_) | LoadedProgramType::Closed => true,
LoadedProgramType::LegacyV0(program) | LoadedProgramType::LegacyV1(program)
if Arc::ptr_eq(
program.get_loader(),
&self.program_runtime_environment_v1,
) =>
{
true
}
LoadedProgramType::Unloaded(environment)
if Arc::ptr_eq(environment, &self.program_runtime_environment_v1) =>
{
true
}
_ => false,
};
if !retain {
self.stats.prunes.fetch_add(1, Ordering::Relaxed);
}
retain
});
}
self.remove_programs_with_no_entries();
}

/// Before rerooting the blockstore this removes all programs of orphan forks
pub fn prune<F: ForkGraph>(&mut self, fork_graph: &F, new_root: Slot) {
let previous_root = self.latest_root;
Expand Down
2 changes: 2 additions & 0 deletions programs/bpf_loader/src/syscalls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ pub fn create_program_runtime_environment<'a>(
debugging_features: bool,
) -> Result<BuiltinProgram<InvokeContext<'a>>, Error> {
use rand::Rng;
// When adding new features for RBPF,
// also add them to `Bank::apply_builtin_program_feature_transitions()`.
let config = Config {
max_call_depth: compute_budget.max_call_depth,
stack_frame_size: compute_budget.stack_frame_size,
Expand Down
39 changes: 27 additions & 12 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6286,17 +6286,6 @@ impl Bank {
);

if !debug_do_not_add_builtins {
let program_runtime_environment_v1 = create_program_runtime_environment(
&self.feature_set,
&self.runtime_config.compute_budget.unwrap_or_default(),
false, /* deployment */
false, /* debugging_features */
)
.unwrap();
self.loaded_programs_cache
.write()
.unwrap()
.program_runtime_environment_v1 = Arc::new(program_runtime_environment_v1);
for builtin in BUILTINS
.iter()
.chain(additional_builtins.unwrap_or(&[]).iter())
Expand Down Expand Up @@ -7577,6 +7566,33 @@ impl Bank {
only_apply_transitions_for_new_features: bool,
new_feature_activations: &HashSet<Pubkey>,
) {
const FEATURES_AFFECTING_RBPF: &[Pubkey] = &[
feature_set::error_on_syscall_bpf_function_hash_collisions::id(),
feature_set::reject_callx_r10::id(),
feature_set::switch_to_new_elf_parser::id(),
feature_set::bpf_account_data_direct_mapping::id(),
];
if !only_apply_transitions_for_new_features
|| FEATURES_AFFECTING_RBPF
.iter()
.any(|key| new_feature_activations.contains(key))
{
let program_runtime_environment_v1 = create_program_runtime_environment(
&self.feature_set,
&self.runtime_config.compute_budget.unwrap_or_default(),
false, /* deployment */
false, /* debugging_features */
)
.unwrap();
let mut loaded_programs_cache = self.loaded_programs_cache.write().unwrap();
if *loaded_programs_cache.program_runtime_environment_v1
!= program_runtime_environment_v1
{
loaded_programs_cache.program_runtime_environment_v1 =
Arc::new(program_runtime_environment_v1);
}
loaded_programs_cache.prune_feature_set_transition();
}
for builtin in BUILTINS.iter() {
if let Some(feature_id) = builtin.feature_id {
let should_apply_action_for_feature_transition =
Expand All @@ -7598,7 +7614,6 @@ impl Bank {
}
}
}

for precompile in get_precompiles() {
#[allow(clippy::blocks_in_if_conditions)]
if precompile.feature.map_or(false, |ref feature_id| {
Expand Down