@@ -28,12 +28,19 @@ use starknet_api::deprecated_contract_class::{
2828 EntryPointV0 ,
2929 Program as DeprecatedProgram ,
3030} ;
31+ use starknet_api:: execution_resources:: GasAmount ;
3132use starknet_types_core:: felt:: Felt ;
3233
3334use crate :: abi:: constants:: { self } ;
35+ use crate :: blockifier_versioned_constants:: VersionedConstants ;
36+ use crate :: bouncer:: vm_resources_to_sierra_gas;
3437use crate :: execution:: entry_point:: { EntryPointExecutionContext , EntryPointTypeAndSelector } ;
3538use 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" ) ]
3845use crate :: execution:: native:: contract_class:: NativeCompiledClassV1 ;
3946use 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.
0 commit comments