Skip to content

Commit

Permalink
SIMD-0207: Raise block limit to 50M (#4112)
Browse files Browse the repository at this point in the history
* SIMD-0207: Raise block limit to 50M (#4026)

* Fix loading from snapshots/genesis

(cherry picked from commit 9e59baa)

# Conflicts:
#	cost-model/src/block_cost_limits.rs
#	runtime/src/bank.rs
#	sdk/feature-set/src/lib.rs
  • Loading branch information
apfitzge authored and mergify[bot] committed Dec 16, 2024
1 parent 8a652ac commit 057244e
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 0 deletions.
21 changes: 21 additions & 0 deletions cost-model/src/block_cost_limits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,23 @@ pub const INSTRUCTION_DATA_BYTES_COST: u64 = 140 /*bytes per us*/ / COMPUTE_UNIT
/// accumulated by Transactions added to it; A transaction's compute units are
/// calculated by cost_model, based on transaction's signatures, write locks,
/// data size and built-in and SBF instructions.
<<<<<<< HEAD
pub const MAX_BLOCK_UNITS: u64 =
MAX_BLOCK_REPLAY_TIME_US * COMPUTE_UNIT_TO_US_RATIO * MAX_CONCURRENCY;

#[cfg(test)]
static_assertions::const_assert_eq!(MAX_BLOCK_UNITS, 48_000_000);
=======
pub const MAX_BLOCK_UNITS: u64 = 48_000_000;
pub const MAX_BLOCK_UNITS_SIMD_0207: u64 = 50_000_000;
>>>>>>> 9e59baae7 (SIMD-0207: Raise block limit to 50M (#4112))

/// Number of compute units that a writable account in a block is allowed. The
/// limit is to prevent too many transactions write to same account, therefore
/// reduce block's parallelism.
pub const MAX_WRITABLE_ACCOUNT_UNITS: u64 = MAX_BLOCK_REPLAY_TIME_US * COMPUTE_UNIT_TO_US_RATIO;

<<<<<<< HEAD
#[cfg(test)]
static_assertions::const_assert_eq!(MAX_WRITABLE_ACCOUNT_UNITS, 12_000_000);

Expand All @@ -54,6 +60,21 @@ pub const MAX_VOTE_UNITS: u64 = (MAX_BLOCK_UNITS as f64 * 0.75_f64) as u64;
#[cfg(test)]
static_assertions::const_assert_eq!(MAX_VOTE_UNITS, 36_000_000);

=======
>>>>>>> 9e59baae7 (SIMD-0207: Raise block limit to 50M (#4112))
/// The maximum allowed size, in bytes, that accounts data can grow, per block.
/// This can also be thought of as the maximum size of new allocations per block.
pub const MAX_BLOCK_ACCOUNTS_DATA_SIZE_DELTA: u64 = 100_000_000;

/// Return the block limits that will be used upon activation of SIMD-0207.
/// Returns as
/// (account_limit, block_limit, vote_limit)
// ^ Above order is used to be consistent with the order of
// `CostTracker::set_limits`.
pub const fn simd_0207_block_limits() -> (u64, u64, u64) {
(
MAX_WRITABLE_ACCOUNT_UNITS,
MAX_BLOCK_UNITS_SIMD_0207,
MAX_VOTE_UNITS,
)
}
5 changes: 5 additions & 0 deletions cost-model/src/cost_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ impl CostTracker {
self.in_flight_transaction_count = 0;
}

/// Get the overall block limit.
pub fn get_block_limit(&self) -> u64 {
self.block_cost_limit
}

/// allows to adjust limits initiated during construction
pub fn set_limits(
&mut self,
Expand Down
78 changes: 78 additions & 0 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,12 @@ use {
create_program_runtime_environment_v1, create_program_runtime_environment_v2,
},
solana_compute_budget::compute_budget::ComputeBudget,
<<<<<<< HEAD
solana_cost_model::cost_tracker::CostTracker,
=======
solana_compute_budget_instruction::instructions_processor::process_compute_budget_instructions,
solana_cost_model::{block_cost_limits::simd_0207_block_limits, cost_tracker::CostTracker},
>>>>>>> 9e59baae7 (SIMD-0207: Raise block limit to 50M (#4112))
solana_feature_set::{
self as feature_set, remove_rounding_in_fee_calculation, reward_full_priority_fee,
FeatureSet,
Expand Down Expand Up @@ -5066,6 +5071,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()
Expand Down Expand Up @@ -6639,6 +6660,63 @@ impl Bank {
if new_feature_activations.contains(&feature_set::update_hashes_per_tick6::id()) {
self.apply_updated_hashes_per_tick(UPDATED_HASHES_PER_TICK6);
}
<<<<<<< HEAD
=======

if new_feature_activations.contains(&feature_set::accounts_lt_hash::id()) {
// Activating the accounts lt hash feature means we need to have an accounts lt hash
// value at the end of this if-block. If the cli arg has been used, that means we
// already have an accounts lt hash and do not need to recalculate it.
if self
.rc
.accounts
.accounts_db
.is_experimental_accumulator_hash_enabled()
{
// We already have an accounts lt hash value, so no need to recalculate it.
// Nothing else to do here.
} else {
let parent_slot = self.parent_slot;
info!(
"Calculating the accounts lt hash for slot {parent_slot} \
as part of feature activation; this may take some time...",
);
// We must calculate the accounts lt hash now as part of feature activation.
// Note, this bank is *not* frozen yet, which means it will later call
// `update_accounts_lt_hash()`. Therefore, we calculate the accounts lt hash based
// on *our parent*, not us!
let parent_ancestors = {
let mut ancestors = self.ancestors.clone();
ancestors.remove(&self.slot());
ancestors
};
let (parent_accounts_lt_hash, duration) = meas_dur!({
self.rc
.accounts
.accounts_db
.calculate_accounts_lt_hash_at_startup_from_index(
&parent_ancestors,
parent_slot,
)
});
*self.accounts_lt_hash.get_mut().unwrap() = parent_accounts_lt_hash;
info!(
"Calculating the accounts lt hash for slot {parent_slot} \
completed in {duration:?}, accounts_lt_hash checksum: {}",
self.accounts_lt_hash.get_mut().unwrap().0.checksum(),
);
}
}

if new_feature_activations.contains(&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,
);
}
>>>>>>> 9e59baae7 (SIMD-0207: Raise block limit to 50M (#4112))
}

fn apply_updated_hashes_per_tick(&mut self, hashes_per_tick: u64) {
Expand Down
68 changes: 68 additions & 0 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ use {
compute_budget_limits::{self, MAX_COMPUTE_UNIT_LIMIT},
prioritization_fee::{PrioritizationFeeDetails, PrioritizationFeeType},
},
solana_cost_model::block_cost_limits::{MAX_BLOCK_UNITS, MAX_BLOCK_UNITS_SIMD_0207},
solana_feature_set::{self as feature_set, FeatureSet},
solana_inline_spl::token,
solana_logger,
Expand Down Expand Up @@ -7999,6 +8000,73 @@ fn test_reserved_account_keys() {
);
}

#[test]
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);
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,
"before activating the feature, bank should have old/default limit"
);

// Activate `raise_block_limits_to_50m` feature
bank.store_account(
&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(),
MAX_BLOCK_UNITS_SIMD_0207,
"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);
assert_eq!(
bank.read_cost_tracker().unwrap().get_block_limit(),
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]
fn test_program_replacement() {
let mut bank = create_simple_test_bank(0);
Expand Down
21 changes: 21 additions & 0 deletions sdk/feature-set/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,21 @@ pub mod migrate_stake_program_to_core_bpf {
solana_pubkey::declare_id!("6M4oQ6eXneVhtLoiAr4yRYQY43eVLjrKbiDZDJc892yk");
}

<<<<<<< HEAD
=======
pub mod deplete_cu_meter_on_vm_failure {
solana_pubkey::declare_id!("B7H2caeia4ZFcpE3QcgMqbiWiBtWrdBRBSJ1DY6Ktxbq");
}

pub mod reserve_minimal_cus_for_builtin_instructions {
solana_pubkey::declare_id!("C9oAhLxDBm3ssWtJx1yBGzPY55r2rArHmN1pbQn6HogH");
}

pub mod raise_block_limits_to_50m {
solana_pubkey::declare_id!("5oMCU3JPaFLr8Zr4ct7yFA7jdk6Mw1RmB8K4u9ZbS42z");
}

>>>>>>> 9e59baae7 (SIMD-0207: Raise block limit to 50M (#4112))
lazy_static! {
/// Map of feature identifiers to user-visible description
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
Expand Down Expand Up @@ -1096,6 +1111,12 @@ lazy_static! {
(disable_account_loader_special_case::id(), "Disable account loader special case #3513"),
(enable_secp256r1_precompile::id(), "Enable secp256r1 precompile SIMD-0075"),
(migrate_stake_program_to_core_bpf::id(), "Migrate Stake program to Core BPF SIMD-0196 #3655"),
<<<<<<< HEAD
=======
(deplete_cu_meter_on_vm_failure::id(), "Deplete compute meter for vm errors SIMD-0182 #3993"),
(reserve_minimal_cus_for_builtin_instructions::id(), "Reserve minimal CUs for builtin instructions SIMD-170 #2562"),
(raise_block_limits_to_50m::id(), "Raise block limit to 50M SIMD-0207"),
>>>>>>> 9e59baae7 (SIMD-0207: Raise block limit to 50M (#4112))
/*************** ADD NEW FEATURES HERE ***************/
]
.iter()
Expand Down

0 comments on commit 057244e

Please sign in to comment.