Use consistent naming for compute unit limit (#25229)
* Use consistent naming for compute unit limit * feedback
This commit is contained in:
parent
66c9513eb0
commit
a1522d0024
|
@ -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
|
||||
|
|
|
@ -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<PrioritizationFeeDetails, TransactionError> {
|
||||
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()
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -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()),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
||||
|
|
|
@ -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::<u64>() / 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());
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -113,7 +113,7 @@ pub struct TestValidatorGenesis {
|
|||
pub geyser_plugin_config_files: Option<Vec<PathBuf>>,
|
||||
pub accounts_db_caching_enabled: bool,
|
||||
deactivate_feature_set: HashSet<Pubkey>,
|
||||
max_compute_units: Option<u64>,
|
||||
compute_unit_limit: Option<u64>,
|
||||
}
|
||||
|
||||
impl Default for TestValidatorGenesis {
|
||||
|
@ -141,7 +141,7 @@ impl Default for TestValidatorGenesis {
|
|||
geyser_plugin_config_files: Option::<Vec<PathBuf>>::default(),
|
||||
accounts_db_caching_enabled: bool::default(),
|
||||
deactivate_feature_set: HashSet::<Pubkey>::default(),
|
||||
max_compute_units: Option::<u64>::default(),
|
||||
compute_unit_limit: Option::<u64>::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,8 +691,10 @@ impl TestValidator {
|
|||
|
||||
let runtime_config = RuntimeConfig {
|
||||
bpf_jit: !config.no_bpf_jit,
|
||||
compute_budget: config.max_compute_units.map(|max_units| ComputeBudget {
|
||||
max_units,
|
||||
compute_budget: config
|
||||
.compute_unit_limit
|
||||
.map(|compute_unit_limit| ComputeBudget {
|
||||
compute_unit_limit,
|
||||
..ComputeBudget::default()
|
||||
}),
|
||||
};
|
||||
|
|
|
@ -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::<u64>)
|
||||
.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) {
|
||||
|
|
Loading…
Reference in New Issue