diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 84b1c10f1b8e5a..5d2a1535d2386d 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -5301,6 +5301,22 @@ impl Bank { debug_do_not_add_builtins, ); + // Cost-Tracker is not serialized in snapshot or any configs. + // We must apply previously activated features related to limits here + // so that the initial bank state is consistent with the feature set. + // Cost-tracker limits are propagated through children banks. + if self + .feature_set + .is_active(&feature_set::raise_block_limits_to_50m::id()) + { + let (account_cost_limit, block_cost_limit, vote_cost_limit) = simd_0207_block_limits(); + self.write_cost_tracker().unwrap().set_limits( + account_cost_limit, + block_cost_limit, + vote_cost_limit, + ); + } + if !debug_do_not_add_builtins { for builtin in BUILTINS .iter() diff --git a/runtime/src/bank/tests.rs b/runtime/src/bank/tests.rs index 210b64eb1820dc..1cb8c7ab4b5a22 100644 --- a/runtime/src/bank/tests.rs +++ b/runtime/src/bank/tests.rs @@ -8004,8 +8004,9 @@ fn test_reserved_account_keys() { fn test_block_limits() { let (bank0, _bank_forks) = create_simple_test_arc_bank(100_000); let mut bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1); - bank.feature_set = Arc::new(FeatureSet::default()); - + assert!(!bank + .feature_set + .is_active(&feature_set::raise_block_limits_to_50m::id())); assert_eq!( bank.read_cost_tracker().unwrap().get_block_limit(), MAX_BLOCK_UNITS, @@ -8017,6 +8018,15 @@ fn test_block_limits() { &feature_set::raise_block_limits_to_50m::id(), &feature::create_account(&Feature::default(), 42), ); + // apply_feature_activations for `FinishInit` will not cause the block limit to be updated + bank.apply_feature_activations(ApplyFeatureActivationsCaller::FinishInit, true); + assert_eq!( + bank.read_cost_tracker().unwrap().get_block_limit(), + MAX_BLOCK_UNITS, + "before activating the feature, bank should have old/default limit" + ); + + // apply_feature_activations for `NewFromParent` will cause feature to be activated bank.apply_feature_activations(ApplyFeatureActivationsCaller::NewFromParent, true); assert_eq!( bank.read_cost_tracker().unwrap().get_block_limit(), @@ -8031,6 +8041,30 @@ fn test_block_limits() { MAX_BLOCK_UNITS_SIMD_0207, "child bank should have new limit" ); + + // Test starting from a genesis config with and without feature account + let (mut genesis_config, _keypair) = create_genesis_config(100_000); + // Without feature account in genesis, old limits are used. + let bank = Bank::new_for_tests(&genesis_config); + assert_eq!( + bank.read_cost_tracker().unwrap().get_block_limit(), + MAX_BLOCK_UNITS, + "before activating the feature, bank should have old/default limit" + ); + + activate_feature( + &mut genesis_config, + feature_set::raise_block_limits_to_50m::id(), + ); + let bank = Bank::new_for_tests(&genesis_config); + assert!(bank + .feature_set + .is_active(&feature_set::raise_block_limits_to_50m::id())); + assert_eq!( + bank.read_cost_tracker().unwrap().get_block_limit(), + MAX_BLOCK_UNITS_SIMD_0207, + "bank created from genesis config should have new limit" + ); } #[test]