Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce public visibility of compute-budget APIs #4601

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compute-budget-instruction/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
1 change: 1 addition & 0 deletions compute-budget/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
158 changes: 107 additions & 51 deletions compute-budget/src/compute_budget.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -12,123 +12,177 @@ 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),
)
)]
#[non_exhaustive]
pub struct ComputeBudget {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we leave these fields pub please? LiteSVM lets people overwrite the ComputeBudget fields.

I'm open to being told these fields are quite unstable and we should limit to a subset, since I doubt many users care about overwriting poseidon_cost_coefficient_a etc

/// 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 {
Expand Down Expand Up @@ -218,7 +272,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<u64> {
#[cfg(feature = "svm-internal")]
#[cfg_attr(feature = "svm-internal", qualifiers(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
Expand Down
28 changes: 21 additions & 7 deletions compute-budget/src/compute_budget_limits.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,31 @@
#[cfg(any(feature = "dev-context-only-utils", feature = "svm-internal"))]
use qualifier_attr::qualifiers;
use {
solana_fee_structure::FeeBudgetLimits, solana_program_entrypoint::HEAP_LENGTH,
std::num::NonZeroU32,
};

/// 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;

Expand All @@ -21,7 +34,8 @@ 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)]
Expand Down
2 changes: 1 addition & 1 deletion program-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
2 changes: 1 addition & 1 deletion program-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ solana-banks-client = { workspace = true }
solana-banks-interface = { workspace = true }
solana-banks-server = { workspace = true }
solana-bpf-loader-program = { workspace = true }
solana-compute-budget = { workspace = true }
solana-compute-budget = { workspace = true, features = ["dev-context-only-utils"] }
solana-feature-set = { workspace = true }
solana-inline-spl = { workspace = true }
solana-instruction = { workspace = true }
Expand Down
7 changes: 3 additions & 4 deletions program-test/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -846,10 +846,9 @@ impl ProgramTest {
let bank = Bank::new_with_paths(
&genesis_config,
Arc::new(RuntimeConfig {
compute_budget: self.compute_max_units.map(|max_units| ComputeBudget {
compute_unit_limit: max_units,
..ComputeBudget::default()
}),
compute_budget: self
.compute_max_units
.map(|max_units| ComputeBudget::new(max_units)),
transaction_account_lock_limit: self.transaction_account_lock_limit,
..RuntimeConfig::default()
}),
Expand Down
1 change: 1 addition & 0 deletions programs/sbf/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ rand0-7 = { package = "rand", version = "0.7" }
rand_chacha = { workspace = true }
solana-accounts-db = { workspace = true, features = ["dev-context-only-utils"] }
solana-builtins = { workspace = true, features = ["dev-context-only-utils"] }
solana-compute-budget = { workspace = true, features = ["dev-context-only-utils"] }
solana-logger = { workspace = true }
# See order-crates-for-publishing.py for using this unusual `path = "."`
solana-runtime = { path = ".", features = ["dev-context-only-utils"] }
Expand Down
Loading
Loading