Skip to content
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
1 change: 1 addition & 0 deletions crates/blockifier/src/blockifier_versioned_constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -947,6 +947,7 @@ pub struct BuiltinGasCosts {
}

impl BuiltinGasCosts {
// TODO(AvivG): Make this function private and use get_cairo_primitive_gas_cost instead.
pub fn get_builtin_gas_cost(&self, builtin: &BuiltinName) -> Result<u64, GasCostsError> {
let gas_cost = match *builtin {
BuiltinName::range_check => self.range_check,
Expand Down
66 changes: 41 additions & 25 deletions crates/blockifier/src/bouncer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use crate::blockifier::transaction_executor::{
};
use crate::blockifier_versioned_constants::{BuiltinGasCosts, VersionedConstants};
use crate::execution::call_info::{
cairo_primitive_counter_map,
BuiltinCounterMap,
CairoPrimitiveCounterMap,
CairoPrimitiveName,
Expand Down Expand Up @@ -688,11 +689,15 @@ fn proving_gas_from_builtins_and_sierra_gas(
proving_builtin_gas_costs: &BuiltinGasCosts,
sierra_builtin_gas_costs: &BuiltinGasCosts,
) -> GasAmount {
let builtins_proving_gas = builtins_to_gas(builtin_counters, proving_builtin_gas_costs);
// TODO(AvivG): To support opcodes in the computation, pass cairo_primitive_counter_map to this
// function
let cairo_primitives_counters = cairo_primitive_counter_map(builtin_counters.clone());
let cairo_primitives_proving_gas =
cairo_primitives_to_gas(&cairo_primitives_counters, proving_builtin_gas_costs);
let steps_proving_gas =
sierra_gas_to_steps_gas(sierra_gas, builtin_counters, sierra_builtin_gas_costs);
sierra_gas_to_steps_gas(sierra_gas, &cairo_primitives_counters, sierra_builtin_gas_costs);

steps_proving_gas.checked_add_panic_on_overflow(builtins_proving_gas)
steps_proving_gas.checked_add_panic_on_overflow(cairo_primitives_proving_gas)
}

/// Generic function to convert VM resources to gas with configurable builtin gas calculation
Expand All @@ -701,7 +706,11 @@ pub fn vm_resources_to_gas(
builtin_gas_cost: &BuiltinGasCosts,
versioned_constants: &VersionedConstants,
) -> GasAmount {
let builtins_gas_cost = builtins_to_gas(&resources.prover_builtins(), builtin_gas_cost);
// TODO(AvivG): To support opcodes in the computation, resources should include opcode counters.
let builtins_gas_cost = cairo_primitives_to_gas(
&cairo_primitive_counter_map(resources.prover_builtins()),
builtin_gas_cost,
);
let n_steps_gas_cost = n_steps_to_gas(resources.total_n_steps(), versioned_constants);
let n_memory_holes_gas_cost =
memory_holes_to_gas(resources.n_memory_holes, versioned_constants);
Expand All @@ -714,38 +723,45 @@ pub fn vm_resources_to_gas(
/// Computes the steps gas by subtracting the builtins' contribution from the Sierra gas.
pub fn sierra_gas_to_steps_gas(
sierra_gas: GasAmount,
builtin_counters: &BuiltinCounterMap,
cairo_primitives_counters: &CairoPrimitiveCounterMap,
sierra_builtin_gas_costs: &BuiltinGasCosts,
) -> GasAmount {
let builtins_gas_cost = builtins_to_gas(builtin_counters, sierra_builtin_gas_costs);
let cairo_primitives_gas =
cairo_primitives_to_gas(cairo_primitives_counters, sierra_builtin_gas_costs);

sierra_gas.checked_sub(builtins_gas_cost).unwrap_or_else(|| {
sierra_gas.checked_sub(cairo_primitives_gas).unwrap_or_else(|| {
log::debug!(
"Sierra gas underflow: builtins gas exceeds total. Sierra gas: {sierra_gas:?}, \
Builtins gas: {builtins_gas_cost:?}, Builtins: {builtin_counters:?}"
"Sierra gas underflow: cairo primitives gas exceeds total. Sierra gas: \
{sierra_gas:?}, Cairo primitives gas: {cairo_primitives_gas:?}, Cairo primitives: \
{cairo_primitives_counters:?}"
);
GasAmount::ZERO
})
}

pub fn builtins_to_gas(
builtin_counters: &BuiltinCounterMap,
builtin_gas_costs: &BuiltinGasCosts,
pub fn cairo_primitives_to_gas(
cairo_primitives_counters: &CairoPrimitiveCounterMap,
// NOTE: 'blake' is currently the only supported opcode, by being included in the
// builtin_gas_costs.
cairo_primitives_gas_costs: &BuiltinGasCosts,
) -> GasAmount {
let builtin_gas = builtin_counters.iter().fold(0u64, |accumulated_gas, (name, &count)| {
let builtin_weight = builtin_gas_costs.get_builtin_gas_cost(name).unwrap();
builtin_weight
.checked_mul(u64_from_usize(count))
.and_then(|builtin_gas| accumulated_gas.checked_add(builtin_gas))
.unwrap_or_else(|| {
panic!(
"Overflow while converting builtin counters to gas.\nBuiltin: {name}, Weight: \
{builtin_weight}, Count: {count}, Accumulated gas: {accumulated_gas}"
)
})
});
let cairo_primitives_gas =
cairo_primitives_counters.iter().fold(0u64, |accumulated_gas, (name, &count)| {
let cairo_primitive_weight =
cairo_primitives_gas_costs.get_cairo_primitive_gas_cost(name).unwrap();
cairo_primitive_weight
.checked_mul(u64_from_usize(count))
.and_then(|builtin_gas| accumulated_gas.checked_add(builtin_gas))
.unwrap_or_else(|| {
panic!(
"Overflow while converting cairo primitives counters to gas.\nCairo \
primitive: {name:?}, Weight: {cairo_primitive_weight}, Count: {count}, \
Accumulated gas: {accumulated_gas}"
)
})
});

GasAmount(builtin_gas)
GasAmount(cairo_primitives_gas)
}

fn add_casm_hash_computation_gas_cost(
Expand Down
8 changes: 4 additions & 4 deletions crates/blockifier/src/bouncer_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use starknet_api::{class_hash, contract_address, felt, storage_key};
use super::BouncerConfig;
use crate::blockifier::transaction_executor::TransactionExecutorError;
use crate::bouncer::{
builtins_to_gas,
cairo_primitives_to_gas,
get_patricia_update_resources,
get_tx_weights,
map_class_hash_to_casm_hash_computation_resources,
Expand Down Expand Up @@ -282,12 +282,12 @@ fn test_bouncer_try_update_gas_based(#[case] scenario: &'static str, block_conte

let range_check_count = 2;
let max_capacity_builtin_counters =
BTreeMap::from([(BuiltinName::range_check, range_check_count)]);
cairo_primitive_counter_map([(BuiltinName::range_check, range_check_count)]);
let builtin_counters = match scenario {
"proving_gas_block_full" => max_capacity_builtin_counters.clone(),
// Use a minimal or empty map.
"ok" | "sierra_gas_block_full" => {
BTreeMap::from([(BuiltinName::range_check, range_check_count - 1)])
cairo_primitive_counter_map([(BuiltinName::range_check, range_check_count - 1)])
}
_ => panic!("Unexpected scenario: {scenario}"),
};
Expand All @@ -300,7 +300,7 @@ fn test_bouncer_try_update_gas_based(#[case] scenario: &'static str, block_conte
};

let proving_gas_max_capacity =
builtins_to_gas(&max_capacity_builtin_counters, &builtin_weights.gas_costs);
cairo_primitives_to_gas(&max_capacity_builtin_counters, &builtin_weights.gas_costs);

let block_max_capacity = BouncerWeights {
l1_gas: 20,
Expand Down
Loading