55""" # noqa: E501
66
77from itertools import permutations
8- from typing import Any , Dict , Generator , List , Tuple
8+ from typing import Dict , Generator , List , Tuple
99
1010import pytest
1111
12+ from ethereum_test_base_types .base_types import Address
1213from ethereum_test_forks import Fork
1314from ethereum_test_tools import (
1415 Account ,
2627 Transaction ,
2728)
2829from ethereum_test_tools import Opcodes as Op
30+ from ethereum_test_tools .utility .pytest import ParameterSet
31+ from ethereum_test_types .types import EOA
2932
3033from ..eip6110_deposits .helpers import DepositContract , DepositRequest , DepositTransaction
3134from ..eip6110_deposits .spec import Spec as Spec_EIP6110
4346from ..eip7251_consolidations .spec import Spec as Spec_EIP7251
4447from .spec import ref_spec_7685
4548
46- REFERENCE_SPEC_GIT_PATH = ref_spec_7685 .git_path
47- REFERENCE_SPEC_VERSION = ref_spec_7685 .version
49+ REFERENCE_SPEC_GIT_PATH : str = ref_spec_7685 .git_path
50+ REFERENCE_SPEC_VERSION : str = ref_spec_7685 .version
4851
49- pytestmark = pytest .mark .valid_from ("Prague" )
52+ pytestmark : pytest . MarkDecorator = pytest .mark .valid_from ("Prague" )
5053
5154
5255def single_deposit (i : int ) -> DepositRequest : # noqa: D103
@@ -99,9 +102,15 @@ def single_consolidation_from_contract(i: int) -> ConsolidationRequestContract:
99102 return ConsolidationRequestContract (requests = [single_consolidation (i )])
100103
101104
102- def get_permutations (n : int = 3 ) -> Generator [Any , None , None ]:
105+ def get_permutations (
106+ n : int = 3 ,
107+ ) -> Generator [
108+ ParameterSet ,
109+ None ,
110+ None ,
111+ ]:
103112 """Return possible permutations of the requests from an EOA."""
104- requests = [
113+ requests : list = [
105114 (
106115 "deposit" ,
107116 single_deposit (0 ),
@@ -119,9 +128,9 @@ def get_permutations(n: int = 3) -> Generator[Any, None, None]:
119128 yield pytest .param ([p [1 ] for p in perm ], id = "+" .join ([p [0 ] for p in perm ]))
120129
121130
122- def get_eoa_permutations (n : int = 3 ) -> Generator [Any , None , None ]:
131+ def get_eoa_permutations (n : int = 3 ) -> Generator [ParameterSet , None , None ]:
123132 """Return possible permutations of the requests from an EOA."""
124- requests = [
133+ requests : list = [
125134 (
126135 "deposit_from_eoa" ,
127136 single_deposit_from_eoa (0 ),
@@ -139,9 +148,9 @@ def get_eoa_permutations(n: int = 3) -> Generator[Any, None, None]:
139148 yield pytest .param ([p [1 ] for p in perm ], id = "+" .join ([p [0 ] for p in perm ]))
140149
141150
142- def get_contract_permutations (n : int = 3 ) -> Generator [Any , None , None ]:
151+ def get_contract_permutations (n : int = 3 ) -> Generator [ParameterSet , None , None ]:
143152 """Return possible permutations of the requests from a contract."""
144- requests = [
153+ requests : list = [
145154 (
146155 "deposit_from_contract" ,
147156 single_deposit_from_contract (0 ),
@@ -172,14 +181,6 @@ def get_contract_permutations(n: int = 3) -> Generator[Any, None, None]:
172181 ],
173182 id = "deposit_from_eoa+withdrawal_from_eoa+deposit_from_contract" ,
174183 ),
175- pytest .param (
176- [
177- single_withdrawal_from_eoa (0 ),
178- single_deposit_from_eoa (0 ),
179- single_withdrawal_from_contract (1 ),
180- ],
181- id = "withdrawal_from_eoa+deposit_from_eoa+withdrawal_from_contract" ,
182- ),
183184 pytest .param (
184185 [
185186 single_deposit_from_eoa (0 ),
@@ -214,10 +215,140 @@ def get_contract_permutations(n: int = 3) -> Generator[Any, None, None]:
214215 ],
215216 id = "withdrawal_from_eoa+consolidation_from_eoa+withdrawal_from_contract" ,
216217 ),
218+ pytest .param (
219+ [
220+ single_withdrawal_from_eoa (0 ),
221+ single_deposit_from_eoa (0 ),
222+ single_withdrawal_from_contract (1 ),
223+ ],
224+ id = "withdrawal_from_eoa+deposit_from_eoa+withdrawal_from_contract" ,
225+ ),
217226 pytest .param (
218227 [],
219228 id = "empty_requests" ,
220229 ),
230+ # contract: consolidation + withdrawal
231+ pytest .param (
232+ [
233+ single_withdrawal_from_eoa (0 ),
234+ single_consolidation_from_contract (0 ),
235+ single_withdrawal_from_contract (1 ),
236+ ],
237+ id = "withdrawal_from_eoa+consolidation_from_contract+withdrawal_from_contract" ,
238+ ),
239+ pytest .param (
240+ [
241+ single_deposit_from_eoa (0 ),
242+ single_consolidation_from_contract (0 ),
243+ single_withdrawal_from_contract (0 ),
244+ ],
245+ id = "deposit_from_eoa+consolidation_from_contract+withdrawal_from_contract" ,
246+ ),
247+ pytest .param (
248+ [
249+ single_consolidation_from_eoa (0 ),
250+ single_consolidation_from_contract (1 ),
251+ single_withdrawal_from_contract (0 ),
252+ ],
253+ id = "consolidation_from_eoa+consolidation_from_contract+withdrawal_from_contract" ,
254+ ),
255+ # contract: consolidation + deposit
256+ pytest .param (
257+ [
258+ single_withdrawal_from_eoa (0 ),
259+ single_consolidation_from_contract (0 ),
260+ single_deposit_from_contract (0 ),
261+ ],
262+ id = "withdrawal_from_eoa+consolidation_from_contract+deposit_from_contract" ,
263+ ),
264+ pytest .param (
265+ [
266+ single_deposit_from_eoa (0 ),
267+ single_consolidation_from_contract (0 ),
268+ single_deposit_from_contract (1 ),
269+ ],
270+ id = "deposit_from_eoa+consolidation_from_contract+deposit_from_contract" ,
271+ ),
272+ pytest .param (
273+ [
274+ single_consolidation_from_eoa (0 ),
275+ single_consolidation_from_contract (1 ),
276+ single_deposit_from_contract (0 ),
277+ ],
278+ id = "consolidation_from_eoa+consolidation_from_contract+deposit_from_contract" ,
279+ ),
280+ # contract: withdrawal + deposit
281+ pytest .param (
282+ [
283+ single_withdrawal_from_eoa (0 ),
284+ single_withdrawal_from_contract (1 ),
285+ single_deposit_from_contract (0 ),
286+ ],
287+ id = "withdrawal_from_eoa+withdrawal_from_contract+deposit_from_contract" ,
288+ ),
289+ pytest .param (
290+ [
291+ single_deposit_from_eoa (0 ),
292+ single_withdrawal_from_contract (0 ),
293+ single_deposit_from_contract (1 ),
294+ ],
295+ id = "deposit_from_eoa+withdrawal_from_contract+deposit_from_contract" ,
296+ ),
297+ pytest .param (
298+ [
299+ single_consolidation_from_eoa (0 ),
300+ single_withdrawal_from_contract (0 ),
301+ single_deposit_from_contract (0 ),
302+ ],
303+ id = "consolidation_from_eoa+withdrawal_from_contract+deposit_from_contract" ,
304+ ),
305+ # testing upper limits of each request type per slot if it exists
306+ pytest .param (
307+ [
308+ single_consolidation_from_contract (0 ),
309+ single_consolidation_from_contract (1 ),
310+ # single_consolidation_from_contract(2), # i=2 is not allowed cuz
311+ # only 2 MAX CONSOLIDATIONS PER BLOCK (EIP-7251), but why does the error message
312+ # not inform about this? only reports hash mismatch
313+ #
314+ # the following performs single_withdrawal_from_contract(0) to (16)
315+ * [
316+ single_withdrawal_from_contract (i )
317+ for i in range (
318+ 0 ,
319+ 16 , # ensure that the hard limit of deposits per epoch has been removed
320+ # in all clients (EIP-6610), prev limit was
321+ # 16 deposits/slot or 512 deposits/epoch
322+ ) # when using larger numbers: it fails around 1000 due to:
323+ # UnixHTTPConnectionPool(host='localhost', port=None):
324+ # Read timed out. (read timeout=20), workaround: in transition_tool.py
325+ # use SLOW_REQUEST_TIMEOUT (60 sec), so slow=True
326+ ],
327+ # single_withdrawal_from_contract(16), # i=16 not allowed cuz only
328+ # 16 MAX WITHDRAWALS PER BLOCK (EIP-7002)
329+ #
330+ # the following performs single_deposit_from_contract(0) to (18)
331+ * [
332+ single_deposit_from_contract (i )
333+ for i in range (
334+ 0 ,
335+ 18 , # ensure that the hard limit of deposits per epoch has been removed
336+ # in all clients (EIP-6610), prev limit was 16 deposits/slot
337+ # or 512 deposits/epoch
338+ ) # when using larger numbers: it fails around 1000 due to:
339+ # UnixHTTPConnectionPool(host='localhost', port=None): Read timed out.
340+ # (read timeout=20), workaround: in transition_tool.py use
341+ # SLOW_REQUEST_TIMEOUT (60 sec), so slow=True
342+ ],
343+ ],
344+ # following ID not possible to due filename length limitations
345+ # id=(
346+ # ("consolidation_from_contract+" * 2)
347+ # + ("withdrawal_from_contract+" * 16)
348+ # + ("deposit_from_contract+" * 18)
349+ # )[:-1], # remove last '+'
350+ id = "max_withdrawals_per_slot+max_consolidations_per_slot+unlimited_deposits_per_slot" ,
351+ ),
221352 ],
222353)
223354def test_valid_deposit_withdrawal_consolidation_requests (
@@ -248,23 +379,23 @@ def test_valid_deposit_withdrawal_consolidation_request_from_same_tx(
248379 Test making a deposit to the beacon chain deposit contract and a withdrawal in
249380 the same tx.
250381 """
251- withdrawal_request_fee = 1
252- consolidation_request_fee = 1
382+ withdrawal_request_fee : int = 1
383+ consolidation_request_fee : int = 1
253384
254- calldata = b""
255- contract_code = Bytecode ()
256- total_value = 0
257- storage = Storage ()
385+ calldata : bytes = b""
386+ contract_code : Bytecode = Bytecode ()
387+ total_value : int = 0
388+ storage : Storage = Storage ()
258389
259390 for request in requests :
260- calldata_start = len (calldata )
261- current_calldata = request .calldata
391+ calldata_start : int = len (calldata )
392+ current_calldata : bytes = request .calldata
262393 calldata += current_calldata
263394
264395 contract_code += Op .CALLDATACOPY (0 , calldata_start , len (current_calldata ))
265396
266- call_contract_address = 0
267- value = 0
397+ call_contract_address : int = 0
398+ value : int = 0
268399 if isinstance (request , DepositRequest ):
269400 call_contract_address = Spec_EIP6110 .DEPOSIT_CONTRACT_ADDRESS
270401 value = request .value
@@ -287,12 +418,12 @@ def test_valid_deposit_withdrawal_consolidation_request_from_same_tx(
287418 ),
288419 )
289420
290- sender = pre .fund_eoa ()
291- contract_address = pre .deploy_contract (
421+ sender : EOA = pre .fund_eoa ()
422+ contract_address : Address = pre .deploy_contract (
292423 code = contract_code ,
293424 )
294425
295- tx = Transaction (
426+ tx : Transaction = Transaction (
296427 gas_limit = 10_000_000 ,
297428 to = contract_address ,
298429 value = total_value ,
@@ -324,7 +455,7 @@ def test_valid_deposit_withdrawal_consolidation_request_from_same_tx(
324455 )
325456
326457
327- def invalid_requests_block_combinations (fork : Fork ) -> List [Any ]:
458+ def invalid_requests_block_combinations (fork : Fork ) -> List [ParameterSet ]:
328459 """
329460 Return a list of invalid request combinations for the given fork.
330461
@@ -343,29 +474,29 @@ def invalid_requests_block_combinations(fork: Fork) -> List[Any]:
343474 ],
344475 ] = {
345476 "deposit" : (
346- single_deposit_from_eoa (0 ),
347- single_deposit (0 ),
477+ single_deposit_from_eoa (0 ), # eoa_request
478+ single_deposit (0 ), # block_request
348479 ),
349480 "withdrawal" : (
350- single_withdrawal_from_eoa (0 ),
351- single_withdrawal (0 ).with_source_address (TestAddress ),
481+ single_withdrawal_from_eoa (0 ), # eoa_request
482+ single_withdrawal (0 ).with_source_address (TestAddress ), # block_request
352483 ),
353484 "consolidation" : (
354- single_consolidation_from_eoa (0 ),
355- single_consolidation (0 ).with_source_address (TestAddress ),
485+ single_consolidation_from_eoa (0 ), # eoa_request
486+ single_consolidation (0 ).with_source_address (TestAddress ), # block_request
356487 ),
357488 }
358489
359490 # - Empty requests list with invalid hash
360- combinations = [
491+ combinations : List [ ParameterSet ] = [
361492 pytest .param (
362493 [],
363494 [
364495 bytes ([i ]) for i in range (fork .max_request_type () + 1 )
365496 ], # Using empty requests, calculate the hash using an invalid calculation method:
366- # sha256(sha256(b"\0" ) ++ sha256(b"\1" ) ++ sha256(b"\2" ) ++ ...)
497+ # sha256(sha256(b'0x00' ) ++ sha256(b'0x01' ) ++ sha256(b'0x02' ) ++ ...)
367498 BlockException .INVALID_REQUESTS ,
368- id = "no_requests_invalid_hash_calculation_method " ,
499+ id = "no_requests_and_invalid_hash_calculation_method " ,
369500 ),
370501 pytest .param (
371502 [],
@@ -374,7 +505,7 @@ def invalid_requests_block_combinations(fork: Fork) -> List[Any]:
374505 ], # Using empty requests, calculate the hash using an invalid calculation method:
375506 # sha256(sha256(b"") ++ sha256(b"") ++ sha256(b"") ++ ...)
376507 BlockException .INVALID_REQUESTS ,
377- id = "no_requests_invalid_hash_calculation_method_2 " ,
508+ id = "no_requests_and_invalid_hash_calculation_method_2 " ,
378509 ),
379510 ]
380511
@@ -491,6 +622,15 @@ def invalid_requests_block_combinations(fork: Fork) -> List[Any]:
491622 id = "extra_invalid_type_request_with_data_0xff" ,
492623 ),
493624 )
625+ # too many withdrawals per block (16 is max - EIP-7002)
626+ # TODO: how to make sth like below work?
627+ # combinations.append(
628+ # pytest.param(
629+ # *[single_withdrawal_from_contract(i) for i in range(0, 17)],
630+ # BlockException.INVALID_REQUESTS,
631+ # id="more_than_16_withdrawals_per_block",
632+ # ),
633+ # )
494634
495635 return combinations
496636
0 commit comments