diff --git a/docs/src/developing/programming-model/runtime.md b/docs/src/developing/programming-model/runtime.md index 56f602398f..f8ac8bc7cf 100644 --- a/docs/src/developing/programming-model/runtime.md +++ b/docs/src/developing/programming-model/runtime.md @@ -115,11 +115,11 @@ Compute Budget instructions don't require any accounts and don't consume any compute units to process. Transactions can only contain one of each type of compute budget instruction, duplicate types will result in an error. -The `ComputeBudgetInstruction::request_units` function can be used to create +The `ComputeBudgetInstruction::set_compute_unit_limit` function can be used to create these instructions: ```rust -let instruction = ComputeBudgetInstruction::request_units(300_000); +let instruction = ComputeBudgetInstruction::set_compute_unit_limit(300_000); ``` ## Transaction-wide Compute Budget diff --git a/program-runtime/src/compute_budget.rs b/program-runtime/src/compute_budget.rs index d8b655997f..5d7bbeb65f 100644 --- a/program-runtime/src/compute_budget.rs +++ b/program-runtime/src/compute_budget.rs @@ -10,8 +10,8 @@ use { }, }; -pub const DEFAULT_UNITS: u32 = 200_000; -pub const MAX_UNITS: u32 = 1_400_000; +pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000; +pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000; const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024; #[cfg(RUSTC_WITH_SPECIALIZATION)] @@ -24,9 +24,10 @@ impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget { #[derive(Clone, Copy, Debug, PartialEq)] pub struct ComputeBudget { - /// Number of compute units that an instruction is allowed. Compute units - /// are consumed by program execution, resources they use, etc... - pub max_units: u64, + /// Number of compute units that a transaction or individual instruction is + /// allowed to consume. Compute units are consumed by program execution, + /// resources they use, etc... + pub compute_unit_limit: u64, /// Number of compute units consumed by a log_u64 call pub log_64_units: u64, /// Number of compute units consumed by a create_program_address call @@ -87,14 +88,14 @@ pub struct ComputeBudget { impl Default for ComputeBudget { fn default() -> Self { - Self::new(MAX_UNITS) + Self::new(MAX_COMPUTE_UNIT_LIMIT as u64) } } impl ComputeBudget { - pub fn new(max_units: u32) -> Self { + pub fn new(compute_unit_limit: u64) -> Self { ComputeBudget { - max_units: max_units as u64, + compute_unit_limit, log_64_units: 100, create_program_address_units: 1500, invoke_units: 1000, @@ -133,7 +134,7 @@ impl ComputeBudget { support_set_compute_unit_price_ix: bool, ) -> Result { let mut num_non_compute_budget_instructions: usize = 0; - let mut requested_units = None; + let mut updated_compute_unit_limit = None; let mut requested_heap_size = None; let mut prioritization_fee = None; @@ -149,16 +150,16 @@ impl ComputeBudget { match try_from_slice_unchecked(&instruction.data) { Ok(ComputeBudgetInstruction::RequestUnitsDeprecated { - units, + units: compute_unit_limit, additional_fee, }) => { - if requested_units.is_some() { + if updated_compute_unit_limit.is_some() { return Err(duplicate_instruction_error); } if prioritization_fee.is_some() { return Err(duplicate_instruction_error); } - requested_units = Some(units as u64); + updated_compute_unit_limit = Some(compute_unit_limit); prioritization_fee = Some(PrioritizationFeeType::Deprecated(additional_fee as u64)); } @@ -168,11 +169,11 @@ impl ComputeBudget { } requested_heap_size = Some((bytes, i as u8)); } - Ok(ComputeBudgetInstruction::RequestUnits(units)) => { - if requested_units.is_some() { + Ok(ComputeBudgetInstruction::SetComputeUnitLimit(compute_unit_limit)) => { + if updated_compute_unit_limit.is_some() { return Err(duplicate_instruction_error); } - requested_units = Some(units as u64); + updated_compute_unit_limit = Some(compute_unit_limit); } Ok(ComputeBudgetInstruction::SetComputeUnitPrice(micro_lamports)) => { if prioritization_fee.is_some() { @@ -186,10 +187,10 @@ impl ComputeBudget { } else if i < 3 { match try_from_slice_unchecked(&instruction.data) { Ok(ComputeBudgetInstruction::RequestUnitsDeprecated { - units, + units: compute_unit_limit, additional_fee, }) => { - requested_units = Some(units as u64); + updated_compute_unit_limit = Some(compute_unit_limit); prioritization_fee = Some(PrioritizationFeeType::Deprecated(additional_fee as u64)); } @@ -225,21 +226,21 @@ impl ComputeBudget { self.heap_size = Some(bytes as usize); } - self.max_units = if default_units_per_instruction { - requested_units.or_else(|| { + self.compute_unit_limit = if default_units_per_instruction { + updated_compute_unit_limit.or_else(|| { Some( - num_non_compute_budget_instructions.saturating_mul(DEFAULT_UNITS as usize) - as u64, + (num_non_compute_budget_instructions as u32) + .saturating_mul(DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT), ) }) } else { - requested_units + updated_compute_unit_limit } - .unwrap_or(MAX_UNITS as u64) - .min(MAX_UNITS as u64); + .unwrap_or(MAX_COMPUTE_UNIT_LIMIT) + .min(MAX_COMPUTE_UNIT_LIMIT) as u64; Ok(prioritization_fee - .map(|fee_type| PrioritizationFeeDetails::new(fee_type, self.max_units)) + .map(|fee_type| PrioritizationFeeDetails::new(fee_type, self.compute_unit_limit)) .unwrap_or_default()) } } @@ -300,40 +301,40 @@ mod tests { &[], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: 0, + compute_unit_limit: 0, ..ComputeBudget::default() } ); test!( &[ - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: 1, + compute_unit_limit: 1, ..ComputeBudget::default() } ); test!( &[ - ComputeBudgetInstruction::request_units(MAX_UNITS + 1), + ComputeBudgetInstruction::set_compute_unit_limit(MAX_COMPUTE_UNIT_LIMIT + 1), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: MAX_UNITS as u64, + compute_unit_limit: MAX_COMPUTE_UNIT_LIMIT as u64, ..ComputeBudget::default() } ); test!( &[ Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(MAX_UNITS), + ComputeBudgetInstruction::set_compute_unit_limit(MAX_COMPUTE_UNIT_LIMIT), ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: MAX_UNITS as u64, + compute_unit_limit: MAX_COMPUTE_UNIT_LIMIT as u64, ..ComputeBudget::default() } ); @@ -342,11 +343,11 @@ mod tests { Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: 1, + compute_unit_limit: 1, ..ComputeBudget::default() } ); @@ -356,11 +357,11 @@ mod tests { Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(1), // ignored + ComputeBudgetInstruction::set_compute_unit_limit(1), // ignored ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: DEFAULT_UNITS as u64 * 3, + compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64 * 3, ..ComputeBudget::default() }, false @@ -374,7 +375,7 @@ mod tests { 1, )), ComputeBudget { - max_units: 1, + compute_unit_limit: 1, ..ComputeBudget::default() }, false @@ -382,7 +383,7 @@ mod tests { test!( &[ - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), ComputeBudgetInstruction::set_compute_unit_price(42) ], Ok(PrioritizationFeeDetails::new( @@ -390,7 +391,7 @@ mod tests { 1 )), ComputeBudget { - max_units: 1, + compute_unit_limit: 1, ..ComputeBudget::default() } ); @@ -402,7 +403,7 @@ mod tests { 1 )), ComputeBudget { - max_units: 1, + compute_unit_limit: 1, ..ComputeBudget::default() }, false @@ -413,7 +414,7 @@ mod tests { &[], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: 0, + compute_unit_limit: 0, ..ComputeBudget::default() } ); @@ -424,7 +425,7 @@ mod tests { ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: DEFAULT_UNITS as u64, + compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64, heap_size: Some(40 * 1024), ..ComputeBudget::default() } @@ -469,7 +470,7 @@ mod tests { ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: DEFAULT_UNITS as u64, + compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64, heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), ..ComputeBudget::default() } @@ -501,7 +502,7 @@ mod tests { ], Ok(PrioritizationFeeDetails::default()), ComputeBudget { - max_units: DEFAULT_UNITS as u64 * 7, + compute_unit_limit: DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64 * 7, ..ComputeBudget::default() } ); @@ -511,15 +512,15 @@ mod tests { &[ Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), - ComputeBudgetInstruction::request_units(MAX_UNITS), + ComputeBudgetInstruction::set_compute_unit_limit(MAX_COMPUTE_UNIT_LIMIT), ComputeBudgetInstruction::set_compute_unit_price(u64::MAX), ], Ok(PrioritizationFeeDetails::new( PrioritizationFeeType::ComputeUnitPrice(u64::MAX), - MAX_UNITS as u64, + MAX_COMPUTE_UNIT_LIMIT as u64, )), ComputeBudget { - max_units: MAX_UNITS as u64, + compute_unit_limit: MAX_COMPUTE_UNIT_LIMIT as u64, heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), ..ComputeBudget::default() } @@ -529,7 +530,7 @@ mod tests { &[ Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), - ComputeBudgetInstruction::request_units(MAX_UNITS), + ComputeBudgetInstruction::set_compute_unit_limit(MAX_COMPUTE_UNIT_LIMIT), ComputeBudgetInstruction::set_compute_unit_price(u64::MAX), ], Err(TransactionError::InstructionError( @@ -543,7 +544,7 @@ mod tests { test!( &[ Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), ComputeBudgetInstruction::request_heap_frame(MAX_HEAP_FRAME_BYTES), ComputeBudgetInstruction::set_compute_unit_price(u64::MAX), ], @@ -552,7 +553,7 @@ mod tests { 1 )), ComputeBudget { - max_units: 1, + compute_unit_limit: 1, heap_size: Some(MAX_HEAP_FRAME_BYTES as usize), ..ComputeBudget::default() } @@ -561,15 +562,15 @@ mod tests { test!( &[ Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - request_units_deprecated(MAX_UNITS, u32::MAX), + request_units_deprecated(MAX_COMPUTE_UNIT_LIMIT, u32::MAX), ComputeBudgetInstruction::request_heap_frame(MIN_HEAP_FRAME_BYTES as u32), ], Ok(PrioritizationFeeDetails::new( PrioritizationFeeType::Deprecated(u32::MAX as u64), - MAX_UNITS as u64, + MAX_COMPUTE_UNIT_LIMIT as u64, )), ComputeBudget { - max_units: MAX_UNITS as u64, + compute_unit_limit: MAX_COMPUTE_UNIT_LIMIT as u64, heap_size: Some(MIN_HEAP_FRAME_BYTES as usize), ..ComputeBudget::default() }, @@ -580,8 +581,8 @@ mod tests { test!( &[ Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), - ComputeBudgetInstruction::request_units(MAX_UNITS), - ComputeBudgetInstruction::request_units(MAX_UNITS - 1), + ComputeBudgetInstruction::set_compute_unit_limit(MAX_COMPUTE_UNIT_LIMIT), + ComputeBudgetInstruction::set_compute_unit_limit(MAX_COMPUTE_UNIT_LIMIT - 1), ], Err(TransactionError::DuplicateInstruction(2)), ComputeBudget::default() diff --git a/program-runtime/src/invoke_context.rs b/program-runtime/src/invoke_context.rs index 44debd277a..548fd48887 100644 --- a/program-runtime/src/invoke_context.rs +++ b/program-runtime/src/invoke_context.rs @@ -255,7 +255,7 @@ impl<'a> InvokeContext<'a> { log_collector, current_compute_budget: compute_budget, compute_budget, - compute_meter: ComputeMeter::new_ref(compute_budget.max_units), + compute_meter: ComputeMeter::new_ref(compute_budget.compute_unit_limit), accounts_data_meter: AccountsDataMeter::new(initial_accounts_data_len), executors, feature_set, @@ -351,7 +351,7 @@ impl<'a> InvokeContext<'a> { && program_id == Some(&crate::neon_evm_program::id()) { // Bump the compute budget for neon_evm - compute_budget.max_units = compute_budget.max_units.max(500_000); + compute_budget.compute_unit_limit = compute_budget.compute_unit_limit.max(500_000); } if !self.feature_set.is_active(&requestable_heap_size::id()) && self.feature_set.is_active(&neon_evm_compute_budget::id()) @@ -363,7 +363,8 @@ impl<'a> InvokeContext<'a> { self.current_compute_budget = compute_budget; if !self.feature_set.is_active(&tx_wide_compute_cap::id()) { - self.compute_meter = ComputeMeter::new_ref(self.current_compute_budget.max_units); + self.compute_meter = + ComputeMeter::new_ref(self.current_compute_budget.compute_unit_limit); } self.pre_accounts = Vec::with_capacity(instruction_accounts.len()); @@ -1760,20 +1761,21 @@ mod tests { let mut transaction_context = TransactionContext::new(accounts, 1, 3); let mut invoke_context = InvokeContext::new_mock(&mut transaction_context, &[]); invoke_context.feature_set = Arc::new(feature_set); - invoke_context.compute_budget = ComputeBudget::new(compute_budget::DEFAULT_UNITS); + invoke_context.compute_budget = + ComputeBudget::new(compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64); invoke_context.push(&[], &[0], &[]).unwrap(); assert_eq!( *invoke_context.get_compute_budget(), - ComputeBudget::new(compute_budget::DEFAULT_UNITS) + ComputeBudget::new(compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64) ); invoke_context.pop().unwrap(); invoke_context.push(&[], &[1], &[]).unwrap(); let expected_compute_budget = ComputeBudget { - max_units: 500_000, + compute_unit_limit: 500_000, heap_size: Some(256_usize.saturating_mul(1024)), - ..ComputeBudget::new(compute_budget::DEFAULT_UNITS) + ..ComputeBudget::new(compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64) }; assert_eq!( *invoke_context.get_compute_budget(), @@ -1784,7 +1786,7 @@ mod tests { invoke_context.push(&[], &[0], &[]).unwrap(); assert_eq!( *invoke_context.get_compute_budget(), - ComputeBudget::new(compute_budget::DEFAULT_UNITS) + ComputeBudget::new(compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64) ); invoke_context.pop().unwrap(); } diff --git a/program-runtime/src/prioritization_fee.rs b/program-runtime/src/prioritization_fee.rs index 0898b33ace..befc85b49d 100644 --- a/program-runtime/src/prioritization_fee.rs +++ b/program-runtime/src/prioritization_fee.rs @@ -15,15 +15,15 @@ pub struct PrioritizationFeeDetails { } impl PrioritizationFeeDetails { - pub fn new(fee_type: PrioritizationFeeType, max_compute_units: u64) -> Self { + pub fn new(fee_type: PrioritizationFeeType, compute_unit_limit: u64) -> Self { match fee_type { PrioritizationFeeType::Deprecated(fee) => { - let priority = if max_compute_units == 0 { + let priority = if compute_unit_limit == 0 { 0 } else { let micro_lamport_fee: MicroLamports = (fee as u128).saturating_mul(MICRO_LAMPORTS_PER_LAMPORT as u128); - let priority = micro_lamport_fee.saturating_div(max_compute_units as u128); + let priority = micro_lamport_fee.saturating_div(compute_unit_limit as u128); u64::try_from(priority).unwrap_or(u64::MAX) }; @@ -32,7 +32,7 @@ impl PrioritizationFeeDetails { PrioritizationFeeType::ComputeUnitPrice(cu_price) => { let fee = { let micro_lamport_fee: MicroLamports = - (cu_price as u128).saturating_mul(max_compute_units as u128); + (cu_price as u128).saturating_mul(compute_unit_limit as u128); let fee = micro_lamport_fee .saturating_add(MICRO_LAMPORTS_PER_LAMPORT.saturating_sub(1) as u128) .saturating_div(MICRO_LAMPORTS_PER_LAMPORT as u128); diff --git a/program-test/src/lib.rs b/program-test/src/lib.rs index 3cae577bb6..fa23564c1d 100644 --- a/program-test/src/lib.rs +++ b/program-test/src/lib.rs @@ -802,7 +802,7 @@ impl ProgramTest { bank.set_capitalization(); if let Some(max_units) = self.compute_max_units { bank.set_compute_budget(Some(ComputeBudget { - max_units, + compute_unit_limit: max_units, ..ComputeBudget::default() })); } diff --git a/programs/bpf/tests/programs.rs b/programs/bpf/tests/programs.rs index facf005420..841062e7fd 100644 --- a/programs/bpf/tests/programs.rs +++ b/programs/bpf/tests/programs.rs @@ -1398,7 +1398,7 @@ fn test_program_bpf_compute_budget() { ); let message = Message::new( &[ - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), Instruction::new_with_bincode(program_id, &0, vec![]), ], Some(&mint_keypair.pubkey()), diff --git a/runtime/src/bank.rs b/runtime/src/bank.rs index 23d2063d76..2a763236c7 100644 --- a/runtime/src/bank.rs +++ b/runtime/src/bank.rs @@ -4382,12 +4382,12 @@ impl Bank { compute_budget } else { let tx_wide_compute_cap = feature_set.is_active(&tx_wide_compute_cap::id()); - let compute_budget_max_units = if tx_wide_compute_cap { - compute_budget::MAX_UNITS + let compute_unit_limit = if tx_wide_compute_cap { + compute_budget::MAX_COMPUTE_UNIT_LIMIT } else { - compute_budget::DEFAULT_UNITS + compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT }; - let mut compute_budget = ComputeBudget::new(compute_budget_max_units); + let mut compute_budget = ComputeBudget::new(compute_unit_limit as u64); if tx_wide_compute_cap { let mut compute_budget_process_transaction_time = Measure::start("compute_budget_process_transaction_time"); @@ -4640,7 +4640,7 @@ impl Bank { let compute_fee = fee_structure .compute_fee_bins .iter() - .find(|bin| compute_budget.max_units <= bin.limit) + .find(|bin| compute_budget.compute_unit_limit <= bin.limit) .map(|bin| bin.fee) .unwrap_or_else(|| { fee_structure @@ -7251,7 +7251,7 @@ pub(crate) mod tests { }, crossbeam_channel::{bounded, unbounded}, solana_program_runtime::{ - compute_budget::MAX_UNITS, + compute_budget::MAX_COMPUTE_UNIT_LIMIT, invoke_context::InvokeContext, prioritization_fee::{PrioritizationFeeDetails, PrioritizationFeeType}, }, @@ -16424,7 +16424,7 @@ pub(crate) mod tests { assert_eq!( *compute_budget, ComputeBudget { - max_units: 200_000, + compute_unit_limit: 200_000, heap_size: None, ..ComputeBudget::default() } @@ -16436,7 +16436,7 @@ pub(crate) mod tests { let message = Message::new( &[ - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), ComputeBudgetInstruction::request_heap_frame(48 * 1024), Instruction::new_with_bincode(program_id, &0, vec![]), ], @@ -16468,7 +16468,7 @@ pub(crate) mod tests { assert_eq!( *compute_budget, ComputeBudget { - max_units: 1, + compute_unit_limit: 1, heap_size: Some(48 * 1024), ..ComputeBudget::default() } @@ -16480,7 +16480,7 @@ pub(crate) mod tests { let message = Message::new( &[ - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), ComputeBudgetInstruction::request_heap_frame(48 * 1024), Instruction::new_with_bincode(program_id, &0, vec![]), ], @@ -16519,7 +16519,7 @@ pub(crate) mod tests { assert_eq!( *compute_budget, ComputeBudget { - max_units: 1, + compute_unit_limit: 1, heap_size: Some(48 * 1024), ..ComputeBudget::default() } @@ -16540,7 +16540,7 @@ pub(crate) mod tests { // This message will be processed successfully let message1 = Message::new( &[ - ComputeBudgetInstruction::request_units(1), + ComputeBudgetInstruction::set_compute_unit_limit(1), ComputeBudgetInstruction::request_heap_frame(48 * 1024), Instruction::new_with_bincode(program_id, &0, vec![]), ], @@ -16778,8 +16778,17 @@ pub(crate) mod tests { // Explicit fee schedule for requested_compute_units in [ - 0, 5_000, 10_000, 100_000, 300_000, 500_000, 700_000, 900_000, 1_100_000, 1_300_000, - MAX_UNITS, + 0, + 5_000, + 10_000, + 100_000, + 300_000, + 500_000, + 700_000, + 900_000, + 1_100_000, + 1_300_000, + MAX_COMPUTE_UNIT_LIMIT, ] { const PRIORITIZATION_FEE_RATE: u64 = 42; let prioritization_fee_details = PrioritizationFeeDetails::new( @@ -16788,7 +16797,7 @@ pub(crate) mod tests { ); let message = SanitizedMessage::try_from(Message::new( &[ - ComputeBudgetInstruction::request_units(requested_compute_units), + ComputeBudgetInstruction::set_compute_unit_limit(requested_compute_units), ComputeBudgetInstruction::set_compute_unit_price(PRIORITIZATION_FEE_RATE), Instruction::new_with_bincode(Pubkey::new_unique(), &0, vec![]), ], @@ -17633,9 +17642,9 @@ pub(crate) mod tests { None, ); - let compute_budget = bank - .compute_budget - .unwrap_or_else(|| ComputeBudget::new(compute_budget::DEFAULT_UNITS)); + let compute_budget = bank.compute_budget.unwrap_or_else(|| { + ComputeBudget::new(compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64) + }); let transaction_context = TransactionContext::new( loaded_txs[0].0.as_ref().unwrap().accounts.clone(), compute_budget.max_invoke_depth.saturating_add(1), diff --git a/runtime/src/cost_model.rs b/runtime/src/cost_model.rs index 79a7bbabbe..7ce546ab64 100644 --- a/runtime/src/cost_model.rs +++ b/runtime/src/cost_model.rs @@ -117,7 +117,9 @@ impl CostModel { match self.instruction_execution_cost_table.get_cost(program_key) { Some(cost) => *cost, None => { - let default_value = self.instruction_execution_cost_table.get_default_units(); + let default_value = self + .instruction_execution_cost_table + .get_default_compute_unit_limit(); debug!( "Program {:?} does not have aggregated cost, using default value {}", program_key, default_value @@ -286,7 +288,9 @@ mod tests { // unknown program is assigned with default cost assert_eq!( - testee.instruction_execution_cost_table.get_default_units(), + testee + .instruction_execution_cost_table + .get_default_compute_unit_limit(), testee.find_instruction_cost( &Pubkey::from_str("unknown111111111111111111111111111111111111").unwrap() ) @@ -421,7 +425,10 @@ mod tests { debug!("many random transaction {:?}", tx); let testee = CostModel::default(); - let expected_cost = testee.instruction_execution_cost_table.get_default_units() * 2; + let expected_cost = testee + .instruction_execution_cost_table + .get_default_compute_unit_limit() + * 2; let mut tx_cost = TransactionCost::default(); testee.get_transaction_cost(&mut tx_cost, &tx); assert_eq!(0, tx_cost.builtins_execution_cost); @@ -471,7 +478,7 @@ mod tests { assert_eq!( cost_model .instruction_execution_cost_table - .get_default_units(), + .get_default_compute_unit_limit(), cost_model.find_instruction_cost(&key1) ); diff --git a/runtime/src/execute_cost_table.rs b/runtime/src/execute_cost_table.rs index 417e0ddd66..922d31c1c0 100644 --- a/runtime/src/execute_cost_table.rs +++ b/runtime/src/execute_cost_table.rs @@ -4,8 +4,8 @@ /// When its capacity limit is reached, it prunes old and less-used programs /// to make room for new ones. use { - log::*, solana_program_runtime::compute_budget::DEFAULT_UNITS, solana_sdk::pubkey::Pubkey, - std::collections::HashMap, + log::*, solana_program_runtime::compute_budget::DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT, + solana_sdk::pubkey::Pubkey, std::collections::HashMap, }; // prune is rather expensive op, free up bulk space in each operation @@ -44,24 +44,24 @@ impl ExecuteCostTable { self.table.len() } - /// default program cost, set to ComputeBudget::DEFAULT_UNITS - pub fn get_default_units(&self) -> u64 { - DEFAULT_UNITS as u64 + /// default program cost, set to ComputeBudget::DEFAULT_COMPUTE_UNIT_LIMIT + pub fn get_default_compute_unit_limit(&self) -> u64 { + DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT as u64 } /// average cost of all recorded programs - pub fn get_global_average_units(&self) -> u64 { + pub fn get_global_average_program_cost(&self) -> u64 { if self.table.is_empty() { - self.get_default_units() + self.get_default_compute_unit_limit() } else { self.table.iter().map(|(_, value)| value).sum::() / self.get_count() as u64 } } /// the most frequently occurring program's cost - pub fn get_statistical_mode_units(&self) -> u64 { + pub fn get_statistical_mode_program_cost(&self) -> u64 { if self.occurrences.is_empty() { - self.get_default_units() + self.get_default_compute_unit_limit() } else { let key = self .occurrences @@ -75,8 +75,9 @@ impl ExecuteCostTable { } /// returns None if program doesn't exist in table. In this case, - /// `get_default_units()`, `get_global_average_units()` or `get_statistical_mode_units()` - /// can be used to assign a value to new program. + /// `get_default_compute_unit_limit()`, `get_global_average_program_cost()` + /// or `get_statistical_mode_program_cost()` can be used to assign a value + /// to new program. pub fn get_cost(&self, key: &Pubkey) -> Option<&u64> { self.table.get(key) } @@ -225,15 +226,18 @@ mod tests { // insert one record testee.upsert(&key1, cost1); assert_eq!(1, testee.get_count()); - assert_eq!(cost1, testee.get_global_average_units()); - assert_eq!(cost1, testee.get_statistical_mode_units()); + assert_eq!(cost1, testee.get_global_average_program_cost()); + assert_eq!(cost1, testee.get_statistical_mode_program_cost()); assert_eq!(&cost1, testee.get_cost(&key1).unwrap()); // insert 2nd record testee.upsert(&key2, cost2); assert_eq!(2, testee.get_count()); - assert_eq!((cost1 + cost2) / 2_u64, testee.get_global_average_units()); - assert_eq!(cost2, testee.get_statistical_mode_units()); + assert_eq!( + (cost1 + cost2) / 2_u64, + testee.get_global_average_program_cost() + ); + assert_eq!(cost2, testee.get_statistical_mode_program_cost()); assert_eq!(&cost1, testee.get_cost(&key1).unwrap()); assert_eq!(&cost2, testee.get_cost(&key2).unwrap()); @@ -242,9 +246,12 @@ mod tests { assert_eq!(2, testee.get_count()); assert_eq!( ((cost1 + cost2) / 2 + cost2) / 2_u64, - testee.get_global_average_units() + testee.get_global_average_program_cost() + ); + assert_eq!( + (cost1 + cost2) / 2, + testee.get_statistical_mode_program_cost() ); - assert_eq!((cost1 + cost2) / 2, testee.get_statistical_mode_units()); assert_eq!(&((cost1 + cost2) / 2), testee.get_cost(&key1).unwrap()); assert_eq!(&cost2, testee.get_cost(&key2).unwrap()); } @@ -278,8 +285,11 @@ mod tests { // insert 3rd record, pushes out the oldest (eg 1st) record testee.upsert(&key3, cost3); assert_eq!(2, testee.get_count()); - assert_eq!((cost2 + cost3) / 2_u64, testee.get_global_average_units()); - assert_eq!(cost3, testee.get_statistical_mode_units()); + assert_eq!( + (cost2 + cost3) / 2_u64, + testee.get_global_average_program_cost() + ); + assert_eq!(cost3, testee.get_statistical_mode_program_cost()); assert!(testee.get_cost(&key1).is_none()); assert_eq!(&cost2, testee.get_cost(&key2).unwrap()); assert_eq!(&cost3, testee.get_cost(&key3).unwrap()); @@ -290,9 +300,12 @@ mod tests { testee.upsert(&key4, cost4); assert_eq!( ((cost1 + cost2) / 2 + cost4) / 2_u64, - testee.get_global_average_units() + testee.get_global_average_program_cost() + ); + assert_eq!( + (cost1 + cost2) / 2, + testee.get_statistical_mode_program_cost() ); - assert_eq!((cost1 + cost2) / 2, testee.get_statistical_mode_units()); assert_eq!(2, testee.get_count()); assert!(testee.get_cost(&key1).is_none()); assert_eq!(&((cost1 + cost2) / 2), testee.get_cost(&key2).unwrap()); diff --git a/sdk/src/compute_budget.rs b/sdk/src/compute_budget.rs index 19c510a7e7..7375f55f08 100644 --- a/sdk/src/compute_budget.rs +++ b/sdk/src/compute_budget.rs @@ -32,9 +32,8 @@ pub enum ComputeBudgetInstruction { /// size applies to each program executed in the transaction, including all /// calls to CPIs. RequestHeapFrame(u32), - /// Request a specific maximum number of compute units the transaction is - /// allowed to consume and an additional fee to pay. - RequestUnits(u32), + /// Set a specific compute unit limit that the transaction is allowed to consume. + SetComputeUnitLimit(u32), /// Set a compute unit price in "micro-lamports" to pay a higher transaction /// fee for higher transaction prioritization. SetComputeUnitPrice(u64), @@ -46,9 +45,9 @@ impl ComputeBudgetInstruction { Instruction::new_with_borsh(id(), &Self::RequestHeapFrame(bytes), vec![]) } - /// Create a `ComputeBudgetInstruction::RequestUnits` `Instruction` - pub fn request_units(units: u32) -> Instruction { - Instruction::new_with_borsh(id(), &Self::RequestUnits(units), vec![]) + /// Create a `ComputeBudgetInstruction::SetComputeUnitLimit` `Instruction` + pub fn set_compute_unit_limit(units: u32) -> Instruction { + Instruction::new_with_borsh(id(), &Self::SetComputeUnitLimit(units), vec![]) } /// Create a `ComputeBudgetInstruction::SetComputeUnitPrice` `Instruction` diff --git a/test-validator/src/lib.rs b/test-validator/src/lib.rs index 2c697fcb06..02cffd6c47 100644 --- a/test-validator/src/lib.rs +++ b/test-validator/src/lib.rs @@ -113,7 +113,7 @@ pub struct TestValidatorGenesis { pub geyser_plugin_config_files: Option>, pub accounts_db_caching_enabled: bool, deactivate_feature_set: HashSet, - max_compute_units: Option, + compute_unit_limit: Option, } impl Default for TestValidatorGenesis { @@ -141,7 +141,7 @@ impl Default for TestValidatorGenesis { geyser_plugin_config_files: Option::>::default(), accounts_db_caching_enabled: bool::default(), deactivate_feature_set: HashSet::::default(), - max_compute_units: Option::::default(), + compute_unit_limit: Option::::default(), } } } @@ -239,11 +239,16 @@ impl TestValidatorGenesis { self } - pub fn max_compute_units(&mut self, max_compute_units: u64) -> &mut Self { - self.max_compute_units = Some(max_compute_units); + pub fn compute_unit_limit(&mut self, compute_unit_limit: u64) -> &mut Self { + self.compute_unit_limit = Some(compute_unit_limit); self } + #[deprecated(note = "Please use `compute_unit_limit` instead")] + pub fn max_compute_units(&mut self, max_compute_units: u64) -> &mut Self { + self.compute_unit_limit(max_compute_units) + } + /// Add an account to the test environment pub fn add_account(&mut self, address: Pubkey, account: AccountSharedData) -> &mut Self { self.accounts.insert(address, account); @@ -686,10 +691,12 @@ impl TestValidator { let runtime_config = RuntimeConfig { bpf_jit: !config.no_bpf_jit, - compute_budget: config.max_compute_units.map(|max_units| ComputeBudget { - max_units, - ..ComputeBudget::default() - }), + compute_budget: config + .compute_unit_limit + .map(|compute_unit_limit| ComputeBudget { + compute_unit_limit, + ..ComputeBudget::default() + }), }; let mut validator_config = ValidatorConfig { diff --git a/validator/src/bin/solana-test-validator.rs b/validator/src/bin/solana-test-validator.rs index 66e455faa9..2e5e36de26 100644 --- a/validator/src/bin/solana-test-validator.rs +++ b/validator/src/bin/solana-test-validator.rs @@ -369,12 +369,13 @@ fn main() { .help("deactivate this feature in genesis.") ) .arg( - Arg::with_name("max_compute_units") - .long("max-compute-units") + Arg::with_name("compute_unit_limit") + .long("compute-unit-limit") + .alias("max-compute-units") .value_name("COMPUTE_UNITS") .validator(is_parsable::) .takes_value(true) - .help("Override the runtime's maximum compute units") + .help("Override the runtime's compute unit limit per transaction") ) .get_matches(); @@ -484,7 +485,7 @@ fn main() { exit(1); }) }); - let max_compute_units = value_t!(matches, "max_compute_units", u64).ok(); + let compute_unit_limit = value_t!(matches, "compute_unit_limit", u64).ok(); let faucet_addr = Some(SocketAddr::new( IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), @@ -762,8 +763,8 @@ fn main() { ); } - if let Some(max_compute_units) = max_compute_units { - genesis.max_compute_units(max_compute_units); + if let Some(compute_unit_limit) = compute_unit_limit { + genesis.compute_unit_limit(compute_unit_limit); } match genesis.start_with_mint_address(mint_address, socket_addr_space) {