Feature - Prune on feature set transition (#31945)
* Call create_program_runtime_environment() in Bank::apply_builtin_program_feature_transitions(). * Adds LoadedPrograms::prune_feature_set_transition().
This commit is contained in:
parent
557155d34b
commit
89207a3fe5
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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())
|
||||
|
@ -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 =
|
||||
|
@ -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| {
|
||||
|
|
Loading…
Reference in New Issue