Brennan 3 месяцев назад
Родитель
Сommit
6634fd2239
3 измененных файлов с 149 добавлено и 2 удалено
  1. 5 0
      feature-set/src/lib.rs
  2. 28 0
      runtime/src/bank.rs
  3. 116 2
      runtime/src/bank/tests.rs

+ 5 - 0
feature-set/src/lib.rs

@@ -1115,6 +1115,10 @@ pub mod raise_block_limits_to_100m {
     solana_pubkey::declare_id!("P1BCUMpAC7V2GRBRiJCNUgpMyWZhoqt3LKo712ePqsz");
 }
 
+pub mod raise_account_cu_limit {
+    solana_pubkey::declare_id!("htsptAwi2yRoZH83SKaUXykeZGtZHgxkS2QwW1pssR8");
+}
+
 pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::new(|| {
     [
         (secp256k1_program_enabled::id(), "secp256k1 program"),
@@ -1354,6 +1358,7 @@ pub static FEATURE_NAMES: LazyLock<AHashMap<Pubkey, &'static str>> = LazyLock::n
         (disable_zk_elgamal_proof_program::id(), "Disables zk-elgamal-proof program"),
         (reenable_zk_elgamal_proof_program::id(), "Re-enables zk-elgamal-proof program"),
         (raise_block_limits_to_100m::id(), "SIMD-0286: Raise block limit to 100M"),
+        (raise_account_cu_limit::id(), "SIMD-0306: Raise account CU limit to 40% max"),
         /*************** ADD NEW FEATURES HERE ***************/
     ]
     .iter()

+ 28 - 0
runtime/src/bank.rs

@@ -4019,6 +4019,15 @@ impl Bank {
         self.rc.accounts.clone()
     }
 
+    fn apply_simd_0306_cost_tracker_changes(&mut self) {
+        let mut cost_tracker = self.write_cost_tracker().unwrap();
+        let block_cost_limit = cost_tracker.get_block_limit();
+        let vote_cost_limit = cost_tracker.get_vote_limit();
+        // SIMD-0306 makes account cost limit 40% of the block cost limit.
+        let account_cost_limit = block_cost_limit.saturating_mul(40).saturating_div(100);
+        cost_tracker.set_limits(account_cost_limit, block_cost_limit, vote_cost_limit);
+    }
+
     fn finish_init(
         &mut self,
         genesis_config: &GenesisConfig,
@@ -4053,6 +4062,13 @@ impl Bank {
             cost_tracker.set_limits(account_cost_limit, block_cost_limit, vote_cost_limit);
         }
 
+        if self
+            .feature_set
+            .is_active(&feature_set::raise_account_cu_limit::id())
+        {
+            self.apply_simd_0306_cost_tracker_changes();
+        }
+
         if !debug_do_not_add_builtins {
             for builtin in BUILTINS
                 .iter()
@@ -5313,6 +5329,18 @@ impl Bank {
             let account_cost_limit = cost_tracker.get_account_limit();
             let vote_cost_limit = cost_tracker.get_vote_limit();
             cost_tracker.set_limits(account_cost_limit, block_cost_limit, vote_cost_limit);
+            drop(cost_tracker);
+
+            if self
+                .feature_set
+                .is_active(&feature_set::raise_account_cu_limit::id())
+            {
+                self.apply_simd_0306_cost_tracker_changes();
+            }
+        }
+
+        if new_feature_activations.contains(&feature_set::raise_account_cu_limit::id()) {
+            self.apply_simd_0306_cost_tracker_changes();
         }
     }
 

+ 116 - 2
runtime/src/bank/tests.rs

@@ -50,7 +50,9 @@ use {
         compute_budget::ComputeBudget, compute_budget_limits::ComputeBudgetLimits,
     },
     solana_compute_budget_interface::ComputeBudgetInstruction,
-    solana_cost_model::block_cost_limits::{MAX_BLOCK_UNITS, MAX_BLOCK_UNITS_SIMD_0286},
+    solana_cost_model::block_cost_limits::{
+        MAX_BLOCK_UNITS, MAX_BLOCK_UNITS_SIMD_0286, MAX_WRITABLE_ACCOUNT_UNITS,
+    },
     solana_cpi::MAX_RETURN_DATA,
     solana_epoch_schedule::{EpochSchedule, MINIMUM_SLOTS_PER_EPOCH},
     solana_feature_gate_interface::{self as feature, Feature},
@@ -6713,6 +6715,8 @@ fn test_reserved_account_keys() {
 
 #[test]
 fn test_block_limits() {
+    const MAX_WRITABLE_ACCOUNT_UNITS_SIMD_0306_FIRST: u64 = 24_000_000;
+    const MAX_WRITABLE_ACCOUNT_UNITS_SIMD_0306_SECOND: u64 = 40_000_000;
     let (bank0, _bank_forks) = create_simple_test_arc_bank(100_000);
     let mut bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1);
 
@@ -6725,6 +6729,14 @@ fn test_block_limits() {
         MAX_BLOCK_UNITS,
         "before activating the feature, bank should have old/default limit"
     );
+    assert!(!bank
+        .feature_set
+        .is_active(&feature_set::raise_account_cu_limit::id()));
+    assert_eq!(
+        bank.read_cost_tracker().unwrap().get_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS,
+        "before activating the feature, bank should have old/default limit"
+    );
 
     // Activate `raise_block_limits_to_100m` feature
     bank.store_account(
@@ -6746,15 +6758,98 @@ fn test_block_limits() {
         MAX_BLOCK_UNITS_SIMD_0286,
         "after activating the feature, bank should have new limit"
     );
+    assert_eq!(
+        bank.read_cost_tracker().unwrap().get_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS,
+        "after activating the feature, bank should have new limit"
+    );
 
     // Make sure the limits propagate to the child-bank.
-    let bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), 2);
+    let mut bank = Bank::new_from_parent(Arc::new(bank), &Pubkey::default(), 2);
     assert_eq!(
         bank.read_cost_tracker().unwrap().get_block_limit(),
         MAX_BLOCK_UNITS_SIMD_0286,
         "child bank should have new limit"
     );
 
+    // Activate `raise_account_cu_limit` feature
+    bank.store_account(
+        &feature_set::raise_account_cu_limit::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_account_limit(),
+        MAX_WRITABLE_ACCOUNT_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_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS_SIMD_0306_SECOND,
+        "after activating the feature, bank should have new limit"
+    );
+
+    // Test SIMD-0306 getting activated first
+    let (bank0, _bank_forks) = create_simple_test_arc_bank(100_000);
+    let mut bank = Bank::new_from_parent(bank0, &Pubkey::default(), 1);
+
+    // Activate `raise_account_cu_limit` feature
+    bank.store_account(
+        &feature_set::raise_account_cu_limit::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_account_limit(),
+        MAX_WRITABLE_ACCOUNT_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(),
+        MAX_BLOCK_UNITS,
+        "after activating the feature, bank should have new limit"
+    );
+    assert_eq!(
+        bank.read_cost_tracker().unwrap().get_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS_SIMD_0306_FIRST,
+        "after activating the feature, bank should have new limit"
+    );
+
+    // Activate `raise_block_limits_to_100m` feature
+    bank.store_account(
+        &feature_set::raise_block_limits_to_100m::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(),
+        MAX_BLOCK_UNITS_SIMD_0286,
+        "after activating the feature, bank should have new limit"
+    );
+    assert_eq!(
+        bank.read_cost_tracker().unwrap().get_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS_SIMD_0306_SECOND,
+        "after activating the feature, 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.
@@ -6764,6 +6859,11 @@ fn test_block_limits() {
         MAX_BLOCK_UNITS,
         "before activating the feature, bank should have old/default limit"
     );
+    assert_eq!(
+        bank.read_cost_tracker().unwrap().get_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS,
+        "before activating the feature, bank should have old/default limit"
+    );
 
     activate_feature(
         &mut genesis_config,
@@ -6778,6 +6878,20 @@ fn test_block_limits() {
         MAX_BLOCK_UNITS_SIMD_0286,
         "bank created from genesis config should have new limit"
     );
+
+    activate_feature(
+        &mut genesis_config,
+        feature_set::raise_account_cu_limit::id(),
+    );
+    let bank = Bank::new_for_tests(&genesis_config);
+    assert!(bank
+        .feature_set
+        .is_active(&feature_set::raise_account_cu_limit::id()));
+    assert_eq!(
+        bank.read_cost_tracker().unwrap().get_account_limit(),
+        MAX_WRITABLE_ACCOUNT_UNITS_SIMD_0306_SECOND,
+        "bank created from genesis config should have new limit"
+    );
 }
 
 #[test]