diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 262cfe14019c0c..a4bd0a456dd27c 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -43,7 +43,7 @@ pub use solana_sdk::reward_type::RewardType; use { crate::{ bank::{ - builtins::{BuiltinPrototype, BUILTINS}, + builtins::{BuiltinPrototype, BUILTINS, EPHEMERAL_BUILTINS}, metrics::*, }, bank_forks::BankForks, @@ -5953,7 +5953,16 @@ impl Bank { .iter() .chain(additional_builtins.unwrap_or(&[]).iter()) { - if builtin.enable_feature_id.is_none() { + let should_add_builtin = builtin.enable_feature_id.is_none() && { + if let Some(core_bpf_migration) = &builtin.core_bpf_migration { + // The built-in should be added if the feature to + // migrate it to Core BPF is not active + !self.feature_set.is_active(&core_bpf_migration.feature_id) + } else { + true + } + }; + if should_add_builtin { self.add_builtin( builtin.program_id, builtin.name.to_string(), @@ -6051,6 +6060,10 @@ impl Bank { self.load_slow(&self.ancestors, pubkey) } + pub fn get_builtins(&self) -> &HashSet { + &self.builtin_programs + } + fn load_slow( &self, ancestors: &Ancestors, @@ -7299,14 +7312,42 @@ impl Bank { new_feature_activations: &HashSet, ) { for builtin in BUILTINS.iter() { + let mut builtin_disabled = false; + if let Some(core_bpf_migration) = &builtin.core_bpf_migration { + // If the built-in is set to be migrated to Core BPF on feature + // activation, perform the migration and do not add the program + // to the bank's builtins. The migration will remove it from + // the builtins list and the cache. + // + // There should never be a case where a built-in is set to be + // migrated to Core BPF and is also set to be enabled on feature + // activation. However, the `builtin_disabled` flag is used to + // handle this case. + if new_feature_activations.contains(&core_bpf_migration.feature_id) { + if let Err(e) = builtin.migrate_to_core_bpf(self) { + warn!( + "Failed to migrate built-in {} to core BPF: {}", + builtin.name, e + ); + } else { + builtin_disabled = true; + } + } else { + // If the built-in has already been migrated to Core BPF, do not + // add it to the bank's builtins. + builtin_disabled = self.feature_set.is_active(&core_bpf_migration.feature_id); + } + }; + if let Some(feature_id) = builtin.enable_feature_id { - let should_apply_action_for_feature_transition = - if only_apply_transitions_for_new_features { + let should_enable_builtin_on_feature_transition = !builtin_disabled + && if only_apply_transitions_for_new_features { new_feature_activations.contains(&feature_id) } else { self.feature_set.is_active(&feature_id) }; - if should_apply_action_for_feature_transition { + + if should_enable_builtin_on_feature_transition { self.add_builtin( builtin.program_id, builtin.name.to_string(), @@ -7319,6 +7360,21 @@ impl Bank { } } } + + // Migrate any necessary ephemeral built-ins to core BPF. + for ephemeral_builtin in EPHEMERAL_BUILTINS.iter() { + if let Some(core_bpf_migration) = &ephemeral_builtin.core_bpf_migration { + if new_feature_activations.contains(&core_bpf_migration.feature_id) { + if let Err(e) = ephemeral_builtin.migrate_to_core_bpf(self) { + warn!( + "Failed to migrate ephemeral built-in {} to core BPF: {}", + ephemeral_builtin.name, e + ); + } + } + } + } + for precompile in get_precompiles() { let should_add_precompile = precompile .feature diff --git a/runtime/src/bank/builtins/prototypes.rs b/runtime/src/bank/builtins/prototypes.rs index f1ec7f5e87c6b4..c397eba6d4a119 100644 --- a/runtime/src/bank/builtins/prototypes.rs +++ b/runtime/src/bank/builtins/prototypes.rs @@ -1,4 +1,3 @@ -#![allow(dead_code)] // Removed in later commit use { super::core_bpf_migration::{ error::CoreBpfMigrationError, CoreBpfMigration, CoreBpfMigrationConfig, diff --git a/runtime/src/snapshot_minimizer.rs b/runtime/src/snapshot_minimizer.rs index 280f4d7f45454f..3d98bb44a7d5e2 100644 --- a/runtime/src/snapshot_minimizer.rs +++ b/runtime/src/snapshot_minimizer.rs @@ -1,10 +1,7 @@ //! Used to create minimal snapshots - separated here to keep accounts_db simpler use { - crate::{ - bank::{builtins::BUILTINS, Bank}, - static_ids, - }, + crate::{bank::Bank, static_ids}, dashmap::DashSet, log::info, rayon::{ @@ -116,8 +113,8 @@ impl<'a> SnapshotMinimizer<'a> { /// Used to get builtin accounts in `minimize` fn get_builtins(&self) { - BUILTINS.iter().for_each(|e| { - self.minimized_account_set.insert(e.program_id); + self.bank.get_builtins().iter().for_each(|program_id| { + self.minimized_account_set.insert(*program_id); }); }