46
46
accounts_update_notifier_interface::AccountsUpdateNotifier,
47
47
ancestors::{Ancestors, AncestorsForSerialization},
48
48
blockhash_queue::BlockhashQueue,
49
- builtins::{self, ActivationType, Builtin , Builtins},
49
+ builtins::{self, BuiltinAction, BuiltinFeatureTransition , Builtins},
50
50
cost_tracker::CostTracker,
51
51
epoch_stakes::{EpochStakes, NodeVoteAccounts},
52
52
inline_spl_associated_token_account, inline_spl_token,
@@ -1196,9 +1196,9 @@ pub struct Bank {
1196
1196
1197
1197
compute_budget: Option<ComputeBudget>,
1198
1198
1199
- /// Builtin programs activated dynamically by feature
1199
+ /// Dynamic feature transitions for builtin programs
1200
1200
#[allow(clippy::rc_buffer)]
1201
- feature_builtins : Arc<Vec<(Builtin, Pubkey, ActivationType) >>,
1201
+ builtin_feature_transitions : Arc<Vec<BuiltinFeatureTransition >>,
1202
1202
1203
1203
/// Protocol-level rewards that were distributed by this bank
1204
1204
pub rewards: RwLock<Vec<(Pubkey, RewardInfo)>>,
@@ -1367,7 +1367,7 @@ impl Bank {
1367
1367
is_delta: AtomicBool::default(),
1368
1368
builtin_programs: BuiltinPrograms::default(),
1369
1369
compute_budget: Option::<ComputeBudget>::default(),
1370
- feature_builtins : Arc::<Vec<(Builtin, Pubkey, ActivationType) >>::default(),
1370
+ builtin_feature_transitions : Arc::<Vec<BuiltinFeatureTransition >>::default(),
1371
1371
rewards: RwLock::<Vec<(Pubkey, RewardInfo)>>::default(),
1372
1372
cluster_type: Option::<ClusterType>::default(),
1373
1373
lazy_rent_collection: AtomicBool::default(),
@@ -1703,7 +1703,7 @@ impl Bank {
1703
1703
signature_count: AtomicU64::new(0),
1704
1704
builtin_programs,
1705
1705
compute_budget: parent.compute_budget,
1706
- feature_builtins : parent.feature_builtins .clone(),
1706
+ builtin_feature_transitions : parent.builtin_feature_transitions .clone(),
1707
1707
hard_forks: parent.hard_forks.clone(),
1708
1708
rewards: RwLock::new(vec![]),
1709
1709
cluster_type: parent.cluster_type,
@@ -1989,7 +1989,7 @@ impl Bank {
1989
1989
is_delta: AtomicBool::new(fields.is_delta),
1990
1990
builtin_programs: new(),
1991
1991
compute_budget: None,
1992
- feature_builtins : new(),
1992
+ builtin_feature_transitions : new(),
1993
1993
rewards: new(),
1994
1994
cluster_type: Some(genesis_config.cluster_type),
1995
1995
lazy_rent_collection: new(),
@@ -5514,8 +5514,8 @@ impl Bank {
5514
5514
.genesis_builtins
5515
5515
.extend_from_slice(&additional_builtins.genesis_builtins);
5516
5516
builtins
5517
- .feature_builtins
5518
- .extend_from_slice(&additional_builtins.feature_builtins );
5517
+ .feature_transitions
5518
+ .extend_from_slice(&additional_builtins.feature_transitions );
5519
5519
}
5520
5520
if !debug_do_not_add_builtins {
5521
5521
for builtin in builtins.genesis_builtins {
@@ -5531,7 +5531,7 @@ impl Bank {
5531
5531
}
5532
5532
}
5533
5533
}
5534
- self.feature_builtins = Arc::new(builtins.feature_builtins );
5534
+ self.builtin_feature_transitions = Arc::new(builtins.feature_transitions );
5535
5535
5536
5536
self.apply_feature_activations(true, debug_do_not_add_builtins);
5537
5537
}
@@ -6238,29 +6238,9 @@ impl Bank {
6238
6238
debug!("Added program {} under {:?}", name, program_id);
6239
6239
}
6240
6240
6241
- /// Replace a builtin instruction processor if it already exists
6242
- pub fn replace_builtin(
6243
- &mut self,
6244
- name: &str,
6245
- program_id: &Pubkey,
6246
- process_instruction: ProcessInstructionWithContext,
6247
- ) {
6248
- debug!("Replacing program {} under {:?}", name, program_id);
6249
- self.add_builtin_account(name, program_id, true);
6250
- if let Some(entry) = self
6251
- .builtin_programs
6252
- .vec
6253
- .iter_mut()
6254
- .find(|entry| entry.program_id == *program_id)
6255
- {
6256
- entry.process_instruction = process_instruction;
6257
- }
6258
- debug!("Replaced program {} under {:?}", name, program_id);
6259
- }
6260
-
6261
6241
/// Remove a builtin instruction processor if it already exists
6262
- pub fn remove_builtin(&mut self, name: &str, program_id: &Pubkey) {
6263
- debug!("Removing program {} under {:?}", name , program_id);
6242
+ pub fn remove_builtin(&mut self, program_id: &Pubkey) {
6243
+ debug!("Removing program {}" , program_id);
6264
6244
// Don't remove the account since the bank expects the account state to
6265
6245
// be idempotent
6266
6246
if let Some(position) = self
@@ -6271,7 +6251,7 @@ impl Bank {
6271
6251
{
6272
6252
self.builtin_programs.vec.remove(position);
6273
6253
}
6274
- debug!("Removed program {} under {:?}", name , program_id);
6254
+ debug!("Removed program {}" , program_id);
6275
6255
}
6276
6256
6277
6257
pub fn add_precompile(&mut self, program_id: &Pubkey) {
@@ -6451,7 +6431,7 @@ impl Bank {
6451
6431
}
6452
6432
6453
6433
if !debug_do_not_add_builtins {
6454
- self.ensure_feature_builtins (init_finish_or_warp, &new_feature_activations);
6434
+ self.apply_builtin_feature_transitions (init_finish_or_warp, &new_feature_activations);
6455
6435
self.reconfigure_token2_native_mint();
6456
6436
}
6457
6437
self.ensure_no_storage_rewards_pool();
@@ -6508,33 +6488,34 @@ impl Bank {
6508
6488
newly_activated
6509
6489
}
6510
6490
6511
- fn ensure_feature_builtins (
6491
+ fn apply_builtin_feature_transitions (
6512
6492
&mut self,
6513
6493
init_or_warp: bool,
6514
6494
new_feature_activations: &HashSet<Pubkey>,
6515
6495
) {
6516
- let feature_builtins = self.feature_builtins.clone();
6517
- for (builtin, feature, activation_type) in feature_builtins.iter() {
6518
- let should_populate = init_or_warp && self.feature_set.is_active(feature)
6519
- || !init_or_warp && new_feature_activations.contains(feature);
6520
- if should_populate {
6521
- match activation_type {
6522
- ActivationType::NewProgram => self.add_builtin(
6523
- &builtin.name,
6524
- &builtin.id,
6525
- builtin.process_instruction_with_context,
6526
- ),
6527
- ActivationType::NewVersion => self.replace_builtin(
6496
+ let feature_set = self.feature_set.clone();
6497
+ let should_apply_action_for_feature = |feature_id: &Pubkey| -> bool {
6498
+ if init_or_warp {
6499
+ feature_set.is_active(feature_id)
6500
+ } else {
6501
+ new_feature_activations.contains(feature_id)
6502
+ }
6503
+ };
6504
+
6505
+ let builtin_feature_transitions = self.builtin_feature_transitions.clone();
6506
+ for transition in builtin_feature_transitions.iter() {
6507
+ if let Some(builtin_action) = transition.to_action(&should_apply_action_for_feature) {
6508
+ match builtin_action {
6509
+ BuiltinAction::Add(builtin) => self.add_builtin(
6528
6510
&builtin.name,
6529
6511
&builtin.id,
6530
6512
builtin.process_instruction_with_context,
6531
6513
),
6532
- ActivationType::RemoveProgram => {
6533
- self.remove_builtin(&builtin.name, &builtin.id)
6534
- }
6514
+ BuiltinAction::Remove { program_id } => self.remove_builtin(&program_id),
6535
6515
}
6536
6516
}
6537
6517
}
6518
+
6538
6519
for precompile in get_precompiles() {
6539
6520
#[allow(clippy::blocks_in_if_conditions)]
6540
6521
if precompile.feature.map_or(false, |ref feature_id| {
@@ -13350,16 +13331,6 @@ pub(crate) mod tests {
13350
13331
mock_ix_processor,
13351
13332
);
13352
13333
assert_eq!(bank.get_account_modified_slot(&program_id).unwrap().1, slot);
13353
-
13354
- Arc::get_mut(&mut bank).unwrap().replace_builtin(
13355
- "mock_program v2",
13356
- &program_id,
13357
- mock_ix_processor,
13358
- );
13359
- assert_eq!(
13360
- bank.get_account_modified_slot(&program_id).unwrap().1,
13361
- bank.slot()
13362
- );
13363
13334
}
13364
13335
13365
13336
#[test]
0 commit comments