@@ -31,12 +31,19 @@ use starknet_api::deprecated_contract_class::{
3131use starknet_types_core:: felt:: Felt ;
3232
3333use crate :: abi:: constants:: { self } ;
34+ use crate :: blockifier_versioned_constants:: VersionedConstants ;
35+ use crate :: bouncer:: vm_resources_to_sierra_gas;
3436use crate :: execution:: entry_point:: { EntryPointExecutionContext , EntryPointTypeAndSelector } ;
3537use crate :: execution:: errors:: PreExecutionError ;
36- use crate :: execution:: execution_utils:: { poseidon_hash_many_cost, sn_api_to_cairo_vm_program} ;
38+ use crate :: execution:: execution_utils:: {
39+ cost_of_encode_felt252_data_and_calc_blake_hash,
40+ poseidon_hash_many_cost,
41+ sn_api_to_cairo_vm_program,
42+ } ;
3743#[ cfg( feature = "cairo_native" ) ]
3844use crate :: execution:: native:: contract_class:: NativeCompiledClassV1 ;
3945use crate :: transaction:: errors:: TransactionExecutionError ;
46+ use crate :: utils:: safe_add_gas_panic_on_overflow;
4047
4148#[ cfg( test) ]
4249#[ path = "contract_class_test.rs" ]
@@ -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,68 @@ 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 gas = 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+ gas = safe_add_gas_panic_on_overflow ( gas, segment_overhead) ;
369+ gas = safe_add_gas_panic_on_overflow ( gas, 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+ let node_hash_cost = cost_of_encode_felt252_data_and_calc_blake_hash (
377+ segs. len ( ) ,
378+ segs. len ( ) ,
379+ versioned_constants,
380+ ) ;
381+
382+ safe_add_gas_panic_on_overflow ( gas, node_hash_cost)
383+ }
384+
385+ /// Estimates the VM resources to compute the CASM Blake hash for a Cairo-1 contract:
386+ /// - Uses only bytecode size (treats all felts as “big”, ignores the small-felt optimization).
387+ pub fn estimate_casm_blake_hash_computation_resources (
388+ bytecode_segment_lengths : & NestedIntList ,
389+ versioned_constants : & VersionedConstants ,
390+ ) -> GasAmount {
391+ // TODO(AvivG): Currently ignores entry-point costs.
392+ // Basic frame overhead
393+ let resources = ExecutionResources {
394+ n_steps : 0 ,
395+ n_memory_holes : 0 ,
396+ builtin_instance_counter : HashMap :: from ( [ ( BuiltinName :: range_check, 3 ) ] ) ,
397+ } ;
398+ let gas = vm_resources_to_sierra_gas ( resources, versioned_constants) ;
399+
400+ // Add leaf vs node cost
401+ match bytecode_segment_lengths {
402+ // Single-segment contract (e.g., older Sierra contracts).
403+ NestedIntList :: Leaf ( len) => {
404+ safe_add_gas_panic_on_overflow ( gas, leaf_cost ( * len, versioned_constants) )
405+ }
406+ NestedIntList :: Node ( segs) => {
407+ safe_add_gas_panic_on_overflow ( gas, node_cost ( segs, versioned_constants) )
408+ }
409+ }
410+ }
411+
343412// Returns the set of segments that were visited according to the given visited PCs and segment
344413// lengths.
345414// Each visited segment must have its starting PC visited, and is represented by it.
0 commit comments