diff --git a/compute-budget/src/compute_budget.rs b/compute-budget/src/compute_budget.rs index 6b91affca4dd1c..d538fca560b1af 100644 --- a/compute-budget/src/compute_budget.rs +++ b/compute-budget/src/compute_budget.rs @@ -178,8 +178,12 @@ impl ComputeBudget { pub fn try_from_instructions<'a>( instructions: impl Iterator, + use_default_loaded_accounts_data_size: bool, ) -> Result { - let compute_budget_limits = process_compute_budget_instructions(instructions)?; + let compute_budget_limits = process_compute_budget_instructions( + instructions, + use_default_loaded_accounts_data_size, + )?; Ok(ComputeBudget { compute_unit_limit: u64::from(compute_budget_limits.compute_unit_limit), heap_size: compute_budget_limits.updated_heap_bytes, diff --git a/core/src/banking_stage/consumer.rs b/core/src/banking_stage/consumer.rs index 3e144031288f1c..2a548d60378729 100644 --- a/core/src/banking_stage/consumer.rs +++ b/core/src/banking_stage/consumer.rs @@ -751,8 +751,12 @@ impl Consumer { error_counters: &mut TransactionErrorMetrics, ) -> Result<(), TransactionError> { let fee_payer = message.fee_payer(); - let budget_limits = - process_compute_budget_instructions(message.program_instructions_iter())?.into(); + let budget_limits = process_compute_budget_instructions( + message.program_instructions_iter(), + bank.feature_set + .is_active(&feature_set::default_loaded_accounts_data_size_limit::id()), + )? + .into(); let fee = bank.fee_structure().calculate_fee( message, bank.get_lamports_per_signature(), diff --git a/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs b/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs index 57a52f58a5c1cc..920ca7274a031c 100644 --- a/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs +++ b/core/src/banking_stage/transaction_scheduler/scheduler_controller.rs @@ -29,6 +29,7 @@ use { solana_sdk::{ self, clock::{FORWARD_TRANSACTIONS_TO_LEADER_AT_SLOT_OFFSET, MAX_PROCESSING_AGE}, + feature_set, fee::FeeBudgetLimits, saturating_add_assign, transaction::SanitizedTransaction, @@ -509,9 +510,13 @@ impl SchedulerController { .is_ok() }) .filter_map(|(packet, tx)| { - process_compute_budget_instructions(tx.message().program_instructions_iter()) - .map(|compute_budget| (packet, tx, compute_budget.into())) - .ok() + process_compute_budget_instructions( + tx.message().program_instructions_iter(), + bank.feature_set + .is_active(&feature_set::default_loaded_accounts_data_size_limit::id()), + ) + .map(|compute_budget| (packet, tx, compute_budget.into())) + .ok() }) .for_each(|(packet, tx, fee_budget_limits)| { arc_packets.push(packet); diff --git a/cost-model/src/cost_model.rs b/cost-model/src/cost_model.rs index 1f5f1948db57c3..414e90f73fcb8a 100644 --- a/cost-model/src/cost_model.rs +++ b/cost-model/src/cost_model.rs @@ -141,8 +141,10 @@ impl CostModel { // if failed to process compute_budget instructions, the transaction will not be executed // by `bank`, therefore it should be considered as no execution cost by cost model. - match process_compute_budget_instructions(transaction.message().program_instructions_iter()) - { + match process_compute_budget_instructions( + transaction.message().program_instructions_iter(), + feature_set.is_active(&feature_set::default_loaded_accounts_data_size_limit::id()), + ) { Ok(compute_budget_limits) => { // if tx contained user-space instructions and a more accurate estimate available correct it, // where "user-space instructions" must be specifically checked by diff --git a/runtime-transaction/src/runtime_transaction.rs b/runtime-transaction/src/runtime_transaction.rs index 625ec28fdb22d8..080a6c11dc355c 100644 --- a/runtime-transaction/src/runtime_transaction.rs +++ b/runtime-transaction/src/runtime_transaction.rs @@ -15,6 +15,7 @@ use { process_compute_budget_instructions, ComputeBudgetLimits, }, solana_sdk::{ + feature_set::{self, default_loaded_accounts_data_size_limit}, hash::Hash, message::{AddressLoader, SanitizedMessage, SanitizedVersionedMessage}, pubkey::Pubkey, @@ -71,6 +72,7 @@ impl RuntimeTransaction { sanitized_versioned_tx: SanitizedVersionedTransaction, message_hash: Option, is_simple_vote_tx: Option, + feature_set: &feature_set::FeatureSet, ) -> Result { let mut meta = TransactionMeta::default(); meta.set_is_simple_vote_tx( @@ -86,7 +88,10 @@ impl RuntimeTransaction { compute_unit_price, loaded_accounts_bytes, .. - } = process_compute_budget_instructions(message.program_instructions_iter())?; + } = process_compute_budget_instructions( + message.program_instructions_iter(), + feature_set.is_active(&default_loaded_accounts_data_size_limit::id()), + )?; meta.set_compute_unit_limit(compute_unit_limit); meta.set_compute_unit_price(compute_unit_price); meta.set_loaded_accounts_bytes(loaded_accounts_bytes); diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 28b78884c94ce9..5cac23d9a8bd08 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -95,6 +95,7 @@ use { solana_measure::{measure, measure::Measure, measure_us}, solana_perf::perf_libs, solana_program_runtime::{ + compute_budget_processor::{process_compute_budget_instructions, ComputeBudgetLimits}, invoke_context::BuiltinFunctionWithContext, loaded_programs::{ ProgramCache, ProgramCacheEntry, ProgramCacheEntryOwner, ProgramCacheEntryType, @@ -120,7 +121,8 @@ use { epoch_schedule::EpochSchedule, feature, feature_set::{ - self, include_loaded_accounts_data_size_in_fee_calculation, + self, default_loaded_accounts_data_size_limit, + include_loaded_accounts_data_size_in_fee_calculation, remove_rounding_in_fee_calculation, reward_full_priority_fee, FeatureSet, }, fee::{FeeDetails, FeeStructure}, @@ -3105,12 +3107,20 @@ impl Bank { message: &SanitizedMessage, lamports_per_signature: u64, ) -> u64 { + let use_default_loaded_accounts_data_size = self + .feature_set + .is_active(&default_loaded_accounts_data_size_limit::id()); self.fee_structure().calculate_fee( message, lamports_per_signature, - &process_compute_budget_instructions(message.program_instructions_iter()) - .unwrap_or_default() - .into(), + &process_compute_budget_instructions( + message.program_instructions_iter(), + use_default_loaded_accounts_data_size, + ) + .unwrap_or_else(|_| { + ComputeBudgetLimits::new_with(use_default_loaded_accounts_data_size) + }) + .into(), self.feature_set .is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()), self.feature_set diff --git a/runtime/src/compute_budget_details.rs b/runtime/src/compute_budget_details.rs index c14aa24c063538..eb9cca429c56a7 100644 --- a/runtime/src/compute_budget_details.rs +++ b/runtime/src/compute_budget_details.rs @@ -23,7 +23,14 @@ pub trait GetComputeBudgetDetails { instructions: impl Iterator, _round_compute_unit_price_enabled: bool, ) -> Option { - let compute_budget_limits = process_compute_budget_instructions(instructions).ok()?; + // ComputeBudgetDetails does not concern with loaded_accounts_data_size_limit, hence safe + // to hardcode its feature gate `default_loaded_accounts_data_size_limit` as activated + let use_default_loaded_accounts_data_size = true; + let compute_budget_limits = process_compute_budget_instructions( + instructions, + use_default_loaded_accounts_data_size, + ) + .ok()?; Some(ComputeBudgetDetails { compute_unit_price: compute_budget_limits.compute_unit_price, compute_unit_limit: u64::from(compute_budget_limits.compute_unit_limit), diff --git a/sdk/src/feature_set.rs b/sdk/src/feature_set.rs index ed3a7ff5162341..44a290821fa192 100644 --- a/sdk/src/feature_set.rs +++ b/sdk/src/feature_set.rs @@ -817,6 +817,10 @@ pub mod migrate_config_program_to_core_bpf { solana_sdk::declare_id!("2Fr57nzzkLYXW695UdDxDeR5fhnZWSttZeZYemrnpGFV"); } +pub mod default_loaded_accounts_data_size_limit { + solana_sdk::declare_id!("CVvWw7NMVCn2Yp5RfxqrcTHXnaYyh91A2bGbkk88XXMM"); +} + lazy_static! { /// Map of feature identifiers to user-visible description pub static ref FEATURE_NAMES: HashMap = [ @@ -1016,6 +1020,7 @@ lazy_static! { (migrate_feature_gate_program_to_core_bpf::id(), "Migrate Feature Gate program to Core BPF (programify) #1003"), (vote_only_full_fec_sets::id(), "vote only full fec sets"), (migrate_config_program_to_core_bpf::id(), "Migrate Config program to Core BPF #1378"), + (default_loaded_accounts_data_size_limit::id(), "add default loaded_accounts_data_size_limit #1568"), /*************** ADD NEW FEATURES HERE ***************/ ] .iter() diff --git a/svm/src/account_loader.rs b/svm/src/account_loader.rs index fd1971733a826f..7565565ddf6141 100644 --- a/svm/src/account_loader.rs +++ b/svm/src/account_loader.rs @@ -7,12 +7,15 @@ use { transaction_processing_callback::TransactionProcessingCallback, }, itertools::Itertools, - solana_compute_budget::compute_budget_processor::process_compute_budget_instructions, - solana_program_runtime::loaded_programs::{ProgramCacheEntry, ProgramCacheForTxBatch}, + solana_program_runtime::{ + compute_budget_processor::{process_compute_budget_instructions, ComputeBudgetLimits}, + loaded_programs::{ProgramCacheEntry, ProgramCacheForTxBatch}, + }, solana_sdk::{ account::{Account, AccountSharedData, ReadableAccount, WritableAccount}, feature_set::{ - self, include_loaded_accounts_data_size_in_fee_calculation, + self, default_loaded_accounts_data_size_limit, + include_loaded_accounts_data_size_in_fee_calculation, remove_rounding_in_fee_calculation, FeatureSet, }, fee::{FeeDetails, FeeStructure}, @@ -171,12 +174,19 @@ pub(crate) fn load_accounts( }), ) => { let message = tx.message(); + let use_default_loaded_accounts_data_size = + feature_set.is_active(&default_loaded_accounts_data_size_limit::id()); let fee_details = fee_structure.calculate_fee_details( message, *lamports_per_signature, - &process_compute_budget_instructions(message.program_instructions_iter()) - .unwrap_or_default() - .into(), + &process_compute_budget_instructions( + message.program_instructions_iter(), + use_default_loaded_accounts_data_size, + ) + .unwrap_or_else(|_| { + ComputeBudgetLimits::new_with(use_default_loaded_accounts_data_size) + }) + .into(), feature_set .is_active(&include_loaded_accounts_data_size_in_fee_calculation::id()), feature_set.is_active(&remove_rounding_in_fee_calculation::id()), @@ -218,8 +228,10 @@ fn load_transaction_accounts( let mut rent_debits = RentDebits::default(); let rent_collector = callbacks.get_rent_collector(); - let requested_loaded_accounts_data_size_limit = - get_requested_loaded_accounts_data_size_limit(message)?; + let requested_loaded_accounts_data_size_limit = get_requested_loaded_accounts_data_size_limit( + message, + feature_set.is_active(&default_loaded_accounts_data_size_limit::id()), + )?; let mut accumulated_accounts_data_size: usize = 0; let instruction_accounts = message @@ -416,10 +428,13 @@ fn load_transaction_accounts( /// Note, requesting zero bytes will result transaction error fn get_requested_loaded_accounts_data_size_limit( sanitized_message: &SanitizedMessage, + use_default_loaded_accounts_data_size: bool, ) -> Result> { - let compute_budget_limits = - process_compute_budget_instructions(sanitized_message.program_instructions_iter()) - .unwrap_or_default(); + let compute_budget_limits = process_compute_budget_instructions( + sanitized_message.program_instructions_iter(), + use_default_loaded_accounts_data_size, + ) + .unwrap_or_else(|_| ComputeBudgetLimits::new_with(use_default_loaded_accounts_data_size)); // sanitize against setting size limit to zero NonZeroUsize::new( usize::try_from(compute_budget_limits.loaded_accounts_bytes).unwrap_or_default(), diff --git a/svm/src/transaction_processor.rs b/svm/src/transaction_processor.rs index 98ce311624e422..f9fba911383bc3 100644 --- a/svm/src/transaction_processor.rs +++ b/svm/src/transaction_processor.rs @@ -32,7 +32,7 @@ use { account::{AccountSharedData, ReadableAccount, PROGRAM_OWNERS}, clock::{Epoch, Slot}, epoch_schedule::EpochSchedule, - feature_set::FeatureSet, + feature_set::{default_loaded_accounts_data_size_limit, FeatureSet}, fee::FeeStructure, inner_instruction::{InnerInstruction, InnerInstructionsList}, instruction::{CompiledInstruction, TRANSACTION_LEVEL_STACK_HEIGHT}, @@ -259,6 +259,9 @@ impl TransactionBatchProcessor { Measure::start("compute_budget_process_transaction_time"); let maybe_compute_budget = ComputeBudget::try_from_instructions( tx.message().program_instructions_iter(), + callbacks + .get_feature_set() + .is_active(&default_loaded_accounts_data_size_limit::id()), ); compute_budget_process_transaction_time.stop(); saturating_add_assign!(