@@ -66,6 +66,61 @@ const UNMEASURABLE_SYSCALLS: [Selector; 30] = [
6666
6767const SYSCALLS_WITH_LINEAR_FACTOR : [ Selector ; 2 ] = [ Selector :: Deploy , Selector :: MetaTxV0 ] ;
6868
69+ /// Expected syscalls in the fee transfer call. Should be removed from the list of syscalls during
70+ /// measurement iteration - only the syscalls called during __execute__ should be measured.
71+ const FEE_TRANSFER_SYSCALLS : [ Selector ; 10 ] = [
72+ Selector :: GetExecutionInfo ,
73+ Selector :: StorageRead ,
74+ Selector :: StorageRead ,
75+ Selector :: StorageWrite ,
76+ Selector :: StorageWrite ,
77+ Selector :: StorageRead ,
78+ Selector :: StorageRead ,
79+ Selector :: StorageWrite ,
80+ Selector :: StorageWrite ,
81+ Selector :: EmitEvent ,
82+ ] ;
83+
84+ #[ tokio:: test]
85+ async fn test_fee_transfer_syscalls ( ) {
86+ let os_resources_contract = FeatureContract :: OsResourcesTest ( RunnableCairo1 :: Casm ) ;
87+ let ( mut builder, [ os_resources_contract_address] ) =
88+ TestBuilder :: create_standard ( [ ( os_resources_contract, calldata ! [ Felt :: ZERO ] ) ] ) . await ;
89+
90+ // Fund the contract - it will be used as the account.
91+ // Then, move on to the next block, so the syscall-measurement tx is in it's own block.
92+ builder. add_fund_address_tx_with_default_amount ( os_resources_contract_address) ;
93+
94+ // Invoke from the OS resources contract, with zeros as calldata, to make the __execute__ do
95+ // nothing. All resulting events should be from the fee transfer call.
96+ builder. add_invoke_tx (
97+ InvokeTransaction :: create (
98+ invoke_tx ( invoke_tx_args ! {
99+ sender_address: os_resources_contract_address,
100+ calldata: calldata![ Felt :: ZERO , Felt :: ZERO , Felt :: ZERO ] ,
101+ resource_bounds: * NON_TRIVIAL_RESOURCE_BOUNDS ,
102+ } ) ,
103+ & builder. chain_id ( ) ,
104+ )
105+ . unwrap ( ) ,
106+ None ,
107+ None ,
108+ ) ;
109+
110+ // Build, run, and get the syscalls list.
111+ let test_output = builder. build_and_run ( ) . await ;
112+ let syscalls = test_output
113+ . runner_output
114+ . txs_trace
115+ . last ( )
116+ . unwrap ( )
117+ . get_syscalls ( )
118+ . iter ( )
119+ . map ( |syscall_trace| syscall_trace. get_selector ( ) )
120+ . collect :: < Vec < _ > > ( ) ;
121+ assert_eq ! ( syscalls, FEE_TRANSFER_SYSCALLS . to_vec( ) ) ;
122+ }
123+
69124#[ tokio:: test]
70125async fn test_os_resources_regression ( ) {
71126 let os_resources_contract = FeatureContract :: OsResourcesTest ( RunnableCairo1 :: Casm ) ;
@@ -149,19 +204,19 @@ async fn test_os_resources_regression() {
149204 test_output. perform_default_validations ( ) ;
150205
151206 // Extract syscall resources consumed, per (measurable) syscall.
152- // There should be two events emitted: the first is the syscall we are measuring, and the second
153- // is the last syscall in the tx, emitted from the fee transfer. Pop the second event.
154- let mut syscall_traces =
155- test_output. runner_output . txs_trace . last ( ) . unwrap ( ) . get_syscalls ( ) . clone ( ) ;
156- assert ! ( !UNMEASURABLE_SYSCALLS . contains( & Selector :: EmitEvent ) ) ;
207+ // Remove the fee transfer syscalls from the list by splitting the iterator into two. The second
208+ // part is the last `FEE_TRANSFER_SYSCALLS.len()` syscalls, and the first part should be the
209+ // rest.
210+ let all_syscalls = test_output. runner_output . txs_trace . last ( ) . unwrap ( ) . get_syscalls ( ) . clone ( ) ;
211+ let ( syscall_traces, fee_transfer_syscall_traces) =
212+ all_syscalls. split_at ( all_syscalls. len ( ) - FEE_TRANSFER_SYSCALLS . len ( ) ) ;
157213 assert_eq ! (
158- syscall_traces
214+ fee_transfer_syscall_traces
159215 . iter( )
160- . filter ( |syscall_trace| syscall_trace. get_selector( ) == Selector :: EmitEvent )
161- . count ( ) ,
162- 2
216+ . map ( |syscall_trace| syscall_trace. get_selector( ) )
217+ . collect :: < Vec <_>> ( ) ,
218+ FEE_TRANSFER_SYSCALLS . to_vec ( )
163219 ) ;
164- assert_eq ! ( syscall_traces. pop( ) . unwrap( ) . get_selector( ) , Selector :: EmitEvent ) ;
165220
166221 // Measure each syscall overhead. If the syscall incurs an inner call, subtract the inner call
167222 // overhead.
@@ -237,6 +292,13 @@ async fn test_os_resources_regression() {
237292 . collect:: <HashSet <_>>( )
238293 ) ;
239294
295+ // Make sure there are no more dangling syscalls.
296+ let dangling_syscall = syscalls_iter. next ( ) ;
297+ assert ! (
298+ dangling_syscall. is_none( ) ,
299+ "There are more syscalls than expected. Dangling syscall: {dangling_syscall:?}."
300+ ) ;
301+
240302 // Compare the measurements with the expected values on the latest VC.
241303 let version = StarknetVersion :: LATEST ;
242304 let mut raw_vc: RawVersionedConstants =
0 commit comments