@@ -34,7 +34,11 @@ use starknet_types_core::felt::Felt;
3434use crate :: abi:: constants:: { self } ;
3535use crate :: execution:: entry_point:: { EntryPointExecutionContext , EntryPointTypeAndSelector } ;
3636use crate :: execution:: errors:: PreExecutionError ;
37- use crate :: execution:: execution_utils:: { poseidon_hash_many_cost, sn_api_to_cairo_vm_program} ;
37+ use crate :: execution:: execution_utils:: {
38+ cost_of_encode_felt252_data_and_calc_blake_hash,
39+ poseidon_hash_many_cost,
40+ sn_api_to_cairo_vm_program,
41+ } ;
3842#[ cfg( feature = "cairo_native" ) ]
3943use crate :: execution:: native:: contract_class:: NativeCompiledClassV1 ;
4044use crate :: transaction:: errors:: TransactionExecutionError ;
@@ -287,7 +291,7 @@ impl CompiledClassV1 {
287291 /// This is an empiric measurement of several bytecode lengths, which constitutes as the
288292 /// dominant factor in it.
289293 fn estimate_casm_hash_computation_resources ( & self ) -> ExecutionResources {
290- estimate_casm_hash_computation_resources ( & self . bytecode_segment_lengths )
294+ estimate_casm_poseidon_hash_computation_resources ( & self . bytecode_segment_lengths )
291295 }
292296
293297 /// Estimate the VM gas required to perform a CompiledClassHash migration,
@@ -321,7 +325,7 @@ impl CompiledClassV1 {
321325///
322326/// Note: the function focuses on the bytecode size, and currently ignores the cost handling the
323327/// class entry points.
324- pub fn estimate_casm_hash_computation_resources (
328+ pub fn estimate_casm_poseidon_hash_computation_resources (
325329 bytecode_segment_lengths : & NestedIntList ,
326330) -> ExecutionResources {
327331 // The constants in this function were computed by running the Casm code on a few values
@@ -361,6 +365,80 @@ pub fn estimate_casm_hash_computation_resources(
361365 }
362366}
363367
368+ /// Cost to hash a single flat segment of `len` felts.
369+ fn leaf_cost < F > ( len : usize , resources_to_gas_fn : F ) -> GasAmount
370+ where
371+ F : Fn ( & ExecutionResources ) -> GasAmount ,
372+ {
373+ // All `len` inputs treated as “big” felts; no small-felt optimization here.
374+ cost_of_encode_felt252_data_and_calc_blake_hash ( len, 0 , resources_to_gas_fn)
375+ }
376+
377+ /// Cost to hash a multi-segment contract:
378+ fn node_cost < F > ( segs : & [ NestedIntList ] , resources_to_gas_fn : F ) -> GasAmount
379+ where
380+ F : Fn ( & ExecutionResources ) -> GasAmount ,
381+ {
382+ // TODO(AvivG): Add base estimation for node.
383+ let mut gas = GasAmount :: ZERO ;
384+
385+ // TODO(AvivG): Add base estimation of each segment. Could this be part of 'leaf_cost'?
386+ let segment_overhead = GasAmount :: ZERO ;
387+
388+ // For each segment, hash its felts.
389+ for seg in segs {
390+ match seg {
391+ NestedIntList :: Leaf ( len) => {
392+ gas = gas. checked_add_panic_on_overflow ( segment_overhead) ;
393+ gas = gas. checked_add_panic_on_overflow ( leaf_cost ( * len, & resources_to_gas_fn) ) ;
394+ }
395+ _ => panic ! ( "Estimating hash cost only supports at most one level of segmentation." ) ,
396+ }
397+ }
398+
399+ // Node‐level hash over (hash1, len1, hash2, len2, …): one segment hash (“big” felt))
400+ // and one segment length (“small” felt) per segment.
401+ let node_hash_cost = cost_of_encode_felt252_data_and_calc_blake_hash (
402+ segs. len ( ) ,
403+ segs. len ( ) ,
404+ resources_to_gas_fn,
405+ ) ;
406+
407+ gas. checked_add_panic_on_overflow ( node_hash_cost)
408+ }
409+
410+ /// Estimates the VM resources to compute the CASM Blake hash for a Cairo-1 contract:
411+ /// - Uses only bytecode size (treats all felts as “big”, ignores the small-felt optimization).
412+ pub fn estimate_casm_blake_hash_computation_resources < F > (
413+ bytecode_segment_lengths : & NestedIntList ,
414+ resources_to_gas_fn : F ,
415+ ) -> GasAmount
416+ where
417+ F : Fn ( & ExecutionResources ) -> GasAmount ,
418+ {
419+ // TODO(AvivG): Currently ignores entry-point hashing costs.
420+ // TODO(AvivG): Missing base overhead estimation for compiled_class_hash.
421+
422+ // Basic frame overhead.
423+ // TODO(AvivG): Once compiled_class_hash estimation is complete,
424+ // revisit whether this should be moved into cost_of_encode_felt252_data_and_calc_blake_hash.
425+ let resources = ExecutionResources {
426+ n_steps : 0 ,
427+ n_memory_holes : 0 ,
428+ builtin_instance_counter : HashMap :: from ( [ ( BuiltinName :: range_check, 3 ) ] ) ,
429+ } ;
430+ let gas = resources_to_gas_fn ( & resources) ;
431+
432+ // Add leaf vs node cost
433+ let added_gas = match bytecode_segment_lengths {
434+ // Single-segment contract (e.g., older Sierra contracts).
435+ NestedIntList :: Leaf ( len) => leaf_cost ( * len, & resources_to_gas_fn) ,
436+ NestedIntList :: Node ( segs) => node_cost ( segs, resources_to_gas_fn) ,
437+ } ;
438+
439+ gas. checked_add_panic_on_overflow ( added_gas)
440+ }
441+
364442// Returns the set of segments that were visited according to the given visited PCs and segment
365443// lengths.
366444// Each visited segment must have its starting PC visited, and is represented by it.
0 commit comments