From 35a8be938d75bcf2c88ba88406b9f6c8c9a6da9e Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Fri, 27 Sep 2024 23:04:45 +0000 Subject: [PATCH] new(tests): EIP-7685: Add invalid request type tests --- .../conftest.py | 23 +++- .../test_request_types.py | 114 ++++++++++++++++++ 2 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 tests/prague/eip7685_general_purpose_el_requests/test_request_types.py diff --git a/tests/prague/eip7685_general_purpose_el_requests/conftest.py b/tests/prague/eip7685_general_purpose_el_requests/conftest.py index aca8b8a63d..11a971324b 100644 --- a/tests/prague/eip7685_general_purpose_el_requests/conftest.py +++ b/tests/prague/eip7685_general_purpose_el_requests/conftest.py @@ -2,7 +2,7 @@ Fixtures for the EIP-7685 deposit tests. """ -from typing import List +from typing import List, SupportsBytes import pytest @@ -27,6 +27,12 @@ def block_body_override_requests() -> List[ return None +@pytest.fixture +def block_body_extra_requests() -> List[SupportsBytes]: + """List of requests that overwrite the requests in the header. None by default.""" + return [] + + @pytest.fixture def exception() -> BlockException | None: """Block exception expected by the tests. None by default.""" @@ -41,8 +47,11 @@ def blocks( | WithdrawalRequestInteractionBase | ConsolidationRequestInteractionBase ], - block_body_override_requests: List[DepositRequest | WithdrawalRequest | ConsolidationRequest] + block_body_override_requests: List[ + DepositRequest | WithdrawalRequest | ConsolidationRequest | SupportsBytes + ] | None, + block_body_extra_requests: List[SupportsBytes], exception: BlockException | None, ) -> List[Block]: """List of blocks that comprise the test.""" @@ -60,14 +69,16 @@ def blocks( included_withdrawal_requests += r.valid_requests(withdrawal_request_fee) elif isinstance(r, ConsolidationRequestInteractionBase): included_consolidation_requests += r.valid_requests(consolidation_request_fee) - + valid_requests = ( + included_deposit_requests + included_withdrawal_requests + included_consolidation_requests + ) + if block_body_override_requests is None and block_body_extra_requests is not None: + block_body_override_requests = valid_requests + block_body_extra_requests return [ Block( txs=sum((r.transactions() for r in requests), []), header_verify=Header( - requests_hash=included_deposit_requests - + included_withdrawal_requests - + included_consolidation_requests, + requests_hash=valid_requests, ), requests=block_body_override_requests, exception=exception, diff --git a/tests/prague/eip7685_general_purpose_el_requests/test_request_types.py b/tests/prague/eip7685_general_purpose_el_requests/test_request_types.py new file mode 100644 index 0000000000..e8d0de1a7e --- /dev/null +++ b/tests/prague/eip7685_general_purpose_el_requests/test_request_types.py @@ -0,0 +1,114 @@ +""" +Test the request types that can be included in a block by the given fork. +""" +from typing import List + +import pytest + +from ethereum_test_exceptions import BlockException +from ethereum_test_forks import Fork +from ethereum_test_tools import Alloc, Block, BlockchainTestFiller, Environment + +from ..eip6110_deposits.helpers import DepositInteractionBase, DepositRequest, DepositTransaction +from ..eip7002_el_triggerable_withdrawals.helpers import ( + WithdrawalRequest, + WithdrawalRequestInteractionBase, + WithdrawalRequestTransaction, +) +from ..eip7251_consolidations.helpers import ( + ConsolidationRequest, + ConsolidationRequestInteractionBase, + ConsolidationRequestTransaction, +) +from .spec import ref_spec_7685 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7685.git_path +REFERENCE_SPEC_VERSION = ref_spec_7685.version + +pytestmark = pytest.mark.valid_from("Prague") + + +@pytest.fixture +def block_body_extra_requests(fork: Fork, invalid_request_data: bytes) -> List[bytes]: + """List of requests that overwrite the requests in the header. None by default.""" + invalid_request_type = fork.max_request_type() + 1 + return [bytes([invalid_request_type]) + invalid_request_data] + + +@pytest.fixture +def requests( + fork: Fork, + include_valid_requests: bool, +) -> List[ + DepositInteractionBase | WithdrawalRequestInteractionBase | ConsolidationRequestInteractionBase +]: + """List of valid requests that are added along with the invalid request.""" + if not include_valid_requests: + return [] + if fork.max_request_type() == 2: + return [ + DepositTransaction( + requests=[ + DepositRequest( + pubkey=1, + withdrawal_credentials=2, + amount=1_000_000_000, + signature=3, + index=0, + ) + ] + ), + WithdrawalRequestTransaction( + requests=[ + WithdrawalRequest( + validator_pubkey=1, + amount=0, + fee=1, + ) + ] + ), + ConsolidationRequestTransaction( + requests=[ + ConsolidationRequest( + source_pubkey=2, + target_pubkey=5, + fee=1, + ) + ] + ), + ] + raise NotImplementedError(f"Unsupported fork: {fork}") + + +@pytest.mark.parametrize( + "include_valid_requests", + [False, True], +) +@pytest.mark.parametrize( + "invalid_request_data", + [ + pytest.param(b"", id="no_data"), + pytest.param(b"\0", id="single_byte"), + pytest.param(b"\0" * 32, id="32_bytes"), + ], +) +@pytest.mark.parametrize( + "exception", + [ + pytest.param(BlockException.INVALID_REQUESTS, id=""), + ], +) +def test_invalid_request_type( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + blocks: List[Block], +): + """ + Test sending a block with an invalid request type. + """ + blockchain_test( + genesis_environment=Environment(), + pre=pre, + post={}, + blocks=blocks, + )