@@ -3,6 +3,7 @@ use std::collections::{HashMap, HashSet};
33use assert_matches:: assert_matches;
44use blockifier_test_utils:: cairo_versions:: { CairoVersion , RunnableCairo1 } ;
55use blockifier_test_utils:: contracts:: FeatureContract ;
6+ use cairo_vm:: types:: builtin_name:: BuiltinName ;
67use rstest:: { fixture, rstest} ;
78use starknet_api:: execution_resources:: GasAmount ;
89use starknet_api:: transaction:: fields:: Fee ;
@@ -190,19 +191,49 @@ fn test_bouncer_update(#[case] initial_bouncer: Bouncer) {
190191 assert_eq ! ( updated_bouncer, expected_bouncer) ;
191192}
192193
193- /// This parameterized test verifies `Bouncer::try_update` behavior when varying only `sierra_gas`.
194194#[ rstest]
195- #[ case:: positive_flow( GasAmount ( 1 ) , "ok" ) ]
196- #[ case:: block_full( GasAmount ( 11 ) , "block_full" ) ]
197- #[ case:: transaction_too_large( GasAmount ( 21 ) , "too_large" ) ]
198- fn test_bouncer_try_update_sierra_gas (
199- #[ case] added_gas : GasAmount ,
200- #[ case] scenario : & ' static str ,
201- block_context : BlockContext ,
202- block_max_capacity : BouncerWeights ,
203- bouncer_config : BouncerConfig ,
204- mut state : CachedState < DictStateReader > ,
205- ) {
195+ #[ case:: sierra_gas_positive_flow( "ok" ) ]
196+ #[ case:: sierra_gas_block_full( "sierra_gas_block_full" ) ]
197+ #[ case:: proving_gas_positive_flow( "ok" ) ]
198+ #[ case:: proving_gas_block_full( "proving_gas_block_full" ) ]
199+ fn test_bouncer_try_update_gas_based ( #[ case] scenario : & ' static str , block_context : BlockContext ) {
200+ let state = & mut test_state ( & block_context. chain_info , Fee ( 0 ) , & [ ] ) ;
201+ let mut transactional_state = TransactionalState :: create_transactional ( state) ;
202+ let builtin_weights = BuiltinWeights :: default ( ) ;
203+
204+ let range_check_count = 2 ;
205+ let max_capacity_builtin_counters =
206+ HashMap :: from ( [ ( BuiltinName :: range_check, range_check_count) ] ) ;
207+ let builtin_counters = match scenario {
208+ "proving_gas_block_full" => max_capacity_builtin_counters. clone ( ) ,
209+ // Use a minimal or empty map.
210+ "ok" | "sierra_gas_block_full" => {
211+ HashMap :: from ( [ ( BuiltinName :: range_check, range_check_count - 1 ) ] )
212+ }
213+ _ => panic ! ( "Unexpected scenario: {}" , scenario) ,
214+ } ;
215+
216+ // Derive sierra_gas from scenario
217+ let sierra_gas = match scenario {
218+ "sierra_gas_block_full" => GasAmount ( 11 ) , // Exceeds capacity
219+ "ok" | "proving_gas_block_full" => GasAmount ( 1 ) , // Within capacity
220+ _ => panic ! ( "Unexpected scenario: {}" , scenario) ,
221+ } ;
222+
223+ let proving_gas_max_capacity =
224+ builtin_weights. calc_proving_gas_from_builtin_counter ( & max_capacity_builtin_counters) ;
225+
226+ let block_max_capacity = BouncerWeights {
227+ l1_gas : 20 ,
228+ message_segment_length : 20 ,
229+ n_events : 20 ,
230+ state_diff_size : 20 ,
231+ n_txs : 20 ,
232+ sierra_gas : GasAmount ( 20 ) ,
233+ proving_gas : proving_gas_max_capacity,
234+ } ;
235+ let bouncer_config = BouncerConfig { block_max_capacity, builtin_weights } ;
236+
206237 let accumulated_weights = BouncerWeights {
207238 l1_gas : 10 ,
208239 message_segment_length : 10 ,
@@ -217,57 +248,71 @@ fn test_bouncer_try_update_sierra_gas(
217248
218249 // Prepare the resources to be added to the bouncer.
219250 let execution_summary = ExecutionSummary :: default ( ) ;
220- let builtin_counters = BuiltinCounterMap :: default ( ) ;
221251 let tx_resources = TransactionResources {
222- // Only the `sierra_gas` field is varied.
223- computation : ComputationResources { sierra_gas : added_gas, ..Default :: default ( ) } ,
252+ computation : ComputationResources { sierra_gas, ..Default :: default ( ) } ,
224253 ..Default :: default ( )
225254 } ;
226- let mut transactional_state = TransactionalState :: create_transactional ( & mut state) ;
227255 let tx_state_changes_keys = transactional_state. to_state_diff ( ) . unwrap ( ) . state_maps . keys ( ) ;
228256
229- // TODO(Yoni, 1/10/2024): simplify this test and move tx-too-large cases out.
257+ let result = bouncer. try_update (
258+ & transactional_state,
259+ & tx_state_changes_keys,
260+ & execution_summary,
261+ & builtin_counters,
262+ & tx_resources,
263+ & block_context. versioned_constants ,
264+ ) ;
265+
266+ match scenario {
267+ "ok" => assert_matches ! ( result, Ok ( ( ) ) ) ,
268+ "proving_gas_block_full" | "sierra_gas_block_full" => {
269+ assert_matches ! ( result, Err ( TransactionExecutorError :: BlockFull ) )
270+ }
271+ _ => panic ! ( "Unexpected scenario: {}" , scenario) ,
272+ }
273+ }
274+
275+ #[ rstest]
276+ fn test_transaction_too_large_sierra_gas_based ( block_context : BlockContext ) {
277+ let mut state = test_state ( & block_context. chain_info , Fee ( 0 ) , & [ ] ) ;
278+ let mut transactional_state = TransactionalState :: create_transactional ( & mut state) ;
279+ let block_max_capacity = BouncerWeights { sierra_gas : GasAmount ( 20 ) , ..Default :: default ( ) } ;
280+ let bouncer_config =
281+ BouncerConfig { block_max_capacity, builtin_weights : BuiltinWeights :: default ( ) } ;
282+
283+ // Use gas amount > block_max_capacity's.
284+ let exceeding_gas = GasAmount ( 30 ) ;
285+ let execution_summary = ExecutionSummary :: default ( ) ;
286+ let builtin_counters = BuiltinCounterMap :: default ( ) ;
287+ let tx_resources = TransactionResources {
288+ computation : ComputationResources { sierra_gas : exceeding_gas, ..Default :: default ( ) } ,
289+ ..Default :: default ( )
290+ } ;
291+ let tx_state_changes_keys = transactional_state. to_state_diff ( ) . unwrap ( ) . state_maps . keys ( ) ;
230292
231- // Check that the transaction is not too large.
232- let mut result = verify_tx_weights_within_max_capacity (
293+ let result = verify_tx_weights_within_max_capacity (
233294 & transactional_state,
234295 & execution_summary,
235296 & builtin_counters,
236297 & tx_resources,
237298 & tx_state_changes_keys,
238- & bouncer . bouncer_config ,
299+ & bouncer_config,
239300 & block_context. versioned_constants ,
240301 )
241302 . map_err ( TransactionExecutorError :: TransactionExecutionError ) ;
303+
242304 let expected_weights = BouncerWeights {
243- sierra_gas : added_gas ,
305+ sierra_gas : exceeding_gas ,
244306 n_txs : 1 ,
245- proving_gas : added_gas ,
307+ proving_gas : exceeding_gas ,
246308 ..BouncerWeights :: empty ( )
247309 } ;
248310
249- if result. is_ok ( ) {
250- // Try to update the bouncer.
251- result = bouncer. try_update (
252- & transactional_state,
253- & tx_state_changes_keys,
254- & execution_summary,
255- & builtin_counters,
256- & tx_resources,
257- & block_context. versioned_constants ,
258- ) ;
259- }
260-
261- match scenario {
262- "ok" => assert_matches ! ( result, Ok ( ( ) ) ) ,
263- "block_full" => assert_matches ! ( result, Err ( TransactionExecutorError :: BlockFull ) ) ,
264- "too_large" => assert_matches ! ( result, Err (
265- TransactionExecutorError :: TransactionExecutionError (
266- TransactionExecutionError :: TransactionTooLarge { max_capacity, tx_size }
267- )
268- ) if * max_capacity == block_max_capacity && * tx_size == expected_weights) ,
269- _ => panic ! ( "Unexpected scenario: {}" , scenario) ,
270- }
311+ assert_matches ! ( result, Err (
312+ TransactionExecutorError :: TransactionExecutionError (
313+ TransactionExecutionError :: TransactionTooLarge { max_capacity, tx_size }
314+ )
315+ ) if * max_capacity == bouncer_config. block_max_capacity && * tx_size == expected_weights) ;
271316}
272317
273318#[ rstest]
0 commit comments