5
5
""" # noqa: E501
6
6
7
7
from itertools import permutations
8
- from typing import Any , Generator , List
8
+ from typing import Any , Dict , Generator , List , Tuple
9
9
10
10
import pytest
11
11
18
18
BlockchainTestFiller ,
19
19
BlockException ,
20
20
Bytecode ,
21
+ Bytes ,
21
22
Environment ,
22
23
Header ,
23
24
Requests ,
@@ -214,6 +215,10 @@ def get_contract_permutations(n: int = 3) -> Generator[Any, None, None]:
214
215
],
215
216
id = "withdrawal_from_eoa+consolidation_from_eoa+withdrawal_from_contract" ,
216
217
),
218
+ pytest .param (
219
+ [],
220
+ id = "empty_requests" ,
221
+ ),
217
222
],
218
223
)
219
224
def test_valid_deposit_withdrawal_consolidation_requests (
@@ -320,148 +325,154 @@ def test_valid_deposit_withdrawal_consolidation_request_from_same_tx(
320
325
)
321
326
322
327
323
- invalid_requests_block_combinations = [
324
- pytest .param (
325
- [],
326
- [], # Even with no requests, the requests hash is not sha256(b""),
327
- # but sha256(sha256(b"\0") ++ sha256(b"\1") ++ sha256(b"\2") ++ ...)
328
- BlockException .INVALID_REQUESTS ,
329
- id = "no_requests_empty_list" ,
330
- ),
331
- pytest .param (
332
- [
333
- single_deposit_from_eoa (0 ),
334
- ],
335
- [
336
- single_deposit (0 ),
337
- ],
338
- BlockException .INVALID_REQUESTS ,
339
- id = "single_deposit_incomplete_requests_list" ,
340
- ),
341
- pytest .param (
342
- [
343
- single_deposit_from_eoa (0 ),
344
- ],
345
- [],
346
- BlockException .INVALID_REQUESTS ,
347
- id = "single_deposit_empty_requests_list" ,
348
- ),
349
- # Incorrect order tests
350
- pytest .param (
351
- [
352
- single_deposit_from_eoa (0 ),
353
- ],
354
- [
355
- b"" ,
356
- single_deposit (0 ),
357
- b"" ,
328
+ def invalid_requests_block_combinations (fork : Fork ) -> List [Any ]:
329
+ """
330
+ Return a list of invalid request combinations for the given fork.
331
+
332
+ In the event of a new request type, the `all_request_types` dictionary should be updated
333
+ with the new request type and its corresponding request-generating transaction.
334
+ """
335
+ assert fork .max_request_type () == 2 , "Test update is needed for new request types"
336
+
337
+ all_request_types : Dict [
338
+ str ,
339
+ Tuple [
340
+ DepositTransaction | WithdrawalRequestTransaction | ConsolidationRequestTransaction ,
341
+ DepositRequest | WithdrawalRequest | ConsolidationRequest ,
358
342
],
359
- BlockException .INVALID_REQUESTS ,
360
- id = "single_deposit_incorrect_order_1" ,
361
- ),
362
- pytest .param (
363
- [
343
+ ] = {
344
+ "deposit" : (
364
345
single_deposit_from_eoa (0 ),
365
- ],
366
- [
367
- b"" ,
368
- b"" ,
369
346
single_deposit (0 ),
370
- ],
371
- BlockException .INVALID_REQUESTS ,
372
- id = "single_deposit_incorrect_order_2" ,
373
- ),
374
- pytest .param (
375
- [
376
- single_withdrawal_from_eoa (0 ),
377
- ],
378
- [
379
- single_withdrawal (0 ).with_source_address (TestAddress ),
380
- b"" ,
381
- b"" ,
382
- ],
383
- BlockException .INVALID_REQUESTS ,
384
- id = "single_withdrawal_incorrect_order_1" ,
385
- ),
386
- pytest .param (
387
- [
347
+ ),
348
+ "withdrawal" : (
388
349
single_withdrawal_from_eoa (0 ),
389
- ],
390
- [
391
- b"" ,
392
- b"" ,
393
350
single_withdrawal (0 ).with_source_address (TestAddress ),
394
- ],
395
- BlockException .INVALID_REQUESTS ,
396
- id = "single_withdrawal_incorrect_order_2" ,
397
- ),
398
- pytest .param (
399
- [
351
+ ),
352
+ "consolidation" : (
400
353
single_consolidation_from_eoa (0 ),
401
- ],
402
- [
403
354
single_consolidation (0 ).with_source_address (TestAddress ),
404
- b"" ,
405
- b"" ,
406
- ],
407
- BlockException .INVALID_REQUESTS ,
408
- id = "single_consolidation_incorrect_order_1" ,
409
- ),
410
- pytest .param (
411
- [
412
- single_consolidation_from_eoa (0 ),
413
- ],
414
- [
415
- b"" ,
416
- single_consolidation (0 ).with_source_address (TestAddress ),
417
- b"" ,
418
- ],
419
- BlockException .INVALID_REQUESTS ,
420
- id = "single_consolidation_incorrect_order_2" ,
421
- ),
422
- pytest .param (
423
- [
424
- single_deposit_from_eoa (0 ),
425
- single_withdrawal_from_eoa (0 ),
426
- ],
427
- [
428
- single_deposit (0 ),
429
- single_withdrawal (0 ).with_source_address (TestAddress ),
430
- ],
431
- BlockException .INVALID_REQUESTS ,
432
- id = "single_deposit_single_withdrawal_incomplete_requests_list" ,
433
- ),
434
- pytest .param (
435
- [
436
- single_deposit_from_eoa (0 ),
437
- single_withdrawal_from_eoa (0 ),
438
- ],
439
- [
440
- single_deposit (0 ),
441
- ],
442
- BlockException .INVALID_REQUESTS ,
443
- id = "single_deposit_single_withdrawal_incomplete_requests_list_2" ,
444
- ),
445
- pytest .param (
446
- [
447
- single_deposit_from_eoa (0 ),
448
- single_withdrawal_from_eoa (0 ),
449
- single_consolidation_from_eoa (0 ),
450
- ],
451
- [
452
- single_deposit (0 ),
453
- single_withdrawal (0 ).with_source_address (TestAddress ),
454
- ],
455
- BlockException .INVALID_REQUESTS ,
456
- id = "single_deposit_single_withdrawal_single_consolidation_incomplete_requests_list" ,
457
- ),
458
- ]
355
+ ),
356
+ }
357
+
358
+ # - Empty requests list with invalid hash
359
+ combinations = [
360
+ pytest .param (
361
+ [],
362
+ [
363
+ bytes ([i ]) for i in range (fork .max_request_type () + 1 )
364
+ ], # Using empty requests, calculate the hash using an invalid calculation method:
365
+ # sha256(sha256(b"\0") ++ sha256(b"\1") ++ sha256(b"\2") ++ ...)
366
+ BlockException .INVALID_REQUESTS ,
367
+ id = "no_requests_invalid_hash_calculation_method" ,
368
+ ),
369
+ pytest .param (
370
+ [],
371
+ [
372
+ bytes ([]) for _ in range (fork .max_request_type () + 1 )
373
+ ], # Using empty requests, calculate the hash using an invalid calculation method:
374
+ # sha256(sha256(b"") ++ sha256(b"") ++ sha256(b"") ++ ...)
375
+ BlockException .INVALID_REQUESTS ,
376
+ id = "no_requests_invalid_hash_calculation_method_2" ,
377
+ ),
378
+ ]
459
379
380
+ # - Missing request or request type byte tests
381
+ for request_type , (eoa_request , block_request ) in all_request_types .items ():
382
+ combinations .extend (
383
+ [
384
+ pytest .param (
385
+ [eoa_request ],
386
+ [
387
+ block_request
388
+ ], # The request type byte missing because we need to use the `Requests` class
389
+ BlockException .INVALID_REQUESTS ,
390
+ id = f"single_{ request_type } _missing_type_byte" ,
391
+ ),
392
+ pytest .param (
393
+ [eoa_request ],
394
+ [],
395
+ BlockException .INVALID_REQUESTS ,
396
+ id = f"single_{ request_type } _empty_requests_list" ,
397
+ ),
398
+ ]
399
+ )
460
400
461
- @pytest .mark .parametrize (
401
+ # - Incorrect order tests
402
+ correct_order : List [Bytes ] = Requests (
403
+ * [r [1 ] for r in all_request_types .values ()]
404
+ ).requests_list # Requests automatically adds the type byte
405
+ correct_order_transactions : List [
406
+ DepositTransaction | WithdrawalRequestTransaction | ConsolidationRequestTransaction
407
+ ] = [r [0 ] for r in all_request_types .values ()]
408
+
409
+ # Send first element to the end
410
+ combinations .append (
411
+ pytest .param (
412
+ correct_order_transactions [1 :] + [correct_order_transactions [0 ]],
413
+ correct_order [1 :] + [correct_order [0 ]],
414
+ BlockException .INVALID_REQUESTS ,
415
+ id = "incorrect_order_first_request_at_end" ,
416
+ ),
417
+ )
418
+
419
+ # Send second element to the end
420
+ combinations .append (
421
+ pytest .param (
422
+ [correct_order_transactions [0 ]]
423
+ + correct_order_transactions [2 :]
424
+ + [correct_order_transactions [1 ]],
425
+ [correct_order [0 ]] + correct_order [2 :] + [correct_order [1 ]],
426
+ BlockException .INVALID_REQUESTS ,
427
+ id = "incorrect_order_second_request_at_end" ,
428
+ ),
429
+ )
430
+
431
+ # Bring last element to the beginning
432
+ combinations .append (
433
+ pytest .param (
434
+ [correct_order_transactions [- 1 ]] + correct_order_transactions [:- 1 ],
435
+ [correct_order [- 1 ]] + correct_order [:- 1 ],
436
+ BlockException .INVALID_REQUESTS ,
437
+ id = "incorrect_order_last_request_at_beginning" ,
438
+ ),
439
+ )
440
+
441
+ # - Duplicate request tests
442
+ for request_type , (eoa_request , block_request ) in all_request_types .items ():
443
+ combinations .append (
444
+ pytest .param (
445
+ [eoa_request ],
446
+ Requests (block_request ).requests_list * 2 ,
447
+ BlockException .INVALID_REQUESTS ,
448
+ id = f"duplicate_{ request_type } _request" ,
449
+ ),
450
+ )
451
+
452
+ # - Extra invalid request tests
453
+ combinations .append (
454
+ pytest .param (
455
+ correct_order_transactions ,
456
+ correct_order + [b"" ],
457
+ BlockException .INVALID_REQUESTS ,
458
+ id = "extra_empty_request" ,
459
+ ),
460
+ )
461
+ combinations .append (
462
+ pytest .param (
463
+ correct_order_transactions ,
464
+ correct_order + [bytes ([fork .max_request_type () + 1 ])],
465
+ BlockException .INVALID_REQUESTS ,
466
+ id = "extra_invalid_type_request" ,
467
+ ),
468
+ )
469
+
470
+ return combinations
471
+
472
+
473
+ @pytest .mark .parametrize_by_fork (
462
474
"requests,block_body_override_requests,exception" ,
463
475
invalid_requests_block_combinations ,
464
- indirect = ["block_body_override_requests" ],
465
476
)
466
477
def test_invalid_deposit_withdrawal_consolidation_requests (
467
478
blockchain_test : BlockchainTestFiller ,
@@ -484,10 +495,9 @@ def test_invalid_deposit_withdrawal_consolidation_requests(
484
495
)
485
496
486
497
487
- @pytest .mark .parametrize (
498
+ @pytest .mark .parametrize_by_fork (
488
499
"requests,block_body_override_requests,exception" ,
489
500
invalid_requests_block_combinations ,
490
- indirect = ["block_body_override_requests" ],
491
501
)
492
502
@pytest .mark .parametrize ("correct_requests_hash_in_header" , [True ])
493
503
def test_invalid_deposit_withdrawal_consolidation_requests_engine (
0 commit comments