diff --git a/compute-budget-instruction/Cargo.toml b/compute-budget-instruction/Cargo.toml index 4e38f6a752eaea..63312d257d0a4d 100644 --- a/compute-budget-instruction/Cargo.toml +++ b/compute-budget-instruction/Cargo.toml @@ -13,7 +13,7 @@ edition = { workspace = true } log = { workspace = true } solana-borsh = { workspace = true } solana-builtins-default-costs = { workspace = true, features = ["svm-internal"] } -solana-compute-budget = { workspace = true } +solana-compute-budget = { workspace = true, features = ["svm-internal"] } solana-compute-budget-interface = { workspace = true } solana-feature-set = { workspace = true } solana-instruction = { workspace = true } diff --git a/compute-budget/Cargo.toml b/compute-budget/Cargo.toml index 78d4761cdc664b..53057ae3944f69 100644 --- a/compute-budget/Cargo.toml +++ b/compute-budget/Cargo.toml @@ -20,6 +20,7 @@ solana-program-entrypoint = { workspace = true } [features] dev-context-only-utils = ["dep:qualifier_attr"] frozen-abi = ["dep:solana-frozen-abi", "solana-fee-structure/frozen-abi"] +svm-internal = ["dep:qualifier_attr"] [lints] workspace = true diff --git a/compute-budget/src/compute_budget.rs b/compute-budget/src/compute_budget.rs index 39247062f25c8d..7f972c3ac3ba1b 100644 --- a/compute-budget/src/compute_budget.rs +++ b/compute-budget/src/compute_budget.rs @@ -1,6 +1,6 @@ use crate::compute_budget_limits::{self, ComputeBudgetLimits, DEFAULT_HEAP_COST}; -#[cfg(feature = "dev-context-only-utils")] -use qualifier_attr::qualifiers; +#[cfg(any(feature = "dev-context-only-utils", feature = "svm-internal"))] +use qualifier_attr::{field_qualifiers, qualifiers}; #[cfg(feature = "frozen-abi")] impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget { @@ -12,123 +12,176 @@ impl ::solana_frozen_abi::abi_example::AbiExample for ComputeBudget { /// Max instruction stack depth. This is the maximum nesting of instructions that can happen during /// a transaction. -pub const MAX_INSTRUCTION_STACK_DEPTH: usize = 5; +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const MAX_INSTRUCTION_STACK_DEPTH: usize = 5; /// Max call depth. This is the maximum nesting of SBF to SBF call that can happen within a program. -pub const MAX_CALL_DEPTH: usize = 64; +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const MAX_CALL_DEPTH: usize = 64; /// The size of one SBF stack frame. -pub const STACK_FRAME_SIZE: usize = 4096; +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const STACK_FRAME_SIZE: usize = 4096; #[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr( + any(feature = "dev-context-only-utils", feature = "svm-internal"), + field_qualifiers( + compute_unit_limit(pub), + log_64_units(pub), + create_program_address_units(pub), + invoke_units(pub), + max_instruction_stack_depth(pub), + max_instruction_trace_length(pub), + sha256_base_cost(pub), + sha256_byte_cost(pub), + sha256_max_slices(pub), + max_call_depth(pub), + stack_frame_size(pub), + log_pubkey_units(pub), + max_cpi_instruction_size(pub), + cpi_bytes_per_unit(pub), + sysvar_base_cost(pub), + secp256k1_recover_cost(pub), + syscall_base_cost(pub), + curve25519_edwards_validate_point_cost(pub), + curve25519_edwards_add_cost(pub), + curve25519_edwards_subtract_cost(pub), + curve25519_edwards_multiply_cost(pub), + curve25519_edwards_msm_base_cost(pub), + curve25519_edwards_msm_incremental_cost(pub), + curve25519_ristretto_validate_point_cost(pub), + curve25519_ristretto_add_cost(pub), + curve25519_ristretto_subtract_cost(pub), + curve25519_ristretto_multiply_cost(pub), + curve25519_ristretto_msm_base_cost(pub), + curve25519_ristretto_msm_incremental_cost(pub), + heap_size(pub), + heap_cost(pub), + mem_op_base_cost(pub), + alt_bn128_addition_cost(pub), + alt_bn128_multiplication_cost(pub), + alt_bn128_pairing_one_pair_cost_first(pub), + alt_bn128_pairing_one_pair_cost_other(pub), + big_modular_exponentiation_base_cost(pub), + big_modular_exponentiation_cost_divisor(pub), + poseidon_cost_coefficient_a(pub), + poseidon_cost_coefficient_c(pub), + get_remaining_compute_units_cost(pub), + alt_bn128_g1_compress(pub), + alt_bn128_g1_decompress(pub), + alt_bn128_g2_compress(pub), + alt_bn128_g2_decompress(pub), + ) +)] pub struct ComputeBudget { /// 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, + compute_unit_limit: u64, /// Number of compute units consumed by a log_u64 call - pub log_64_units: u64, + log_64_units: u64, /// Number of compute units consumed by a create_program_address call - pub create_program_address_units: u64, + create_program_address_units: u64, /// Number of compute units consumed by an invoke call (not including the cost incurred by /// the called program) - pub invoke_units: u64, + invoke_units: u64, /// Maximum program instruction invocation stack depth. Invocation stack /// depth starts at 1 for transaction instructions and the stack depth is /// incremented each time a program invokes an instruction and decremented /// when a program returns. - pub max_instruction_stack_depth: usize, + max_instruction_stack_depth: usize, /// Maximum cross-program invocation and instructions per transaction - pub max_instruction_trace_length: usize, + max_instruction_trace_length: usize, /// Base number of compute units consumed to call SHA256 - pub sha256_base_cost: u64, + sha256_base_cost: u64, /// Incremental number of units consumed by SHA256 (based on bytes) - pub sha256_byte_cost: u64, + sha256_byte_cost: u64, /// Maximum number of slices hashed per syscall - pub sha256_max_slices: u64, + sha256_max_slices: u64, /// Maximum SBF to BPF call depth - pub max_call_depth: usize, + max_call_depth: usize, /// Size of a stack frame in bytes, must match the size specified in the LLVM SBF backend - pub stack_frame_size: usize, + stack_frame_size: usize, /// Number of compute units consumed by logging a `Pubkey` - pub log_pubkey_units: u64, + log_pubkey_units: u64, /// Maximum cross-program invocation instruction size - pub max_cpi_instruction_size: usize, + max_cpi_instruction_size: usize, /// Number of account data bytes per compute unit charged during a cross-program invocation - pub cpi_bytes_per_unit: u64, + cpi_bytes_per_unit: u64, /// Base number of compute units consumed to get a sysvar - pub sysvar_base_cost: u64, + sysvar_base_cost: u64, /// Number of compute units consumed to call secp256k1_recover - pub secp256k1_recover_cost: u64, + secp256k1_recover_cost: u64, /// Number of compute units consumed to do a syscall without any work - pub syscall_base_cost: u64, + syscall_base_cost: u64, /// Number of compute units consumed to validate a curve25519 edwards point - pub curve25519_edwards_validate_point_cost: u64, + curve25519_edwards_validate_point_cost: u64, /// Number of compute units consumed to add two curve25519 edwards points - pub curve25519_edwards_add_cost: u64, + curve25519_edwards_add_cost: u64, /// Number of compute units consumed to subtract two curve25519 edwards points - pub curve25519_edwards_subtract_cost: u64, + curve25519_edwards_subtract_cost: u64, /// Number of compute units consumed to multiply a curve25519 edwards point - pub curve25519_edwards_multiply_cost: u64, + curve25519_edwards_multiply_cost: u64, /// Number of compute units consumed for a multiscalar multiplication (msm) of edwards points. /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`. - pub curve25519_edwards_msm_base_cost: u64, + curve25519_edwards_msm_base_cost: u64, /// Number of compute units consumed for a multiscalar multiplication (msm) of edwards points. /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`. - pub curve25519_edwards_msm_incremental_cost: u64, + curve25519_edwards_msm_incremental_cost: u64, /// Number of compute units consumed to validate a curve25519 ristretto point - pub curve25519_ristretto_validate_point_cost: u64, + curve25519_ristretto_validate_point_cost: u64, /// Number of compute units consumed to add two curve25519 ristretto points - pub curve25519_ristretto_add_cost: u64, + curve25519_ristretto_add_cost: u64, /// Number of compute units consumed to subtract two curve25519 ristretto points - pub curve25519_ristretto_subtract_cost: u64, + curve25519_ristretto_subtract_cost: u64, /// Number of compute units consumed to multiply a curve25519 ristretto point - pub curve25519_ristretto_multiply_cost: u64, + curve25519_ristretto_multiply_cost: u64, /// Number of compute units consumed for a multiscalar multiplication (msm) of ristretto points. /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`. - pub curve25519_ristretto_msm_base_cost: u64, + curve25519_ristretto_msm_base_cost: u64, /// Number of compute units consumed for a multiscalar multiplication (msm) of ristretto points. /// The total cost is calculated as `msm_base_cost + (length - 1) * msm_incremental_cost`. - pub curve25519_ristretto_msm_incremental_cost: u64, + curve25519_ristretto_msm_incremental_cost: u64, /// program heap region size, default: solana_sdk::entrypoint::HEAP_LENGTH - pub heap_size: u32, + heap_size: u32, /// Number of compute units per additional 32k heap above the default (~.5 /// us per 32k at 15 units/us rounded up) - pub heap_cost: u64, + heap_cost: u64, /// Memory operation syscall base cost - pub mem_op_base_cost: u64, + mem_op_base_cost: u64, /// Number of compute units consumed to call alt_bn128_addition - pub alt_bn128_addition_cost: u64, + alt_bn128_addition_cost: u64, /// Number of compute units consumed to call alt_bn128_multiplication. - pub alt_bn128_multiplication_cost: u64, + alt_bn128_multiplication_cost: u64, /// Total cost will be alt_bn128_pairing_one_pair_cost_first /// + alt_bn128_pairing_one_pair_cost_other * (num_elems - 1) - pub alt_bn128_pairing_one_pair_cost_first: u64, - pub alt_bn128_pairing_one_pair_cost_other: u64, + alt_bn128_pairing_one_pair_cost_first: u64, + alt_bn128_pairing_one_pair_cost_other: u64, /// Big integer modular exponentiation base cost - pub big_modular_exponentiation_base_cost: u64, + big_modular_exponentiation_base_cost: u64, /// Big integer moduler exponentiation cost divisor /// The modular exponentiation cost is computed as /// `input_length`/`big_modular_exponentiation_cost_divisor` + `big_modular_exponentiation_base_cost` - pub big_modular_exponentiation_cost_divisor: u64, + big_modular_exponentiation_cost_divisor: u64, /// Coefficient `a` of the quadratic function which determines the number /// of compute units consumed to call poseidon syscall for a given number /// of inputs. - pub poseidon_cost_coefficient_a: u64, + poseidon_cost_coefficient_a: u64, /// Coefficient `c` of the quadratic function which determines the number /// of compute units consumed to call poseidon syscall for a given number /// of inputs. - pub poseidon_cost_coefficient_c: u64, + poseidon_cost_coefficient_c: u64, /// Number of compute units consumed for accessing the remaining compute units. - pub get_remaining_compute_units_cost: u64, + get_remaining_compute_units_cost: u64, /// Number of compute units consumed to call alt_bn128_g1_compress. - pub alt_bn128_g1_compress: u64, + alt_bn128_g1_compress: u64, /// Number of compute units consumed to call alt_bn128_g1_decompress. - pub alt_bn128_g1_decompress: u64, + alt_bn128_g1_decompress: u64, /// Number of compute units consumed to call alt_bn128_g2_compress. - pub alt_bn128_g2_compress: u64, + alt_bn128_g2_compress: u64, /// Number of compute units consumed to call alt_bn128_g2_decompress. - pub alt_bn128_g2_decompress: u64, + alt_bn128_g2_decompress: u64, } impl Default for ComputeBudget { @@ -218,7 +271,9 @@ impl ComputeBudget { /// * function; `61*3^2 + 542 = 1091` /// /// [0] https://github.com/Lightprotocol/light-poseidon#performance - pub fn poseidon_cost(&self, nr_inputs: u64) -> Option { + #[cfg(feature = "svm-internal")] + #[cfg_attr(feature = "svm-internal", qualifiers(pub))] + fn poseidon_cost(&self, nr_inputs: u64) -> Option { let squared_inputs = nr_inputs.checked_pow(2)?; let mul_result = self .poseidon_cost_coefficient_a diff --git a/compute-budget/src/compute_budget_limits.rs b/compute-budget/src/compute_budget_limits.rs index ac951a2014a36a..56354625996c19 100644 --- a/compute-budget/src/compute_budget_limits.rs +++ b/compute-budget/src/compute_budget_limits.rs @@ -1,3 +1,5 @@ +#[cfg(any(feature = "dev-context-only-utils", feature = "svm-internal"))] +use qualifier_attr::{field_qualifiers, qualifiers}; use { solana_fee_structure::FeeBudgetLimits, solana_program_entrypoint::HEAP_LENGTH, std::num::NonZeroU32, @@ -5,14 +7,25 @@ use { /// Roughly 0.5us/page, where page is 32K; given roughly 15CU/us, the /// default heap page cost = 0.5 * 15 ~= 8CU/page -pub const DEFAULT_HEAP_COST: u64 = 8; -pub const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000; +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +pub(crate) const DEFAULT_HEAP_COST: u64 = 8; + +#[cfg(feature = "svm-internal")] +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const DEFAULT_INSTRUCTION_COMPUTE_UNIT_LIMIT: u32 = 200_000; // SIMD-170 defines max CUs to be allocated for any builtin program instructions, that // have not been migrated to sBPF programs. -pub const MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT: u32 = 3_000; -pub const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000; -pub const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024; -pub const MIN_HEAP_FRAME_BYTES: u32 = HEAP_LENGTH as u32; +#[cfg(feature = "svm-internal")] +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const MAX_BUILTIN_ALLOCATION_COMPUTE_UNIT_LIMIT: u32 = 3_000; + +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +pub(crate) const MAX_COMPUTE_UNIT_LIMIT: u32 = 1_400_000; +#[cfg(feature = "svm-internal")] +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const MAX_HEAP_FRAME_BYTES: u32 = 256 * 1024; +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const MIN_HEAP_FRAME_BYTES: u32 = HEAP_LENGTH as u32; type MicroLamports = u128; @@ -21,15 +34,26 @@ const MICRO_LAMPORTS_PER_LAMPORT: u64 = 1_000_000; /// The total accounts data a transaction can load is limited to 64MiB to not break /// anyone in Mainnet-beta today. It can be set by set_loaded_accounts_data_size_limit instruction -pub const MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES: NonZeroU32 = +#[cfg_attr(feature = "svm-internal", qualifiers(pub))] +const MAX_LOADED_ACCOUNTS_DATA_SIZE_BYTES: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(64 * 1024 * 1024) }; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct ComputeBudgetLimits { - pub updated_heap_bytes: u32, - pub compute_unit_limit: u32, - pub compute_unit_price: u64, - pub loaded_accounts_bytes: NonZeroU32, +#[cfg_attr( + any(feature = "dev-context-only-utils", feature = "svm-internal"), + qualifiers(pub), + field_qualifiers( + updated_heap_bytes(pub), + compute_unit_limit(pub), + compute_unit_price(pub), + loaded_accounts_bytes(pub) + ) +)] +pub(crate) struct ComputeBudgetLimits { + pub(crate) updated_heap_bytes: u32, + pub(crate) compute_unit_limit: u32, + compute_unit_price: u64, + loaded_accounts_bytes: NonZeroU32, } impl Default for ComputeBudgetLimits { diff --git a/program-runtime/Cargo.toml b/program-runtime/Cargo.toml index 484921a50bf754..718604926af38a 100644 --- a/program-runtime/Cargo.toml +++ b/program-runtime/Cargo.toml @@ -22,7 +22,7 @@ rand = { workspace = true } serde = { workspace = true } solana-account = { workspace = true, features = ["bincode"] } solana-clock = { workspace = true } -solana-compute-budget = { workspace = true } +solana-compute-budget = { workspace = true, features = ["svm-internal"] } solana-epoch-rewards = { workspace = true } solana-epoch-schedule = { workspace = true } solana-feature-set = { workspace = true } diff --git a/programs/sbf/Cargo.lock b/programs/sbf/Cargo.lock index ae009c17048cdf..eb5d570d0c6b54 100644 --- a/programs/sbf/Cargo.lock +++ b/programs/sbf/Cargo.lock @@ -5512,6 +5512,7 @@ dependencies = [ name = "solana-compute-budget" version = "2.2.0" dependencies = [ + "qualifier_attr", "solana-fee-structure", "solana-program-entrypoint", ] diff --git a/svm/examples/Cargo.lock b/svm/examples/Cargo.lock index 494b481314e76b..9ee171899db7e7 100644 --- a/svm/examples/Cargo.lock +++ b/svm/examples/Cargo.lock @@ -5373,6 +5373,7 @@ dependencies = [ name = "solana-compute-budget" version = "2.2.0" dependencies = [ + "qualifier_attr", "solana-fee-structure", "solana-program-entrypoint", ]