@@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet};
22use std:: sync:: LazyLock ;
33
44use blockifier:: blockifier_versioned_constants:: {
5+ RawStepGasCost ,
56 RawVersionedConstants ,
67 ResourcesParams ,
78 VariableCallDataFactor ,
@@ -44,7 +45,7 @@ use crate::test_manager::{
4445use crate :: tests:: NON_TRIVIAL_RESOURCE_BOUNDS ;
4546
4647// TODO(Dori): Delete this, or at least reduce it to a minimal set of unmeasurable syscalls.
47- const UNMEASURABLE_SYSCALLS : [ Selector ; 28 ] = [
48+ const UNMEASURABLE_SYSCALLS : [ Selector ; 26 ] = [
4849 Selector :: DelegateCall ,
4950 Selector :: DelegateL1Handler ,
5051 Selector :: GetBlockNumber ,
@@ -54,8 +55,6 @@ const UNMEASURABLE_SYSCALLS: [Selector; 28] = [
5455 Selector :: GetSequencerAddress ,
5556 Selector :: GetTxInfo ,
5657 Selector :: GetTxSignature ,
57- Selector :: Keccak ,
58- Selector :: KeccakRound ,
5958 Selector :: Sha256ProcessBlock ,
6059 Selector :: Sha512ProcessBlock ,
6160 Selector :: LibraryCallL1Handler ,
@@ -90,8 +89,9 @@ const UNMEASURABLE_SYSCALLS: [Selector; 28] = [
9089/// The second call will always have one more linear element than the first call.
9190/// Note: Keccak does not store the linear factor in the same entry in the versioned constants, but
9291/// it does have a measurable linear factor stored under [Selector::KeccakRound].
93- static SYSCALLS_WITH_LINEAR_FACTOR : LazyLock < HashMap < Selector , usize > > =
94- LazyLock :: new ( || HashMap :: from ( [ ( Selector :: Deploy , 1 ) , ( Selector :: MetaTxV0 , 1 ) ] ) ) ;
92+ static SYSCALLS_WITH_LINEAR_FACTOR : LazyLock < HashMap < Selector , usize > > = LazyLock :: new ( || {
93+ HashMap :: from ( [ ( Selector :: Deploy , 1 ) , ( Selector :: Keccak , 0 ) , ( Selector :: MetaTxV0 , 1 ) ] )
94+ } ) ;
9595
9696/// Expected syscalls in the fee transfer call. Should be removed from the list of syscalls during
9797/// measurement iteration - only the syscalls called during __execute__ should be measured.
@@ -177,6 +177,9 @@ async fn test_fee_transfer_syscalls() {
177177#[ tokio:: test]
178178async fn test_os_resources_regression ( ) {
179179 let os_resources_contract = FeatureContract :: OsResourcesTest ( RunnableCairo1 :: Casm ) ;
180+ let version = StarknetVersion :: LATEST ;
181+ let mut raw_vc: RawVersionedConstants =
182+ serde_json:: from_str ( VersionedConstants :: json_str ( & version) . unwrap ( ) ) . unwrap ( ) ;
180183
181184 // Setup the test initial state and test builder.
182185 // Need to explicitly set up the state to be able to override the minimal sierra version for gas
@@ -190,6 +193,7 @@ async fn test_os_resources_regression() {
190193 initial_state_data. initial_state . block_context = {
191194 let block_context = & initial_state_data. initial_state . block_context ;
192195 let mut vc = block_context. versioned_constants ( ) . clone ( ) ;
196+ assert_eq ! ( vc, raw_vc. clone( ) . into( ) ) ;
193197 vc. min_sierra_version_for_sierra_gas = SierraVersion :: new ( 99 , 99 , 99 ) ;
194198 BlockContext :: new (
195199 block_context. block_info ( ) . clone ( ) ,
@@ -336,9 +340,7 @@ async fn test_os_resources_regression() {
336340
337341 // If this is a syscall with a linear factor, the next syscall should be an invocation of
338342 // the same syscall with +1 linear element.
339- let syscall_cost = if let Some ( linear_count_in_base) =
340- SYSCALLS_WITH_LINEAR_FACTOR . get ( & selector)
341- {
343+ if let Some ( linear_count_in_base) = SYSCALLS_WITH_LINEAR_FACTOR . get ( & selector) {
342344 let next_syscall_trace = syscalls_iter. next ( ) . unwrap ( ) ;
343345 assert_eq ! (
344346 selector,
@@ -349,24 +351,50 @@ async fn test_os_resources_regression() {
349351 ) ;
350352 let next_resources =
351353 maybe_deduct_inner ( next_syscall_trace. get_resources ( ) . unwrap ( ) . clone ( ) , selector) ;
352- let linear_factor_resources = ( & next_resources - & resources) . filter_unused_builtins ( ) ;
353354
354- // Linear factor is computed; deduct the linear overhead from the base cost to get the
355- // real base cost.
356- let constant_resources = ( & resources
357- - & ( & linear_factor_resources * * linear_count_in_base) )
358- . filter_unused_builtins ( ) ;
355+ // Keccak is a special case:
356+ // 1. We store the linear cost as a separate syscall.
357+ // 2. Currently, the Keccak base cost is enforced in the OS to equal the syscall base
358+ // cost (`static_assert KECCAK_GAS_COST == SYSCALL_BASE_GAS_COST`).
359+ // TODO(Dori): If and when (2) is no longer the case, no need to replace `resources`
360+ // (measured keccak base cost) with the syscall base cost, and no need to recompute
361+ // the linear factor.
362+ if selector == Selector :: Keccak {
363+ let RawStepGasCost { step_gas_cost : n_steps } =
364+ raw_vc. os_constants . syscall_base_gas_cost . clone ( ) ;
365+ let constant_resources = ExecutionResources {
366+ n_steps : n_steps. 0 . try_into ( ) . unwrap ( ) ,
367+ ..Default :: default ( )
368+ } ;
369+ let linear_factor_resources =
370+ ( & next_resources - & constant_resources) . filter_unused_builtins ( ) ;
371+ measurements
372+ . insert ( Selector :: Keccak , VariableResourceParams :: Constant ( constant_resources) ) ;
373+ measurements. insert (
374+ Selector :: KeccakRound ,
375+ VariableResourceParams :: Constant ( linear_factor_resources) ,
376+ ) ;
377+ } else {
378+ let linear_factor_resources =
379+ ( & next_resources - & resources) . filter_unused_builtins ( ) ;
380+ // Linear factor is computed; deduct the linear overhead from the base cost to get
381+ // the real base cost.
382+ let constant_resources = ( & resources
383+ - & ( & linear_factor_resources * * linear_count_in_base) )
384+ . filter_unused_builtins ( ) ;
359385
360- VariableResourceParams :: WithFactor ( ResourcesParams {
361- constant : constant_resources,
362- // Syscalls with a linear factor have an unscaled linear factor cost.
363- calldata_factor : VariableCallDataFactor :: Unscaled ( linear_factor_resources) ,
364- } )
386+ measurements. insert (
387+ selector,
388+ VariableResourceParams :: WithFactor ( ResourcesParams {
389+ constant : constant_resources,
390+ // Syscalls with a linear factor have an unscaled linear factor cost.
391+ calldata_factor : VariableCallDataFactor :: Unscaled ( linear_factor_resources) ,
392+ } ) ,
393+ ) ;
394+ }
365395 } else {
366- VariableResourceParams :: Constant ( resources)
367- } ;
368-
369- measurements. insert ( selector, syscall_cost) ;
396+ measurements. insert ( selector, VariableResourceParams :: Constant ( resources) ) ;
397+ }
370398 }
371399
372400 // Make sure we covered all syscalls we expect to.
@@ -380,9 +408,6 @@ async fn test_os_resources_regression() {
380408 ) ;
381409
382410 // Compare the measurements with the expected values on the latest VC.
383- let version = StarknetVersion :: LATEST ;
384- let mut raw_vc: RawVersionedConstants =
385- serde_json:: from_str ( VersionedConstants :: json_str ( & version) . unwrap ( ) ) . unwrap ( ) ;
386411 for ( syscall, resources) in measurements {
387412 raw_vc. os_resources . execute_syscalls . insert ( syscall, resources) ;
388413 }
0 commit comments