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