Skip to content

Commit f48ced9

Browse files
chore(blockifier): add test_proving_gas_minus_sierra_gas_equals_builtin_gas
1 parent 656da0b commit f48ced9

File tree

1 file changed

+129
-1
lines changed

1 file changed

+129
-1
lines changed

crates/blockifier/src/bouncer_test.rs

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,17 @@ use std::collections::{HashMap, HashSet};
22

33
use assert_matches::assert_matches;
44
use cairo_vm::types::builtin_name::BuiltinName;
5+
use cairo_vm::vm::runners::cairo_runner::ExecutionResources;
56
use rstest::rstest;
7+
use starknet_api::core::ClassHash;
68
use starknet_api::execution_resources::GasAmount;
79
use starknet_api::transaction::fields::Fee;
810
use starknet_api::{class_hash, contract_address, storage_key};
911

1012
use super::BouncerConfig;
1113
use crate::blockifier::transaction_executor::TransactionExecutorError;
1214
use crate::bouncer::{
15+
get_tx_weights,
1316
verify_tx_weights_within_max_capacity,
1417
Bouncer,
1518
BouncerWeights,
@@ -18,9 +21,12 @@ use crate::bouncer::{
1821
use crate::context::BlockContext;
1922
use crate::execution::call_info::ExecutionSummary;
2023
use crate::fee::resources::{ComputationResources, TransactionResources};
21-
use crate::state::cached_state::{StateChangesKeys, TransactionalState};
24+
use crate::state::cached_state::{StateChangesKeys, StateMaps, TransactionalState};
25+
use crate::test_utils::contracts::FeatureContract;
2226
use crate::test_utils::initial_test_state::test_state;
27+
use crate::test_utils::{CairoVersion, RunnableCairo1};
2328
use crate::transaction::errors::TransactionExecutionError;
29+
use crate::utils::{add_maps, u64_from_usize};
2430

2531
#[test]
2632
fn test_block_weights_has_room() {
@@ -239,3 +245,125 @@ fn test_transaction_too_large_sierra_gas_based() {
239245
)
240246
) if *max_capacity == bouncer_config.block_max_capacity && *tx_size == expected_weights);
241247
}
248+
249+
/// Verifies that the difference between proving gas and Sierra gas
250+
/// is fully accounted for by the builtin gas delta (Stone vs Stwo).
251+
///
252+
/// Covers combinations of OS computation builtins and CASM hash computation builtins.
253+
#[rstest]
254+
#[case::tx_builtins_only(&[], ExecutionResources::default())]
255+
#[case::tx_builtins_plus_os_builtins(
256+
&[],
257+
ExecutionResources {
258+
builtin_instance_counter: HashMap::from([
259+
(BuiltinName::bitwise, 1),
260+
]),
261+
..Default::default()
262+
},
263+
)]
264+
#[case::tx_builtins_plus_casm_hash_computation(
265+
&[
266+
(FeatureContract::TestContract(CairoVersion::Cairo0), 1),
267+
(FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), 1),
268+
],
269+
ExecutionResources::default(),
270+
)]
271+
#[case::tx_builtins_plus_os_builtins_plus_casm_hash_computation(
272+
&[
273+
(FeatureContract::TestContract(CairoVersion::Cairo0), 1),
274+
(FeatureContract::TestContract(CairoVersion::Cairo1(RunnableCairo1::Casm)), 1),
275+
],
276+
ExecutionResources {
277+
builtin_instance_counter: HashMap::from([
278+
(BuiltinName::range_check, 1),
279+
(BuiltinName::bitwise, 2),
280+
]),
281+
..Default::default()
282+
},
283+
)]
284+
fn test_proving_gas_minus_sierra_gas_equals_builtin_gas(
285+
#[case] contract_instances: &[(FeatureContract, u16)],
286+
#[case] os_vm_resources: ExecutionResources,
287+
) {
288+
let block_context = BlockContext::create_for_account_testing();
289+
let state = test_state(&block_context.chain_info, Fee(0), contract_instances);
290+
291+
// Derive executed_class_hashes from contract_instances
292+
let executed_class_hashes: HashSet<ClassHash> =
293+
contract_instances.iter().map(|(contract, _)| contract.get_class_hash()).collect();
294+
295+
// Create CASM hash computation builtins only in case CASM computation aren't trivial.
296+
let casm_hash_computation_builtins = if contract_instances.is_empty() {
297+
HashMap::new()
298+
} else {
299+
HashMap::from([(BuiltinName::poseidon, 11699), (BuiltinName::pedersen, 2205)])
300+
};
301+
302+
// Transaction builtin counters.
303+
let mut tx_builtin_counters =
304+
HashMap::from([(BuiltinName::range_check, 2), (BuiltinName::pedersen, 1)]);
305+
306+
let tx_resources = TransactionResources {
307+
computation: ComputationResources {
308+
sierra_gas: GasAmount::ZERO,
309+
tx_vm_resources: ExecutionResources {
310+
builtin_instance_counter: tx_builtin_counters.clone(),
311+
..Default::default()
312+
},
313+
os_vm_resources: os_vm_resources.clone(),
314+
..Default::default()
315+
},
316+
..Default::default()
317+
};
318+
// The os additional resources contains both patricia updates and
319+
// CASM hash computation.
320+
let n_visited_storage_entries = if casm_hash_computation_builtins.is_empty() { 0 } else { 1 };
321+
322+
let result = get_tx_weights(
323+
&state,
324+
&executed_class_hashes,
325+
n_visited_storage_entries,
326+
&tx_resources,
327+
&StateMaps::default().keys(), // state changes keys
328+
&block_context.versioned_constants,
329+
&tx_builtin_counters,
330+
&block_context.bouncer_config.builtin_weights,
331+
)
332+
.unwrap();
333+
334+
// Combine TX + TX overhead (OS) + CASM and patricia builtin usage.
335+
add_maps(&mut tx_builtin_counters, &os_vm_resources.builtin_instance_counter);
336+
add_maps(&mut tx_builtin_counters, &casm_hash_computation_builtins);
337+
338+
// Compute expected gas delta from builtin delta (Stwo - Stone).
339+
let expected_builtin_gas_delta = tx_builtin_counters
340+
.iter()
341+
.map(|(name, count)| {
342+
let stwo_gas = block_context.bouncer_config.builtin_weights.builtin_weight(name);
343+
let stone_gas = block_context
344+
.versioned_constants
345+
.os_constants
346+
.gas_costs
347+
.builtins
348+
.get_builtin_gas_cost(name)
349+
.unwrap();
350+
351+
let stwo_total = stwo_gas.checked_mul(*count).map(u64_from_usize).expect("overflow");
352+
let stone_total = u64_from_usize(*count).checked_mul(stone_gas).expect("overflow");
353+
354+
// This assumes that the Stone gas is always less than or equal to Stwo gas.
355+
stwo_total.checked_sub(stone_total).expect("underflow")
356+
})
357+
// Sum the deltas.
358+
.try_fold(0u64, |acc, val| acc.checked_add(val))
359+
.expect("overflow in sum");
360+
361+
assert_eq!(
362+
result.proving_gas.0 - result.sierra_gas.0,
363+
expected_builtin_gas_delta,
364+
"Proving gas: {} - Sierra gas: {} ≠ builtins gap: {}",
365+
result.proving_gas.0,
366+
result.sierra_gas.0,
367+
expected_builtin_gas_delta
368+
);
369+
}

0 commit comments

Comments
 (0)