@@ -18,9 +18,12 @@ use cairo_vm::vm::vm_core::VirtualMachine;
1818use num_bigint:: BigUint ;
1919use starknet_api:: core:: ClassHash ;
2020use starknet_api:: deprecated_contract_class:: Program as DeprecatedProgram ;
21+ use starknet_api:: execution_resources:: GasAmount ;
2122use starknet_api:: transaction:: fields:: Calldata ;
2223use starknet_types_core:: felt:: Felt ;
2324
25+ use crate :: blockifier_versioned_constants:: VersionedConstants ;
26+ use crate :: bouncer:: vm_resources_to_sierra_gas;
2427use crate :: execution:: call_info:: { CallExecution , CallInfo , Retdata } ;
2528use crate :: execution:: contract_class:: { RunnableCompiledClass , TrackedResource } ;
2629use crate :: execution:: entry_point:: {
@@ -44,6 +47,7 @@ use crate::execution::syscalls::hint_processor::{ENTRYPOINT_NOT_FOUND_ERROR, OUT
4447use crate :: execution:: { deprecated_entry_point_execution, entry_point_execution} ;
4548use crate :: state:: errors:: StateError ;
4649use crate :: state:: state_api:: State ;
50+ use crate :: utils:: { safe_add_gas_panic_on_overflow, u64_from_usize} ;
4751
4852pub type Args = Vec < CairoArg > ;
4953
@@ -363,3 +367,68 @@ pub fn poseidon_hash_many_cost(data_length: usize) -> ExecutionResources {
363367 builtin_instance_counter : HashMap :: from ( [ ( BuiltinName :: poseidon, data_length / 2 + 1 ) ] ) ,
364368 }
365369}
370+
371+ mod blake_cost {
372+ // U-32 counts
373+ pub const N_U32S_MESSAGE : usize = 16 ;
374+ pub const N_U32S_BIG_FELT : usize = 8 ;
375+ pub const N_U32S_SMALL_FELT : usize = 2 ;
376+
377+ // Steps counts
378+ pub const STEPS_BIG_FELT : usize = 45 ;
379+ pub const STEPS_SMALL_FELT : usize = 15 ;
380+
381+ // One-time segment setup cost (full vs partial)
382+ pub const BASE_STEPS_FULL_MSG : usize = 217 ;
383+ pub const BASE_STEPS_PARTIAL_MSG : usize = 195 ;
384+ pub const STEPS_PER_2_U32_REMINDER : usize = 3 ;
385+
386+ // TODO(AvivG): This is a placeholder, add the actual gas cost for the BLAKE opcode
387+ pub const BLAKE_OPCODE_GAS : usize = 0 ;
388+ }
389+
390+ fn compute_blake_hash_steps ( n_big_felts : usize , n_small_felts : usize ) -> usize {
391+ let total_u32s =
392+ n_big_felts * blake_cost:: N_U32S_BIG_FELT + n_small_felts * blake_cost:: N_U32S_SMALL_FELT ;
393+ let rem_u32s = total_u32s % blake_cost:: N_U32S_MESSAGE ;
394+ let base = if rem_u32s == 0 {
395+ blake_cost:: BASE_STEPS_FULL_MSG
396+ } else {
397+ blake_cost:: BASE_STEPS_PARTIAL_MSG + blake_cost:: STEPS_PER_2_U32_REMINDER * ( rem_u32s / 2 )
398+ } ;
399+
400+ n_big_felts * blake_cost:: STEPS_BIG_FELT + n_small_felts * blake_cost:: STEPS_SMALL_FELT + base
401+ }
402+
403+ fn count_blake_opcode ( n_big_felts : usize , n_small_felts : usize ) -> usize {
404+ // The BLAKE opcode is used once per 16 u32s.
405+ let total_u32s =
406+ n_big_felts * blake_cost:: N_U32S_BIG_FELT + n_small_felts * blake_cost:: N_U32S_SMALL_FELT ;
407+
408+ let mut n_msgs = total_u32s / blake_cost:: N_U32S_MESSAGE ;
409+ n_msgs += if total_u32s % blake_cost:: N_U32S_MESSAGE > 0 { 1 } else { 0 } ;
410+
411+ n_msgs
412+ }
413+
414+ /// Estimates the VM resources for `encode_felt252_data_and_calc_blake_hash` in the Starknet OS.
415+ /// Accounts for small felts unpack to 2-u32s and big felts to 8-u32s.
416+ pub fn cost_of_encode_felt252_data_and_calc_blake_hash (
417+ n_big_felts : usize ,
418+ n_small_felts : usize ,
419+ versioned_constants : & VersionedConstants ,
420+ ) -> GasAmount {
421+ let n_steps = compute_blake_hash_steps ( n_big_felts, n_small_felts) ;
422+ let n_felts = n_big_felts + n_small_felts;
423+ // The OS uses one `range_check` per input felt to validate each element’s size constraints.
424+ let builtins = HashMap :: from ( [ ( BuiltinName :: range_check, n_felts) ] ) ;
425+ let resources =
426+ ExecutionResources { n_steps, n_memory_holes : 0 , builtin_instance_counter : builtins } ;
427+ let blake_opcode_gas =
428+ count_blake_opcode ( n_big_felts, n_small_felts) * blake_cost:: BLAKE_OPCODE_GAS ;
429+
430+ safe_add_gas_panic_on_overflow (
431+ vm_resources_to_sierra_gas ( resources, versioned_constants) ,
432+ GasAmount ( u64_from_usize ( blake_opcode_gas) ) ,
433+ )
434+ }
0 commit comments