use {
solana_fee_structure::FeeDetails, solana_program_entrypoint::HEAP_LENGTH,
solana_transaction_context::MAX_INSTRUCTION_TRACE_LENGTH, std::num::NonZeroU32,
};
pub const MAX_INSTRUCTION_STACK_DEPTH: usize = 5;
pub const MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268: usize = 9;
fn get_max_instruction_stack_depth(simd_0268_active: bool) -> usize {
if simd_0268_active {
MAX_INSTRUCTION_STACK_DEPTH_SIMD_0268
} else {
MAX_INSTRUCTION_STACK_DEPTH
}
}
pub const DEFAULT_INVOCATION_COST: u64 = 1000;
pub const INVOKE_UNITS_COST_SIMD_0339: u64 = 946;
fn get_invoke_unit_cost(simd_0339_active: bool) -> u64 {
if simd_0339_active {
INVOKE_UNITS_COST_SIMD_0339
} else {
DEFAULT_INVOCATION_COST
}
}
pub const MAX_CALL_DEPTH: usize = 64;
pub const STACK_FRAME_SIZE: usize = 4096;
pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000;
pub const DEFAULT_HEAP_COST: u64 = 8;
pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000;
pub const MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT: u32 = 3_000;
pub const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024;
pub const MIN_HEAP_FRAME_BYTES: u32 = HEAP_LENGTH as u32;
pub const MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES: NonZeroU32 =
NonZeroU32::new(64 * 1024 * 1024).unwrap();
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SVMTransactionExecutionBudget {
pub compute_unit_limit: u64,
pub max_instruction_stack_depth: usize,
pub max_instruction_trace_length: usize,
pub sha256_max_slices: u64,
pub max_call_depth: usize,
pub stack_frame_size: usize,
pub heap_size: u32,
}
#[cfg(feature = "dev-context-only-utils")]
impl Default for SVMTransactionExecutionBudget {
fn default() -> Self {
Self::new_with_defaults( false)
}
}
impl SVMTransactionExecutionBudget {
pub fn new_with_defaults(simd_0268_active: bool) -> Self {
SVMTransactionExecutionBudget {
compute_unit_limit: u64::from(MAX_COMPUTE_UNIT_LIMIT),
max_instruction_stack_depth: get_max_instruction_stack_depth(simd_0268_active),
max_instruction_trace_length: MAX_INSTRUCTION_TRACE_LENGTH,
sha256_max_slices: 20_000,
max_call_depth: MAX_CALL_DEPTH,
stack_frame_size: STACK_FRAME_SIZE,
heap_size: u32::try_from(solana_program_entrypoint::HEAP_LENGTH).unwrap(),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SVMTransactionExecutionCost {
pub log_64_units: u64,
pub create_program_address_units: u64,
pub invoke_units: u64,
pub sha256_base_cost: u64,
pub sha256_byte_cost: u64,
pub log_pubkey_units: u64,
pub cpi_bytes_per_unit: u64,
pub sysvar_base_cost: u64,
pub secp256k1_recover_cost: u64,
pub syscall_base_cost: u64,
pub curve25519_edwards_validate_point_cost: u64,
pub curve25519_edwards_add_cost: u64,
pub curve25519_edwards_subtract_cost: u64,
pub curve25519_edwards_multiply_cost: u64,
pub curve25519_edwards_msm_base_cost: u64,
pub curve25519_edwards_msm_incremental_cost: u64,
pub curve25519_ristretto_validate_point_cost: u64,
pub curve25519_ristretto_add_cost: u64,
pub curve25519_ristretto_subtract_cost: u64,
pub curve25519_ristretto_multiply_cost: u64,
pub curve25519_ristretto_msm_base_cost: u64,
pub curve25519_ristretto_msm_incremental_cost: u64,
pub heap_cost: u64,
pub mem_op_base_cost: u64,
pub alt_bn128_addition_cost: u64,
pub alt_bn128_multiplication_cost: u64,
pub alt_bn128_pairing_one_pair_cost_first: u64,
pub alt_bn128_pairing_one_pair_cost_other: u64,
pub big_modular_exponentiation_base_cost: u64,
pub big_modular_exponentiation_cost_divisor: u64,
pub poseidon_cost_coefficient_a: u64,
pub poseidon_cost_coefficient_c: u64,
pub get_remaining_compute_units_cost: u64,
pub alt_bn128_g1_compress: u64,
pub alt_bn128_g1_decompress: u64,
pub alt_bn128_g2_compress: u64,
pub alt_bn128_g2_decompress: u64,
}
impl Default for SVMTransactionExecutionCost {
fn default() -> Self {
Self::new_with_defaults( false)
}
}
impl SVMTransactionExecutionCost {
pub fn new_with_defaults(simd_0339_active: bool) -> Self {
SVMTransactionExecutionCost {
log_64_units: 100,
create_program_address_units: 1500,
invoke_units: get_invoke_unit_cost(simd_0339_active),
sha256_base_cost: 85,
sha256_byte_cost: 1,
log_pubkey_units: 100,
cpi_bytes_per_unit: 250, sysvar_base_cost: 100,
secp256k1_recover_cost: 25_000,
syscall_base_cost: 100,
curve25519_edwards_validate_point_cost: 159,
curve25519_edwards_add_cost: 473,
curve25519_edwards_subtract_cost: 475,
curve25519_edwards_multiply_cost: 2_177,
curve25519_edwards_msm_base_cost: 2_273,
curve25519_edwards_msm_incremental_cost: 758,
curve25519_ristretto_validate_point_cost: 169,
curve25519_ristretto_add_cost: 521,
curve25519_ristretto_subtract_cost: 519,
curve25519_ristretto_multiply_cost: 2_208,
curve25519_ristretto_msm_base_cost: 2303,
curve25519_ristretto_msm_incremental_cost: 788,
heap_cost: DEFAULT_HEAP_COST,
mem_op_base_cost: 10,
alt_bn128_addition_cost: 334,
alt_bn128_multiplication_cost: 3_840,
alt_bn128_pairing_one_pair_cost_first: 36_364,
alt_bn128_pairing_one_pair_cost_other: 12_121,
big_modular_exponentiation_base_cost: 190,
big_modular_exponentiation_cost_divisor: 2,
poseidon_cost_coefficient_a: 61,
poseidon_cost_coefficient_c: 542,
get_remaining_compute_units_cost: 100,
alt_bn128_g1_compress: 30,
alt_bn128_g1_decompress: 398,
alt_bn128_g2_compress: 86,
alt_bn128_g2_decompress: 13610,
}
}
pub fn poseidon_cost(&self, nr_inputs: u64) -> Option<u64> {
let squared_inputs = nr_inputs.checked_pow(2)?;
let mul_result = self
.poseidon_cost_coefficient_a
.checked_mul(squared_inputs)?;
let final_result = mul_result.checked_add(self.poseidon_cost_coefficient_c)?;
Some(final_result)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct SVMTransactionExecutionAndFeeBudgetLimits {
pub budget: SVMTransactionExecutionBudget,
pub loaded_accounts_data_size_limit: NonZeroU32,
pub fee_details: FeeDetails,
}
#[cfg(feature = "dev-context-only-utils")]
impl Default for SVMTransactionExecutionAndFeeBudgetLimits {
fn default() -> Self {
Self {
budget: SVMTransactionExecutionBudget::default(),
loaded_accounts_data_size_limit: MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES,
fee_details: FeeDetails::default(),
}
}
}
#[cfg(feature = "dev-context-only-utils")]
impl SVMTransactionExecutionAndFeeBudgetLimits {
pub fn with_fee(fee_details: FeeDetails) -> Self {
Self {
fee_details,
..SVMTransactionExecutionAndFeeBudgetLimits::default()
}
}
}