From 567b3b6ada386e94577f1ed1d53c3208d6fab8ef Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Tue, 29 Apr 2025 18:58:28 +0000 Subject: [PATCH 01/13] feat(plugins/shared): Add "mainnet" marker --- src/pytest_plugins/shared/execute_fill.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/pytest_plugins/shared/execute_fill.py b/src/pytest_plugins/shared/execute_fill.py index 565771d29a4..cffb0f34659 100644 --- a/src/pytest_plugins/shared/execute_fill.py +++ b/src/pytest_plugins/shared/execute_fill.py @@ -158,6 +158,10 @@ def pytest_configure(config: pytest.Config): "markers", "valid_for_bpo_forks: Marks a test as valid for BPO forks", ) + config.addinivalue_line( + "markers", + "mainnet: Specialty tests crafted for running on mainnet and sanity checking.", + ) @pytest.fixture(scope="function") From 824a308ad43cee4a67600373f79b819af375f09c Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Tue, 29 Apr 2025 23:13:40 +0000 Subject: [PATCH 02/13] new(tests): EIP-2537 mainnet tests --- .../conftest.py | 2 +- .../test_eip.py | 91 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 tests/prague/eip2537_bls_12_381_precompiles/test_eip.py diff --git a/tests/prague/eip2537_bls_12_381_precompiles/conftest.py b/tests/prague/eip2537_bls_12_381_precompiles/conftest.py index a4780065df7..d8b2efe771a 100644 --- a/tests/prague/eip2537_bls_12_381_precompiles/conftest.py +++ b/tests/prague/eip2537_bls_12_381_precompiles/conftest.py @@ -162,7 +162,7 @@ def call_contract_address(pre: Alloc, call_contract_code: Bytecode) -> Address: @pytest.fixture def sender(pre: Alloc) -> EOA: """Sender of the transaction.""" - return pre.fund_eoa(1_000_000_000_000_000_000) + return pre.fund_eoa() @pytest.fixture diff --git a/tests/prague/eip2537_bls_12_381_precompiles/test_eip.py b/tests/prague/eip2537_bls_12_381_precompiles/test_eip.py new file mode 100644 index 00000000000..cbaa8404a1b --- /dev/null +++ b/tests/prague/eip2537_bls_12_381_precompiles/test_eip.py @@ -0,0 +1,91 @@ +""" +abstract: Tests all precompiles of [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) + Tests all precompiles of [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537). +""" # noqa: E501 + +import pytest + +from ethereum_test_tools import Alloc, Environment, StateTestFiller, Transaction + +from .spec import FP, FP2, Scalar, Spec, ref_spec_2537 + +REFERENCE_SPEC_GIT_PATH = ref_spec_2537.git_path +REFERENCE_SPEC_VERSION = ref_spec_2537.version + + +@pytest.mark.parametrize( + "precompile_address,input_data,expected_output,vector_gas_value", + [ + pytest.param( + Spec.G1ADD, + Spec.G1 + Spec.INF_G1, + Spec.G1, + None, + id="G1ADD", + ), + pytest.param( + Spec.G1MSM, + Spec.G1 + Scalar(1) + Spec.INF_G1 + Scalar(1), + Spec.G1, + None, + id="G1MSM", + ), + pytest.param( + Spec.G2ADD, + Spec.G2 + Spec.INF_G2, + Spec.G2, + None, + id="G2ADD", + ), + pytest.param( + Spec.G2MSM, + Spec.G2 + Scalar(1) + Spec.INF_G2 + Scalar(1), + Spec.G2, + None, + id="G2MSM", + ), + pytest.param( + Spec.PAIRING, + Spec.G1 + Spec.INF_G2, + Spec.PAIRING_TRUE, + None, + id="PAIRING", + ), + pytest.param( + Spec.MAP_FP_TO_G1, + FP( + 799950832265136997107648781861994410980648980263584507133499364313075404851459407870655748616451882783569609925573 # noqa: E501 + ), + Spec.INF_G1, + None, + id="fp_map_to_inf", + ), + pytest.param( + Spec.MAP_FP2_TO_G2, + FP2( + ( + 3510328712861478240121438855244276237335901234329585006107499559909114695366216070652508985150831181717984778988906, # noqa: E501 + 2924545590598115509050131525615277284817672420174395176262156166974132393611647670391999011900253695923948997972401, # noqa: E501 + ) + ), + Spec.INF_G2, + None, + id="fp_map_to_inf", + ), + ], +) +@pytest.mark.valid_at("Prague") +@pytest.mark.mainnet +def test_eip_2537( + state_test: StateTestFiller, + pre: Alloc, + post: dict, + tx: Transaction, +): + """Test the all precompiles of EIP-2537.""" + state_test( + env=Environment(), + pre=pre, + tx=tx, + post=post, + ) From 6e8aa957355ac92b3f5b60dac9de60179eb0840f Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 22:02:37 +0000 Subject: [PATCH 03/13] fix(tests): EIP-2537 file rename --- .../{test_eip.py => test_eip_mainnet.py} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename tests/prague/eip2537_bls_12_381_precompiles/{test_eip.py => test_eip_mainnet.py} (87%) diff --git a/tests/prague/eip2537_bls_12_381_precompiles/test_eip.py b/tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py similarity index 87% rename from tests/prague/eip2537_bls_12_381_precompiles/test_eip.py rename to tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py index cbaa8404a1b..c5531699407 100644 --- a/tests/prague/eip2537_bls_12_381_precompiles/test_eip.py +++ b/tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py @@ -1,6 +1,6 @@ """ -abstract: Tests all precompiles of [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) - Tests all precompiles of [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537). +abstract: Crafted tests for mainnet of [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537) + Crafted tests for mainnet of [EIP-2537: Precompile for BLS12-381 curve operations](https://eips.ethereum.org/EIPS/eip-2537). """ # noqa: E501 import pytest @@ -12,6 +12,8 @@ REFERENCE_SPEC_GIT_PATH = ref_spec_2537.git_path REFERENCE_SPEC_VERSION = ref_spec_2537.version +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + @pytest.mark.parametrize( "precompile_address,input_data,expected_output,vector_gas_value", @@ -74,8 +76,6 @@ ), ], ) -@pytest.mark.valid_at("Prague") -@pytest.mark.mainnet def test_eip_2537( state_test: StateTestFiller, pre: Alloc, From 08dde52ba05a74d58f269d14fc1e0a2dcd1649fe Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 22:02:57 +0000 Subject: [PATCH 04/13] new(tests): EIP-2935 mainnet tests --- .../test_eip_mainnet.py | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 tests/prague/eip2935_historical_block_hashes_from_state/test_eip_mainnet.py diff --git a/tests/prague/eip2935_historical_block_hashes_from_state/test_eip_mainnet.py b/tests/prague/eip2935_historical_block_hashes_from_state/test_eip_mainnet.py new file mode 100644 index 00000000000..60b2cd3bfae --- /dev/null +++ b/tests/prague/eip2935_historical_block_hashes_from_state/test_eip_mainnet.py @@ -0,0 +1,51 @@ +""" +abstract: Crafted tests for mainnet of [EIP-2935: Serve historical block hashes from state](https://eips.ethereum.org/EIPS/eip-2935) + Crafted tests for mainnet of [EIP-2935: Serve historical block hashes from state](https://eips.ethereum.org/EIPS/eip-2935). +""" # noqa: E501 + +import pytest + +from ethereum_test_tools import Account, Alloc, Block, BlockchainTestFiller, Transaction +from ethereum_test_tools import Opcodes as Op + +from .spec import Spec, ref_spec_2935 + +REFERENCE_SPEC_GIT_PATH = ref_spec_2935.git_path +REFERENCE_SPEC_VERSION = ref_spec_2935.version + +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + + +def test_eip_2935( + blockchain_test: BlockchainTestFiller, + pre: Alloc, +): + """Test a simple block hash request from EIP-2935 system contract.""" + check_block_number = Op.SUB(Op.NUMBER, 1) # Parent block number + check_contract_code = ( + Op.MSTORE(0, check_block_number) + + Op.POP( + Op.CALL( + address=Spec.HISTORY_STORAGE_ADDRESS, + args_offset=0, + args_size=32, + ret_offset=32, + ret_size=32, + ) + ) + + Op.SSTORE(0, Op.EQ(Op.MLOAD(32), Op.BLOCKHASH(check_block_number))) + ) + check_contract_address = pre.deploy_contract(check_contract_code) + tx = Transaction( + to=check_contract_address, + gas_limit=50_000, + sender=pre.fund_eoa(), + ) + block = Block(txs=[tx]) + blockchain_test( + pre=pre, + blocks=[block], + post={ + check_contract_address: Account(storage={0: 1}), + }, + ) From 2941b6fd344c19fdfff27bcd98e912e9d9dec8bb Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 22:03:08 +0000 Subject: [PATCH 05/13] new(tests): EIP-7623 mainnet tests --- .../test_eip_mainnet.py | 318 ++++++++++++++++++ 1 file changed, 318 insertions(+) create mode 100644 tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py diff --git a/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py b/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py new file mode 100644 index 00000000000..3d113ea48fd --- /dev/null +++ b/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py @@ -0,0 +1,318 @@ +""" +abstract: Crafted tests for mainnet of [EIP-7623: Increase calldata cost](https://eips.ethereum.org/EIPS/eip-7623) + Crafted tests for mainnet of [EIP-7623: Increase calldata cost](https://eips.ethereum.org/EIPS/eip-7623). +""" # noqa: E501 + +import pytest + +from ethereum_test_forks import Prague +from ethereum_test_tools import ( + AccessList, + Address, + Alloc, + Hash, + StateTestFiller, + Transaction, + add_kzg_version, +) +from ethereum_test_tools import Opcodes as Op + +from ...cancun.eip4844_blobs.spec import Spec as EIP_4844_Spec +from .helpers import DataTestType +from .spec import ref_spec_7623 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7623.git_path +REFERENCE_SPEC_VERSION = ref_spec_7623.version + +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + + +@pytest.mark.parametrize( + "ty,protected,access_list,blob_versioned_hashes,authorization_list", + [ + pytest.param(0, True, None, None, None, id="type_0_protected"), + pytest.param(0, False, None, None, None, id="type_0_unprotected"), + pytest.param( + 1, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + None, + None, + id="type_1", + ), + pytest.param( + 2, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + None, + None, + id="type_2", + ), + pytest.param( + 3, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + add_kzg_version( + [Hash(x) for x in range(1)], + EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG, + ), + None, + id="type_3", + marks=pytest.mark.execute( + pytest.mark.skip(reason="Blob txs not supported by execute") + ), + ), + pytest.param( + 4, + True, + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + None, + [Address(1)], + id="type_4", + ), + ], + indirect=["authorization_list"], +) +@pytest.mark.parametrize( + "tx_gas_delta", + [ + pytest.param(0, id="exact_gas"), + ], +) +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id="to_eoa"), + ], + indirect=True, +) +@pytest.mark.parametrize( + "data_test_type", + [ + pytest.param( + DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS, + id="floor_gas_greater_than_intrinsic_gas", + ), + ], +) +def test_eip_7623( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """Test transaction validity for transactions without access lists and contract creation.""" + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "to", + [ + pytest.param("eoa", id="to_eoa"), + pytest.param(None, id="contract_creating"), + pytest.param(Op.STOP, id=""), + ], + indirect=True, +) +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + None, + id="no_access_list", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + id="single_access_list_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_access_list_single_storage_key", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(k) for k in range(10)])], + id="single_access_list_multiple_storage_keys", + ), + pytest.param( + [AccessList(address=Address(a), storage_keys=[]) for a in range(10)], + id="multiple_access_lists_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(a), storage_keys=[Hash(0)]) for a in range(10)], + id="multiple_access_lists_single_storage_key", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[Hash(k) for k in range(10)]) + for a in range(10) + ], + id="multiple_access_lists_multiple_storage_keys", + ), + ], +) +@pytest.mark.parametrize( + "ty", + [pytest.param(1, id="type_1"), pytest.param(2, id="type_2")], +) +def test_transaction_validity_type_1_type_2( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """Test transaction validity for transactions with access lists and contract creation.""" + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + None, + id="no_access_list", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + id="single_access_list_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_access_list_single_storage_key", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(k) for k in range(10)])], + id="single_access_list_multiple_storage_keys", + ), + pytest.param( + [AccessList(address=Address(a), storage_keys=[]) for a in range(10)], + id="multiple_access_lists_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(a), storage_keys=[Hash(0)]) for a in range(10)], + id="multiple_access_lists_single_storage_key", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[Hash(k) for k in range(10)]) + for a in range(10) + ], + id="multiple_access_lists_multiple_storage_keys", + ), + ], +) +@pytest.mark.parametrize( + # Blobs don't really have an effect because the blob gas does is not considered in the + # intrinsic gas calculation, but we still test it to make sure that the transaction is + # correctly processed. + "blob_versioned_hashes", + [ + pytest.param( + add_kzg_version( + [Hash(x) for x in range(1)], + EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG, + ), + id="single_blob", + ), + pytest.param( + add_kzg_version( + [Hash(x) for x in range(6)], + EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG, + ), + id="multiple_blobs", + ), + ], +) +@pytest.mark.parametrize( + "ty", + [pytest.param(3, id="type_3")], +) +def test_transaction_validity_type_3( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions with access lists, blobs, + but no contract creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) + + +@pytest.mark.parametrize( + "access_list", + [ + pytest.param( + None, + id="no_access_list", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[])], + id="single_access_list_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(0)])], + id="single_access_list_single_storage_key", + ), + pytest.param( + [AccessList(address=Address(1), storage_keys=[Hash(k) for k in range(10)])], + id="single_access_list_multiple_storage_keys", + ), + pytest.param( + [AccessList(address=Address(a), storage_keys=[]) for a in range(10)], + id="multiple_access_lists_no_storage_keys", + ), + pytest.param( + [AccessList(address=Address(a), storage_keys=[Hash(0)]) for a in range(10)], + id="multiple_access_lists_single_storage_key", + ), + pytest.param( + [ + AccessList(address=Address(a), storage_keys=[Hash(k) for k in range(10)]) + for a in range(10) + ], + id="multiple_access_lists_multiple_storage_keys", + ), + ], +) +@pytest.mark.parametrize( + "authorization_list", + [ + pytest.param( + [Address(1)], + id="single_authorization", + ), + pytest.param( + [Address(i + 1) for i in range(10)], + id="multiple_authorizations", + ), + ], + indirect=True, +) +@pytest.mark.parametrize( + "ty", + [pytest.param(4, id="type_4")], +) +def test_transaction_validity_type_4( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, +) -> None: + """ + Test transaction validity for transactions with access lists, authorization lists, but no + contract creation. + """ + state_test( + pre=pre, + post={}, + tx=tx, + ) From 91b48f50cd0c7b13113d058647eedb3ff53b519a Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 22:03:18 +0000 Subject: [PATCH 06/13] new(tests): EIP-6110 mainnet tests --- .../eip6110_deposits/test_eip_mainnet.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 tests/prague/eip6110_deposits/test_eip_mainnet.py diff --git a/tests/prague/eip6110_deposits/test_eip_mainnet.py b/tests/prague/eip6110_deposits/test_eip_mainnet.py new file mode 100644 index 00000000000..54077e350c3 --- /dev/null +++ b/tests/prague/eip6110_deposits/test_eip_mainnet.py @@ -0,0 +1,59 @@ +""" +abstract: Crafted tests for mainnet of [EIP-6110: Supply validator deposits on chain](https://eips.ethereum.org/EIPS/eip-6110) + Crafted tests for mainnet of [EIP-6110: Supply validator deposits on chain](https://eips.ethereum.org/EIPS/eip-6110). +""" # noqa: E501 + +from typing import List + +import pytest + +from ethereum_test_tools import ( + Alloc, + Block, + BlockchainTestFiller, + Environment, +) + +from .helpers import DepositRequest, DepositTransaction +from .spec import ref_spec_6110 + +REFERENCE_SPEC_GIT_PATH = ref_spec_6110.git_path +REFERENCE_SPEC_VERSION = ref_spec_6110.version + +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + + +@pytest.mark.parametrize( + "requests", + [ + pytest.param( + [ + DepositTransaction( + # TODO: Use a real public key to allow recovery of the funds. + requests=[ + DepositRequest( + pubkey=0x01, + withdrawal_credentials=0x02, + amount=1_000_000_000, + signature=0x03, + index=0x0, + ) + ], + ), + ], + id="single_deposit_from_eoa_minimum", + ), + ], +) +def test_eip_6110( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + blocks: List[Block], +): + """Test making a deposit to the beacon chain deposit contract.""" + blockchain_test( + genesis_environment=Environment(), + pre=pre, + post={}, + blocks=blocks, + ) From 279f769c135a42052993732c6b245fcad3a55de9 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 22:45:47 +0000 Subject: [PATCH 07/13] fix(tests): EIP-7623 --- .../test_eip_mainnet.py | 217 +----------------- 1 file changed, 3 insertions(+), 214 deletions(-) diff --git a/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py b/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py index 3d113ea48fd..4c345663622 100644 --- a/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py +++ b/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py @@ -5,7 +5,6 @@ import pytest -from ethereum_test_forks import Prague from ethereum_test_tools import ( AccessList, Address, @@ -76,13 +75,13 @@ @pytest.mark.parametrize( "tx_gas_delta", [ - pytest.param(0, id="exact_gas"), + pytest.param(0, id=""), ], ) @pytest.mark.parametrize( "to", [ - pytest.param("eoa", id="to_eoa"), + pytest.param("eoa", id=""), ], indirect=True, ) @@ -91,7 +90,7 @@ [ pytest.param( DataTestType.FLOOR_GAS_COST_GREATER_THAN_INTRINSIC_GAS, - id="floor_gas_greater_than_intrinsic_gas", + id="", ), ], ) @@ -106,213 +105,3 @@ def test_eip_7623( post={}, tx=tx, ) - - -@pytest.mark.parametrize( - "to", - [ - pytest.param("eoa", id="to_eoa"), - pytest.param(None, id="contract_creating"), - pytest.param(Op.STOP, id=""), - ], - indirect=True, -) -@pytest.mark.parametrize( - "access_list", - [ - pytest.param( - None, - id="no_access_list", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[])], - id="single_access_list_no_storage_keys", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[Hash(0)])], - id="single_access_list_single_storage_key", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[Hash(k) for k in range(10)])], - id="single_access_list_multiple_storage_keys", - ), - pytest.param( - [AccessList(address=Address(a), storage_keys=[]) for a in range(10)], - id="multiple_access_lists_no_storage_keys", - ), - pytest.param( - [AccessList(address=Address(a), storage_keys=[Hash(0)]) for a in range(10)], - id="multiple_access_lists_single_storage_key", - ), - pytest.param( - [ - AccessList(address=Address(a), storage_keys=[Hash(k) for k in range(10)]) - for a in range(10) - ], - id="multiple_access_lists_multiple_storage_keys", - ), - ], -) -@pytest.mark.parametrize( - "ty", - [pytest.param(1, id="type_1"), pytest.param(2, id="type_2")], -) -def test_transaction_validity_type_1_type_2( - state_test: StateTestFiller, - pre: Alloc, - tx: Transaction, -) -> None: - """Test transaction validity for transactions with access lists and contract creation.""" - state_test( - pre=pre, - post={}, - tx=tx, - ) - - -@pytest.mark.parametrize( - "access_list", - [ - pytest.param( - None, - id="no_access_list", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[])], - id="single_access_list_no_storage_keys", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[Hash(0)])], - id="single_access_list_single_storage_key", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[Hash(k) for k in range(10)])], - id="single_access_list_multiple_storage_keys", - ), - pytest.param( - [AccessList(address=Address(a), storage_keys=[]) for a in range(10)], - id="multiple_access_lists_no_storage_keys", - ), - pytest.param( - [AccessList(address=Address(a), storage_keys=[Hash(0)]) for a in range(10)], - id="multiple_access_lists_single_storage_key", - ), - pytest.param( - [ - AccessList(address=Address(a), storage_keys=[Hash(k) for k in range(10)]) - for a in range(10) - ], - id="multiple_access_lists_multiple_storage_keys", - ), - ], -) -@pytest.mark.parametrize( - # Blobs don't really have an effect because the blob gas does is not considered in the - # intrinsic gas calculation, but we still test it to make sure that the transaction is - # correctly processed. - "blob_versioned_hashes", - [ - pytest.param( - add_kzg_version( - [Hash(x) for x in range(1)], - EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG, - ), - id="single_blob", - ), - pytest.param( - add_kzg_version( - [Hash(x) for x in range(6)], - EIP_4844_Spec.BLOB_COMMITMENT_VERSION_KZG, - ), - id="multiple_blobs", - ), - ], -) -@pytest.mark.parametrize( - "ty", - [pytest.param(3, id="type_3")], -) -def test_transaction_validity_type_3( - state_test: StateTestFiller, - pre: Alloc, - tx: Transaction, -) -> None: - """ - Test transaction validity for transactions with access lists, blobs, - but no contract creation. - """ - state_test( - pre=pre, - post={}, - tx=tx, - ) - - -@pytest.mark.parametrize( - "access_list", - [ - pytest.param( - None, - id="no_access_list", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[])], - id="single_access_list_no_storage_keys", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[Hash(0)])], - id="single_access_list_single_storage_key", - ), - pytest.param( - [AccessList(address=Address(1), storage_keys=[Hash(k) for k in range(10)])], - id="single_access_list_multiple_storage_keys", - ), - pytest.param( - [AccessList(address=Address(a), storage_keys=[]) for a in range(10)], - id="multiple_access_lists_no_storage_keys", - ), - pytest.param( - [AccessList(address=Address(a), storage_keys=[Hash(0)]) for a in range(10)], - id="multiple_access_lists_single_storage_key", - ), - pytest.param( - [ - AccessList(address=Address(a), storage_keys=[Hash(k) for k in range(10)]) - for a in range(10) - ], - id="multiple_access_lists_multiple_storage_keys", - ), - ], -) -@pytest.mark.parametrize( - "authorization_list", - [ - pytest.param( - [Address(1)], - id="single_authorization", - ), - pytest.param( - [Address(i + 1) for i in range(10)], - id="multiple_authorizations", - ), - ], - indirect=True, -) -@pytest.mark.parametrize( - "ty", - [pytest.param(4, id="type_4")], -) -def test_transaction_validity_type_4( - state_test: StateTestFiller, - pre: Alloc, - tx: Transaction, -) -> None: - """ - Test transaction validity for transactions with access lists, authorization lists, but no - contract creation. - """ - state_test( - pre=pre, - post={}, - tx=tx, - ) From d9636dfdf7d4d9f5faec410e14389a8b2eeb013d Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 23:03:47 +0000 Subject: [PATCH 08/13] new(tests): EIP-7002,7251 mainnet tests --- .../test_eip_mainnet.py | 58 +++++++++++++++++++ .../test_eip_mainnet.py | 58 +++++++++++++++++++ 2 files changed, 116 insertions(+) create mode 100644 tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py create mode 100644 tests/prague/eip7251_consolidations/test_eip_mainnet.py diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py b/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py new file mode 100644 index 00000000000..a635543bb96 --- /dev/null +++ b/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py @@ -0,0 +1,58 @@ +""" +abstract: Crafted tests for mainnet of [EIP-7002: Execution layer triggerable withdrawals](https://eips.ethereum.org/EIPS/eip-7002) + Crafted tests for mainnet of [EIP-7002: Execution layer triggerable withdrawals](https://eips.ethereum.org/EIPS/eip-7002). +""" # noqa: E501 + +from typing import List + +import pytest + +from ethereum_test_tools import ( + Alloc, + Block, + BlockchainTestFiller, + Environment, +) + +from .helpers import WithdrawalRequest, WithdrawalRequestTransaction +from .spec import Spec, ref_spec_7002 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7002.git_path +REFERENCE_SPEC_VERSION = ref_spec_7002.version + +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + + +@pytest.mark.parametrize( + "blocks_consolidation_requests", + [ + pytest.param( + [ + [ + WithdrawalRequestTransaction( + requests=[ + WithdrawalRequest( + validator_pubkey=0x01, + amount=0, + fee=Spec.get_fee(0), + ) + ], + ), + ], + ], + id="single_withdrawal_request", + ), + ], +) +def test_eip_7002( + blockchain_test: BlockchainTestFiller, + pre: Alloc, + blocks: List[Block], +): + """Test making a withdrawal request.""" + blockchain_test( + genesis_environment=Environment(), + pre=pre, + post={}, + blocks=blocks, + ) diff --git a/tests/prague/eip7251_consolidations/test_eip_mainnet.py b/tests/prague/eip7251_consolidations/test_eip_mainnet.py new file mode 100644 index 00000000000..bb965ccdf9a --- /dev/null +++ b/tests/prague/eip7251_consolidations/test_eip_mainnet.py @@ -0,0 +1,58 @@ +""" +abstract: Crafted tests for mainnet of [EIP-7251: Increase the MAX_EFFECTIVE_BALANCE](https://eips.ethereum.org/EIPS/eip-7251) + Crafted tests for mainnet of [EIP-7251: Increase the MAX_EFFECTIVE_BALANCE](https://eips.ethereum.org/EIPS/eip-7251). +""" # noqa: E501 + +from typing import List + +import pytest + +from ethereum_test_tools import ( + Alloc, + Block, + BlockchainTestFiller, + Environment, +) + +from .helpers import ConsolidationRequest, ConsolidationRequestTransaction +from .spec import Spec, ref_spec_7251 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7251.git_path +REFERENCE_SPEC_VERSION = ref_spec_7251.version + +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + + +@pytest.mark.parametrize( + "blocks_consolidation_requests", + [ + pytest.param( + [ + [ + ConsolidationRequestTransaction( + requests=[ + ConsolidationRequest( + source_pubkey=0x01, + target_pubkey=0x02, + fee=Spec.get_fee(0), + ) + ], + ), + ], + ], + id="single_consolidation_request", + ), + ], +) +def test_eip_7251( + blockchain_test: BlockchainTestFiller, + blocks: List[Block], + pre: Alloc, +): + """Test making a consolidation request.""" + blockchain_test( + genesis_environment=Environment(), + pre=pre, + post={}, + blocks=blocks, + ) From da4705774ee6e65932eadc5114b96179635084ed Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 23:29:52 +0000 Subject: [PATCH 09/13] new(tests): EIP-7702: Mainnet tests --- .../eip7702_set_code_tx/test_eip_mainnet.py | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 tests/prague/eip7702_set_code_tx/test_eip_mainnet.py diff --git a/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py b/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py new file mode 100644 index 00000000000..4beabf965b3 --- /dev/null +++ b/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py @@ -0,0 +1,90 @@ +""" +abstract: Crafted tests for mainnet of [EIP-7702: Set EOA account code for one transaction](https://eips.ethereum.org/EIPS/eip-7702) + Crafted tests for mainnet of [EIP-7702: Set EOA account code for one transaction](https://eips.ethereum.org/EIPS/eip-7702). +""" # noqa: E501 + +import pytest + +from ethereum_test_forks import Fork +from ethereum_test_tools import ( + Account, + Alloc, + AuthorizationTuple, + Environment, + StateTestFiller, + Storage, + Transaction, +) +from ethereum_test_tools import Opcodes as Op + +from .spec import Spec, ref_spec_7702 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7702.git_path +REFERENCE_SPEC_VERSION = ref_spec_7702.version + +pytestmark = [pytest.mark.valid_at("Prague"), pytest.mark.mainnet] + + +def test_eip_7702( + state_test: StateTestFiller, + pre: Alloc, + fork: Fork, +): + """Test the executing a simple SSTORE in a set-code transaction.""" + storage = Storage() + sender = pre.fund_eoa() + auth_signer = sender + + tx_value = 1 + + set_code = ( + Op.SSTORE(storage.store_next(sender), Op.ORIGIN) + + Op.SSTORE(storage.store_next(sender), Op.CALLER) + + Op.SSTORE(storage.store_next(tx_value), Op.CALLVALUE) + + Op.STOP + ) + set_code_to_address = pre.deploy_contract( + set_code, + ) + authorization_list = [ + AuthorizationTuple( + address=set_code_to_address, + nonce=1, + signer=auth_signer, + ), + ] + gas_costs = fork.gas_costs() + intrinsic_gas_cost_calc = fork.transaction_intrinsic_cost_calculator() + intrinsic_gas_cost = intrinsic_gas_cost_calc( + access_list=[], + authorization_list_or_count=authorization_list, + ) + execution_cost = ( + (gas_costs.G_COLD_SLOAD + gas_costs.G_STORAGE_SET) * 3 + + (gas_costs.G_VERY_LOW * 3) + + (gas_costs.G_BASE * 3) + ) + + tx = Transaction( + gas_limit=intrinsic_gas_cost + execution_cost, + to=auth_signer, + value=tx_value, + authorization_list=authorization_list, + sender=sender, + ) + + state_test( + env=Environment(), + pre=pre, + tx=tx, + post={ + set_code_to_address: Account( + storage=dict.fromkeys(storage, 0), + ), + auth_signer: Account( + nonce=2, + code=Spec.delegation_designation(set_code_to_address), + storage=storage, + ), + }, + ) From a768df9538cacc9bd86d8827c5674e12947a27f3 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 23:30:08 +0000 Subject: [PATCH 10/13] fix(tests): tox on EIP-7623 --- tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py b/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py index 4c345663622..eccb88fac07 100644 --- a/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py +++ b/tests/prague/eip7623_increase_calldata_cost/test_eip_mainnet.py @@ -14,7 +14,6 @@ Transaction, add_kzg_version, ) -from ethereum_test_tools import Opcodes as Op from ...cancun.eip4844_blobs.spec import Spec as EIP_4844_Spec from .helpers import DataTestType From 3e3d35d261144329f59cffa60d5731045b14fe3f Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 30 Apr 2025 23:53:19 +0000 Subject: [PATCH 11/13] fix(tests): EIP-7702, extra parametrization --- .../eip7702_set_code_tx/test_set_code_txs.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py index 254cb5f7dfd..ce9c8a35cad 100644 --- a/tests/prague/eip7702_set_code_tx/test_set_code_txs.py +++ b/tests/prague/eip7702_set_code_tx/test_set_code_txs.py @@ -263,9 +263,18 @@ def test_set_code_to_non_empty_storage_non_zero_nonce( ) +@pytest.mark.parametrize( + "access_list_in_tx", + [ + pytest.param(None, id=""), + pytest.param("sender", id="sender_in_access_list"), + pytest.param("auth_signer", id="auth_signer_in_access_list"), + ], +) def test_set_code_to_sstore_then_sload( blockchain_test: BlockchainTestFiller, pre: Alloc, + access_list_in_tx: str | None, ): """Test the executing a simple SSTORE then SLOAD in two separate set-code transactions.""" auth_signer = pre.fund_eoa(auth_account_start_balance) @@ -295,6 +304,16 @@ def test_set_code_to_sstore_then_sload( sender=sender, ) + access_list = ( + [ + AccessList( + address=sender if access_list_in_tx == "sender" else auth_signer, + storage_keys=[Hash(storage_key_1)], + ) + ] + if access_list_in_tx + else [] + ) tx_2 = Transaction( gas_limit=100_000, to=auth_signer, @@ -306,6 +325,7 @@ def test_set_code_to_sstore_then_sload( signer=auth_signer, ), ], + access_list=access_list, sender=sender, ) From 3274eb2d38fa53ae77adce45c5eff78ca747c16c Mon Sep 17 00:00:00 2001 From: danceratopz Date: Mon, 5 May 2025 12:55:14 +0200 Subject: [PATCH 12/13] fix(tests): fix small copy-paste error that caused unknown fixture error --- .../eip7002_el_triggerable_withdrawals/test_eip_mainnet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py b/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py index a635543bb96..bb66125a2ab 100644 --- a/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py +++ b/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py @@ -24,7 +24,7 @@ @pytest.mark.parametrize( - "blocks_consolidation_requests", + "blocks_withdrawal_requests", [ pytest.param( [ From ec96f3dcc8d715bf499ca9ba18269e3e84fc2463 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Fri, 12 Sep 2025 18:36:42 +0000 Subject: [PATCH 13/13] fixup: Remove env from all tests --- .../prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py | 3 +-- tests/prague/eip6110_deposits/test_eip_mainnet.py | 2 -- .../eip7002_el_triggerable_withdrawals/test_eip_mainnet.py | 2 -- tests/prague/eip7251_consolidations/test_eip_mainnet.py | 2 -- tests/prague/eip7702_set_code_tx/test_eip_mainnet.py | 2 -- 5 files changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py b/tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py index c5531699407..1f20576b76b 100644 --- a/tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py +++ b/tests/prague/eip2537_bls_12_381_precompiles/test_eip_mainnet.py @@ -5,7 +5,7 @@ import pytest -from ethereum_test_tools import Alloc, Environment, StateTestFiller, Transaction +from ethereum_test_tools import Alloc, StateTestFiller, Transaction from .spec import FP, FP2, Scalar, Spec, ref_spec_2537 @@ -84,7 +84,6 @@ def test_eip_2537( ): """Test the all precompiles of EIP-2537.""" state_test( - env=Environment(), pre=pre, tx=tx, post=post, diff --git a/tests/prague/eip6110_deposits/test_eip_mainnet.py b/tests/prague/eip6110_deposits/test_eip_mainnet.py index 54077e350c3..852ba1d1751 100644 --- a/tests/prague/eip6110_deposits/test_eip_mainnet.py +++ b/tests/prague/eip6110_deposits/test_eip_mainnet.py @@ -11,7 +11,6 @@ Alloc, Block, BlockchainTestFiller, - Environment, ) from .helpers import DepositRequest, DepositTransaction @@ -52,7 +51,6 @@ def test_eip_6110( ): """Test making a deposit to the beacon chain deposit contract.""" blockchain_test( - genesis_environment=Environment(), pre=pre, post={}, blocks=blocks, diff --git a/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py b/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py index bb66125a2ab..b42d71ee74f 100644 --- a/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py +++ b/tests/prague/eip7002_el_triggerable_withdrawals/test_eip_mainnet.py @@ -11,7 +11,6 @@ Alloc, Block, BlockchainTestFiller, - Environment, ) from .helpers import WithdrawalRequest, WithdrawalRequestTransaction @@ -51,7 +50,6 @@ def test_eip_7002( ): """Test making a withdrawal request.""" blockchain_test( - genesis_environment=Environment(), pre=pre, post={}, blocks=blocks, diff --git a/tests/prague/eip7251_consolidations/test_eip_mainnet.py b/tests/prague/eip7251_consolidations/test_eip_mainnet.py index bb965ccdf9a..1449dae6b15 100644 --- a/tests/prague/eip7251_consolidations/test_eip_mainnet.py +++ b/tests/prague/eip7251_consolidations/test_eip_mainnet.py @@ -11,7 +11,6 @@ Alloc, Block, BlockchainTestFiller, - Environment, ) from .helpers import ConsolidationRequest, ConsolidationRequestTransaction @@ -51,7 +50,6 @@ def test_eip_7251( ): """Test making a consolidation request.""" blockchain_test( - genesis_environment=Environment(), pre=pre, post={}, blocks=blocks, diff --git a/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py b/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py index 4beabf965b3..1d415b3b5c5 100644 --- a/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py +++ b/tests/prague/eip7702_set_code_tx/test_eip_mainnet.py @@ -10,7 +10,6 @@ Account, Alloc, AuthorizationTuple, - Environment, StateTestFiller, Storage, Transaction, @@ -74,7 +73,6 @@ def test_eip_7702( ) state_test( - env=Environment(), pre=pre, tx=tx, post={