diff --git a/compute-budget/src/compute_budget.rs b/compute-budget/src/compute_budget.rs index da04296a7e3080..5539e812645349 100644 --- a/compute-budget/src/compute_budget.rs +++ b/compute-budget/src/compute_budget.rs @@ -103,8 +103,12 @@ pub struct ComputeBudget { /// + 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, - /// Big integer modular exponentiation cost - pub big_modular_exponentiation_cost: u64, + /// Big integer modular exponentiation base cost + pub 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, /// Coefficient `a` of the quadratic function which determines the number /// of compute units consumed to call poseidon syscall for a given number /// of inputs. @@ -180,7 +184,8 @@ impl ComputeBudget { 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_cost: 33, + 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, diff --git a/programs/bpf_loader/src/syscalls/mod.rs b/programs/bpf_loader/src/syscalls/mod.rs index 47105457372988..7661a000da2938 100644 --- a/programs/bpf_loader/src/syscalls/mod.rs +++ b/programs/bpf_loader/src/syscalls/mod.rs @@ -1710,13 +1710,15 @@ declare_builtin_function!( let input_len: u64 = std::cmp::max(input_len, params.modulus_len); let budget = invoke_context.get_compute_budget(); + // the compute units are calculated by the quadratic equation `0.5 input_len^2 + 190` consume_compute_meter( invoke_context, budget.syscall_base_cost.saturating_add( input_len .saturating_mul(input_len) - .checked_div(budget.big_modular_exponentiation_cost) - .unwrap_or(u64::MAX), + .checked_div(budget.big_modular_exponentiation_cost_divisor) + .unwrap_or(u64::MAX) + .saturating_add(budget.big_modular_exponentiation_base_cost), ), )?; @@ -4719,7 +4721,8 @@ mod tests { let budget = invoke_context.get_compute_budget(); invoke_context.mock_set_remaining( budget.syscall_base_cost - + (MAX_LEN * MAX_LEN) / budget.big_modular_exponentiation_cost, + + (MAX_LEN * MAX_LEN) / budget.big_modular_exponentiation_cost_divisor + + budget.big_modular_exponentiation_base_cost, ); let result = SyscallBigModExp::rust( @@ -4760,7 +4763,8 @@ mod tests { let budget = invoke_context.get_compute_budget(); invoke_context.mock_set_remaining( budget.syscall_base_cost - + (INV_LEN * INV_LEN) / budget.big_modular_exponentiation_cost, + + (INV_LEN * INV_LEN) / budget.big_modular_exponentiation_cost_divisor + + budget.big_modular_exponentiation_base_cost, ); let result = SyscallBigModExp::rust(