Skip to content

Commit 1d6deef

Browse files
feat(blockifier): add estimate_casm_blake_hash_computation_resources
1 parent 1634654 commit 1d6deef

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

crates/blockifier/src/execution/contract_class.rs

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,19 @@ use starknet_api::deprecated_contract_class::{
2828
EntryPointV0,
2929
Program as DeprecatedProgram,
3030
};
31+
use starknet_api::execution_resources::GasAmount;
3132
use starknet_types_core::felt::Felt;
3233

3334
use crate::abi::constants::{self};
35+
use crate::blockifier_versioned_constants::VersionedConstants;
36+
use crate::bouncer::vm_resources_to_sierra_gas;
3437
use crate::execution::entry_point::{EntryPointExecutionContext, EntryPointTypeAndSelector};
3538
use crate::execution::errors::PreExecutionError;
36-
use crate::execution::execution_utils::{poseidon_hash_many_cost, sn_api_to_cairo_vm_program};
39+
use crate::execution::execution_utils::{
40+
cost_of_encode_felt252_data_and_calc_blake_hash,
41+
poseidon_hash_many_cost,
42+
sn_api_to_cairo_vm_program,
43+
};
3744
#[cfg(feature = "cairo_native")]
3845
use crate::execution::native::contract_class::NativeCompiledClassV1;
3946
use crate::transaction::errors::TransactionExecutionError;
@@ -272,7 +279,7 @@ impl CompiledClassV1 {
272279
/// This is an empiric measurement of several bytecode lengths, which constitutes as the
273280
/// dominant factor in it.
274281
fn estimate_casm_hash_computation_resources(&self) -> ExecutionResources {
275-
estimate_casm_hash_computation_resources(&self.bytecode_segment_lengths)
282+
estimate_casm_poseidon_hash_computation_resources(&self.bytecode_segment_lengths)
276283
}
277284

278285
// Returns the set of segments that were visited according to the given visited PCs.
@@ -300,7 +307,7 @@ impl CompiledClassV1 {
300307
///
301308
/// Note: the function focuses on the bytecode size, and currently ignores the cost handling the
302309
/// class entry points.
303-
pub fn estimate_casm_hash_computation_resources(
310+
pub fn estimate_casm_poseidon_hash_computation_resources(
304311
bytecode_segment_lengths: &NestedIntList,
305312
) -> ExecutionResources {
306313
// The constants in this function were computed by running the Casm code on a few values
@@ -340,6 +347,65 @@ pub fn estimate_casm_hash_computation_resources(
340347
}
341348
}
342349

350+
/// Cost to hash a single flat segment of `len` felts.
351+
fn leaf_cost(len: usize, versioned_constants: &VersionedConstants) -> GasAmount {
352+
// All `len` inputs treated as “big” felts; no small-felt optimization here.
353+
cost_of_encode_felt252_data_and_calc_blake_hash(len, 0, versioned_constants)
354+
}
355+
356+
/// Cost to hash a multi-segment contract:
357+
fn node_cost(segs: &[NestedIntList], versioned_constants: &VersionedConstants) -> GasAmount {
358+
// TODO(AvivG): Add base estimation for node.
359+
let mut resources = GasAmount::ZERO;
360+
361+
// TODO(AvivG): Add base estimation of each segment. Could this be part of 'leaf_cost'?
362+
let segment_overhead = GasAmount::ZERO;
363+
364+
// 2) For each segment, hash its felts.
365+
for seg in segs {
366+
match seg {
367+
NestedIntList::Leaf(len) => {
368+
resources += segment_overhead;
369+
resources += leaf_cost(*len, versioned_constants);
370+
}
371+
_ => panic!("Estimating hash cost only supports at most one level of segmentation."),
372+
}
373+
}
374+
// Node‐level hash over (hash1, len1, hash2, len2, …): one segment hash (“big” felt))
375+
// and one segment length (“small” felt) per segment.
376+
resources += cost_of_encode_felt252_data_and_calc_blake_hash(
377+
segs.len(),
378+
segs.len(),
379+
versioned_constants,
380+
);
381+
382+
resources
383+
}
384+
385+
/// Estimates the VM resources to compute the CASM Blake hash for a Cairo-1 contract:
386+
/// - TODO(AvivG): Currently ignores entry-point costs.
387+
/// - Uses only bytecode size (treats all felts as “big”, ignores the small-felt optimization).
388+
/// - This estimation was done by...
389+
pub fn estimate_casm_blake_hash_computation_resources(
390+
bytecode_segment_lengths: &NestedIntList,
391+
versioned_constants: &VersionedConstants,
392+
) -> GasAmount {
393+
// Basic frame overhead
394+
let resources = ExecutionResources {
395+
n_steps: 0,
396+
n_memory_holes: 0,
397+
builtin_instance_counter: HashMap::from([(BuiltinName::range_check, 3)]),
398+
};
399+
let gas = vm_resources_to_sierra_gas(resources, versioned_constants);
400+
401+
// Add leaf vs node cost
402+
match bytecode_segment_lengths {
403+
// Single-segment contract (e.g., older Sierra contracts).
404+
NestedIntList::Leaf(len) => gas + leaf_cost(*len, versioned_constants),
405+
NestedIntList::Node(segs) => gas + node_cost(segs, versioned_constants),
406+
}
407+
}
408+
343409
// Returns the set of segments that were visited according to the given visited PCs and segment
344410
// lengths.
345411
// Each visited segment must have its starting PC visited, and is represented by it.

crates/native_blockifier/src/py_testing_wrappers.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use blockifier::execution::contract_class::estimate_casm_hash_computation_resources;
1+
use blockifier::execution::contract_class::estimate_casm_poseidon_hash_computation_resources;
22
use blockifier::transaction::errors::{TransactionExecutionError, TransactionFeeError};
33
use cairo_lang_starknet_classes::NestedIntList;
44
use pyo3::{pyfunction, PyResult};
@@ -22,7 +22,7 @@ pub fn estimate_casm_hash_computation_resources_for_testing_single(
2222
bytecode_segment_lengths: usize,
2323
) -> PyResult<PyExecutionResources> {
2424
let node = NestedIntList::Leaf(bytecode_segment_lengths);
25-
Ok(estimate_casm_hash_computation_resources(&node).into())
25+
Ok(estimate_casm_poseidon_hash_computation_resources(&node).into())
2626
}
2727

2828
/// Wrapper for [estimate_casm_hash_computation_resources] that can be used for testing.
@@ -34,5 +34,5 @@ pub fn estimate_casm_hash_computation_resources_for_testing_list(
3434
let node = NestedIntList::Node(
3535
bytecode_segment_lengths.into_iter().map(NestedIntList::Leaf).collect(),
3636
);
37-
Ok(estimate_casm_hash_computation_resources(&node).into())
37+
Ok(estimate_casm_poseidon_hash_computation_resources(&node).into())
3838
}

0 commit comments

Comments
 (0)