@@ -32,12 +32,19 @@ use starknet_api::execution_resources::GasAmount;
3232use starknet_types_core:: felt:: Felt ;
3333
3434use crate :: abi:: constants:: { self } ;
35+ use crate :: blockifier_versioned_constants:: VersionedConstants ;
36+ use crate :: bouncer:: vm_resources_to_sierra_gas;
3537use crate :: execution:: entry_point:: { EntryPointExecutionContext , EntryPointTypeAndSelector } ;
3638use crate :: execution:: errors:: PreExecutionError ;
37- 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+ } ;
3844#[ cfg( feature = "cairo_native" ) ]
3945use crate :: execution:: native:: contract_class:: NativeCompiledClassV1 ;
4046use crate :: transaction:: errors:: TransactionExecutionError ;
47+ use crate :: utils:: safe_add_gas_panic_on_overflow;
4148
4249#[ cfg( test) ]
4350#[ path = "contract_class_test.rs" ]
@@ -288,7 +295,7 @@ impl CompiledClassV1 {
288295 /// This is an empiric measurement of several bytecode lengths, which constitutes as the
289296 /// dominant factor in it.
290297 fn estimate_casm_hash_computation_resources ( & self ) -> ExecutionResources {
291- estimate_casm_hash_computation_resources ( & self . bytecode_segment_lengths )
298+ estimate_casm_poseidon_hash_computation_resources ( & self . bytecode_segment_lengths )
292299 }
293300
294301 /// Estimate the VM gas required to perform a CompiledClassHash migration,
@@ -323,7 +330,7 @@ impl CompiledClassV1 {
323330///
324331/// Note: the function focuses on the bytecode size, and currently ignores the cost handling the
325332/// class entry points.
326- pub fn estimate_casm_hash_computation_resources (
333+ pub fn estimate_casm_poseidon_hash_computation_resources (
327334 bytecode_segment_lengths : & NestedIntList ,
328335) -> ExecutionResources {
329336 // The constants in this function were computed by running the Casm code on a few values
@@ -363,6 +370,68 @@ pub fn estimate_casm_hash_computation_resources(
363370 }
364371}
365372
373+ /// Cost to hash a single flat segment of `len` felts.
374+ fn leaf_cost ( len : usize , versioned_constants : & VersionedConstants ) -> GasAmount {
375+ // All `len` inputs treated as “big” felts; no small-felt optimization here.
376+ cost_of_encode_felt252_data_and_calc_blake_hash ( len, 0 , versioned_constants)
377+ }
378+
379+ /// Cost to hash a multi-segment contract:
380+ fn node_cost ( segs : & [ NestedIntList ] , versioned_constants : & VersionedConstants ) -> GasAmount {
381+ // TODO(AvivG): Add base estimation for node.
382+ let mut gas = GasAmount :: ZERO ;
383+
384+ // TODO(AvivG): Add base estimation of each segment. Could this be part of 'leaf_cost'?
385+ let segment_overhead = GasAmount :: ZERO ;
386+
387+ // 2) For each segment, hash its felts.
388+ for seg in segs {
389+ match seg {
390+ NestedIntList :: Leaf ( len) => {
391+ gas = safe_add_gas_panic_on_overflow ( gas, segment_overhead) ;
392+ gas = safe_add_gas_panic_on_overflow ( gas, leaf_cost ( * len, versioned_constants) ) ;
393+ }
394+ _ => panic ! ( "Estimating hash cost only supports at most one level of segmentation." ) ,
395+ }
396+ }
397+ // Node‐level hash over (hash1, len1, hash2, len2, …): one segment hash (“big” felt))
398+ // and one segment length (“small” felt) per segment.
399+ let node_hash_cost = cost_of_encode_felt252_data_and_calc_blake_hash (
400+ segs. len ( ) ,
401+ segs. len ( ) ,
402+ versioned_constants,
403+ ) ;
404+
405+ safe_add_gas_panic_on_overflow ( gas, node_hash_cost)
406+ }
407+
408+ /// Estimates the VM resources to compute the CASM Blake hash for a Cairo-1 contract:
409+ /// - Uses only bytecode size (treats all felts as “big”, ignores the small-felt optimization).
410+ pub fn estimate_casm_blake_hash_computation_resources (
411+ bytecode_segment_lengths : & NestedIntList ,
412+ versioned_constants : & VersionedConstants ,
413+ ) -> GasAmount {
414+ // TODO(AvivG): Currently ignores entry-point costs.
415+ // Basic frame overhead
416+ let resources = ExecutionResources {
417+ n_steps : 0 ,
418+ n_memory_holes : 0 ,
419+ builtin_instance_counter : HashMap :: from ( [ ( BuiltinName :: range_check, 3 ) ] ) ,
420+ } ;
421+ let gas = vm_resources_to_sierra_gas ( resources, versioned_constants) ;
422+
423+ // Add leaf vs node cost
424+ match bytecode_segment_lengths {
425+ // Single-segment contract (e.g., older Sierra contracts).
426+ NestedIntList :: Leaf ( len) => {
427+ safe_add_gas_panic_on_overflow ( gas, leaf_cost ( * len, versioned_constants) )
428+ }
429+ NestedIntList :: Node ( segs) => {
430+ safe_add_gas_panic_on_overflow ( gas, node_cost ( segs, versioned_constants) )
431+ }
432+ }
433+ }
434+
366435// Returns the set of segments that were visited according to the given visited PCs and segment
367436// lengths.
368437// Each visited segment must have its starting PC visited, and is represented by it.
0 commit comments