From 68049262962ae79376f65ea4c13686b564e50c88 Mon Sep 17 00:00:00 2001 From: Felix H Date: Fri, 28 Nov 2025 11:45:07 +0000 Subject: [PATCH 1/9] feat: added more mainnet tests --- .../test_eip_mainnet.py | 86 +++++++++++++++++++ .../test_eip_mainnet.py | 67 +++++++++++++++ .../test_eip_mainnet.py | 68 +++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py create mode 100644 tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py create mode 100644 tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py diff --git a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py new file mode 100644 index 0000000000..84ca3a174e --- /dev/null +++ b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py @@ -0,0 +1,86 @@ +""" +Mainnet marked tests for +[EIP-7823: ModExp Upper Bound](https://eips.ethereum.org/EIPS/eip-7823). +""" + +from typing import Dict + +import pytest +from execution_testing import ( + Alloc, + StateTestFiller, + Transaction, + # TransactionException, +) +from execution_testing.test_types.block_types import Environment + +from ...byzantium.eip198_modexp_precompile.helpers import ModExpInput +from .spec import ref_spec_7823 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7823.git_path +REFERENCE_SPEC_VERSION = ref_spec_7823.version + +pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] + + +# @pytest.mark.exception_test +@pytest.mark.parametrize( + "modexp_input,modexp_expected", + [ + pytest.param( + ModExpInput( + base="ca" * 3070, + exponent="ca", + modulus="fe", + declared_base_length=3070, + declared_exponent_length=1, + declared_modulus_length=1, + ), + # expected result: + bytes.fromhex("00"), + id="3070-bytes-long-base", + ), + pytest.param( + ModExpInput( + base="cd", + exponent="ca" * 3070, + modulus="dc", + declared_base_length=1, + declared_exponent_length=3070, + declared_modulus_length=1, + ), + # expected result: + bytes.fromhex("00"), + id="3070-bytes-long-exp", + ), + pytest.param( + ModExpInput( + base="cd", + exponent="cf", + modulus="ee" * 3070, + declared_base_length=1, + declared_exponent_length=1, + declared_modulus_length=3070, + ), + # expected result: + bytes.fromhex("00"), + id="3070-bytes-long-mod", + ), + ], +) +def test_modexp_different_base_lengths( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, + post: Dict, + modexp_input: ModExpInput, + modexp_expected: ModExpInput, +) -> None: + """ + Mainnet test for triggering gas cost increase. + Upper bound per length param: 1024 bytes + There are 3 length params: base, e, mod + 3*1024 = 3072 + Therefore, we can do negative tests for 3070+1+1 for each of those three. + """ + state_test(env=Environment(), pre=pre, tx=tx, post=post) diff --git a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py new file mode 100644 index 0000000000..155ee12b36 --- /dev/null +++ b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py @@ -0,0 +1,67 @@ +""" +Mainnet tests for transaction gas limit cap [EIP-7825: Transaction Gas Limit +Cap](https://eips.ethereum.org/EIPS/eip-7825). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Environment, + Op, + StateTestFiller, + Transaction, + TransactionException, +) + +from .spec import ref_spec_7825 + +# Update reference spec constants +REFERENCE_SPEC_GIT_PATH = ref_spec_7825.git_path +REFERENCE_SPEC_VERSION = ref_spec_7825.version + +pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] + + +@pytest.mark.exception_test +def test_tx_gas_limit_cap_mainnet( + state_test: StateTestFiller, + pre: Alloc, + env: Environment, +) -> None: + """Negative test going beyond transaction gas limit cap.""" + target_gas_wasted_min = 2 ^ 24 + 1 + + # repeatedly call BALANCE on different addresses until we detect + # that we used up target_gas_wasted_min + code = ( + Op.PUSH4[target_gas_wasted_min] + + Op.GAS + + Op.PUSH1[0x0] + + Op.JUMPDEST + + Op.DUP1 + + Op.BALANCE + + Op.POP + + Op.PUSH1[0x1] + + Op.ADD + + Op.GAS + + Op.DUP4 + + Op.SWAP1 + + Op.SUB + + Op.DUP4 + + Op.GT + + Op.PUSH1[0x8] + + Op.JUMPI + + Op.STOP + ) + + caller_address = pre.deploy_contract(code=code) + + tx = Transaction( + to=caller_address, + sender=pre.fund_eoa(), + gas_limit=17_000_000, # more than target_gas_wasted_min + error=TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM, + ) + + state_test(env=env, pre=pre, post={}, tx=tx) diff --git a/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py b/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py new file mode 100644 index 0000000000..759d199fa8 --- /dev/null +++ b/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py @@ -0,0 +1,68 @@ +""" +Mainnet testing for osaka's [EIP-7939: Count leading zeros (CLZ)](https://eips.ethereum.org/EIPS/eip-7939). +""" + +import pytest +from execution_testing import ( + Account, + Alloc, + Op, + StateTestFiller, + Transaction, +) +from execution_testing.test_types.block_types import Environment + +from .spec import ref_spec_7939 + +REFERENCE_SPEC_GIT_PATH = ref_spec_7939.git_path +REFERENCE_SPEC_VERSION = ref_spec_7939.version + +pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] + + +# ruff keeps making parameters unreadable by putting them in one line +# fmt: off +@pytest.mark.parametrize( + "clz_input,clz_expected", + [ + pytest.param( + 2**256 - 1, + 0, + id="max-size-input-clz" + ), + pytest.param( + 0, + 256, + id="min-size-input-clz" + ), + pytest.param( + 1231350950569847740520874169721133058840016695, + 106, + id="some-other-input-clz" + ), + ], +) +# fmt: on +def test_clz_mainnet( + state_test: StateTestFiller, + pre: Alloc, + clz_input: int, + clz_expected: int, +) -> None: + """ + Test CLZ opcode on mainnet. + """ + sender = pre.fund_eoa() + contract_address = pre.deploy_contract( + code=Op.SSTORE(0, Op.CLZ(clz_input)), + storage={"0x00": "0xdeadbeef"}, + ) + tx = Transaction( + to=contract_address, + sender=sender, + gas_limit=200_000, + ) + post = { + contract_address: Account(storage={"0x00": clz_expected}), + } + state_test(env=Environment(), pre=pre, post=post, tx=tx) From aa7d4656bfb9f2eee5b95968e92f1e1ab35656b2 Mon Sep 17 00:00:00 2001 From: Felix H Date: Fri, 28 Nov 2025 14:00:12 +0000 Subject: [PATCH 2/9] fix: fix modexp tests --- .../eip198_modexp_precompile/helpers.py | 12 +++- .../test_eip_mainnet.py | 34 ++++++++--- .../test_eip_mainnet.py | 1 - .../test_eip_mainnet.py | 57 ++++++++++++++----- 4 files changed, 78 insertions(+), 26 deletions(-) diff --git a/tests/byzantium/eip198_modexp_precompile/helpers.py b/tests/byzantium/eip198_modexp_precompile/helpers.py index 4aeef7bec6..09ce5a5444 100644 --- a/tests/byzantium/eip198_modexp_precompile/helpers.py +++ b/tests/byzantium/eip198_modexp_precompile/helpers.py @@ -155,10 +155,18 @@ class ModExpOutput(TestParameterGroup): call_success (bool): The return_code from CALL, 0 indicates unsuccessful call (out-of-gas), 1 indicates call succeeded. - returned_data(str): The output returnData is the expected + returned_data (Bytes): The output returnData is the expected output of the call. """ - call_success: bool = True + call_success: bool returned_data: Bytes + + def __len__(self) -> int: + """Return the length of the returned data.""" + return len(self.returned_data) + + def __bytes__(self) -> bytes: + """Return the returned data as bytes.""" + return bytes(self.returned_data) diff --git a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py index 84ca3a174e..3a4b88a830 100644 --- a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py +++ b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py @@ -12,9 +12,13 @@ Transaction, # TransactionException, ) +from execution_testing.base_types.base_types import Bytes from execution_testing.test_types.block_types import Environment -from ...byzantium.eip198_modexp_precompile.helpers import ModExpInput +from ...byzantium.eip198_modexp_precompile.helpers import ( + ModExpInput, + ModExpOutput, +) from .spec import ref_spec_7823 REFERENCE_SPEC_GIT_PATH = ref_spec_7823.git_path @@ -23,6 +27,13 @@ pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] +# overwrite the conftest fixture +@pytest.fixture +def call_succeeds(modexp_expected: ModExpOutput) -> bool: + """Override call_succeeds to use the parametrized ModExpOutput value.""" + return modexp_expected.call_success + + # @pytest.mark.exception_test @pytest.mark.parametrize( "modexp_input,modexp_expected", @@ -36,8 +47,10 @@ declared_exponent_length=1, declared_modulus_length=1, ), - # expected result: - bytes.fromhex("00"), + ModExpOutput( + call_success=False, + returned_data=Bytes(), + ), id="3070-bytes-long-base", ), pytest.param( @@ -49,8 +62,10 @@ declared_exponent_length=3070, declared_modulus_length=1, ), - # expected result: - bytes.fromhex("00"), + ModExpOutput( + call_success=False, + returned_data=Bytes(), + ), id="3070-bytes-long-exp", ), pytest.param( @@ -62,8 +77,10 @@ declared_exponent_length=1, declared_modulus_length=3070, ), - # expected result: - bytes.fromhex("00"), + ModExpOutput( + call_success=False, + returned_data=Bytes(), + ), id="3070-bytes-long-mod", ), ], @@ -74,7 +91,8 @@ def test_modexp_different_base_lengths( tx: Transaction, post: Dict, modexp_input: ModExpInput, - modexp_expected: ModExpInput, + modexp_expected: ModExpOutput, + call_succeeds: bool, ) -> None: """ Mainnet test for triggering gas cost increase. diff --git a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py index 155ee12b36..7da68eebdc 100644 --- a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py +++ b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py @@ -5,7 +5,6 @@ import pytest from execution_testing import ( - Account, Alloc, Environment, Op, diff --git a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py index 2f9b395669..767fb34357 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py +++ b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py @@ -13,8 +13,13 @@ StateTestFiller, Transaction, ) +from execution_testing.base_types.base_types import Bytes +from execution_testing.test_types.block_types import Environment -from ...byzantium.eip198_modexp_precompile.helpers import ModExpInput +from ...byzantium.eip198_modexp_precompile.helpers import ( + ModExpInput, + ModExpOutput, +) from .spec import Spec, ref_spec_7883 REFERENCE_SPEC_GIT_PATH = ref_spec_7883.git_path @@ -23,6 +28,13 @@ pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] +# overwrite the conftest fixture +@pytest.fixture +def call_succeeds(modexp_expected: ModExpOutput) -> bool: + """Override call_succeeds to use the parametrized ModExpOutput value.""" + return modexp_expected.call_success + + @pytest.mark.parametrize( "modexp_input,modexp_expected", [ @@ -35,8 +47,10 @@ declared_exponent_length=1, declared_modulus_length=1, ), - # expected result: - bytes.fromhex("04"), + ModExpOutput( + call_success=True, + returned_data=Bytes(bytes.fromhex("04")), + ), id="32-bytes-long-base", ), pytest.param( @@ -48,8 +62,10 @@ declared_exponent_length=1, declared_modulus_length=1, ), - # expected result: - bytes.fromhex("01"), + ModExpOutput( + call_success=True, + returned_data=Bytes(bytes.fromhex("01")), + ), id="33-bytes-long-base", # higher cost than 32 bytes ), pytest.param( @@ -61,8 +77,10 @@ declared_exponent_length=1024, declared_modulus_length=1, ), - # expected result: - bytes.fromhex("02"), + ModExpOutput( + call_success=True, + returned_data=Bytes(bytes.fromhex("02")), + ), id="1024-bytes-long-exp", ), pytest.param( @@ -74,9 +92,13 @@ declared_exponent_length=3, declared_modulus_length=64, ), - # expected result: - bytes.fromhex( - "c36d804180c35d4426b57b50c5bfcca5c01856d104564cd513b461d3c8b8409128a5573e416d0ebe38f5f736766d9dc27143e4da981dfa4d67f7dc474cbee6d2" + ModExpOutput( + call_success=True, + returned_data=Bytes( + bytes.fromhex( + "c36d804180c35d4426b57b50c5bfcca5c01856d104564cd513b461d3c8b8409128a5573e416d0ebe38f5f736766d9dc27143e4da981dfa4d67f7dc474cbee6d2" + ) + ), ), id="nagydani-1-pow0x10001", ), @@ -89,9 +111,13 @@ declared_exponent_length=64, declared_modulus_length=32, ), - # expected result: - bytes.fromhex( - "0000000000000000000000000000000000000000000000000000000000000001" + ModExpOutput( + call_success=True, + returned_data=Bytes( + bytes.fromhex( + "0000000000000000000000000000000000000000000000000000000000000001" + ) + ), ), id="zero-exponent-64bytes", ), @@ -103,7 +129,8 @@ def test_modexp_different_base_lengths( tx: Transaction, post: Dict, modexp_input: ModExpInput, - modexp_expected: ModExpInput, + modexp_expected: ModExpOutput, + call_succeeds: bool, ) -> None: """Mainnet test for triggering gas cost increase.""" - state_test(pre=pre, tx=tx, post=post) + state_test(env=Environment(), pre=pre, tx=tx, post=post) From c4ff08599e088ac6aedc5116524df70d18410753 Mon Sep 17 00:00:00 2001 From: Felix H Date: Fri, 28 Nov 2025 14:04:34 +0000 Subject: [PATCH 3/9] fix: fix --- tests/byzantium/eip198_modexp_precompile/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/byzantium/eip198_modexp_precompile/helpers.py b/tests/byzantium/eip198_modexp_precompile/helpers.py index 09ce5a5444..5274d00778 100644 --- a/tests/byzantium/eip198_modexp_precompile/helpers.py +++ b/tests/byzantium/eip198_modexp_precompile/helpers.py @@ -160,7 +160,7 @@ class ModExpOutput(TestParameterGroup): """ - call_success: bool + call_success: bool = True returned_data: Bytes def __len__(self) -> int: From 8ea836715bc9278309ce4f32d6519b1b7856b279 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 2 Dec 2025 13:12:55 +0000 Subject: [PATCH 4/9] chore(test-tests): update mainnet marked tests for osaka --- .../test_eip_mainnet.py | 84 +++++++++---------- .../test_eip_mainnet.py | 66 ++++++++------- .../test_eip_mainnet.py | 10 +-- .../test_eip_mainnet.py | 23 ++--- .../test_eip_mainnet.py | 7 +- 5 files changed, 85 insertions(+), 105 deletions(-) diff --git a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py index 3a4b88a830..409e097cc5 100644 --- a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py +++ b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py @@ -1,5 +1,5 @@ """ -Mainnet marked tests for +Mainnet marked execute checklist tests for [EIP-7823: ModExp Upper Bound](https://eips.ethereum.org/EIPS/eip-7823). """ @@ -10,7 +10,6 @@ Alloc, StateTestFiller, Transaction, - # TransactionException, ) from execution_testing.base_types.base_types import Bytes from execution_testing.test_types.block_types import Environment @@ -19,6 +18,7 @@ ModExpInput, ModExpOutput, ) +from ..eip7883_modexp_gas_increase.spec import Spec from .spec import ref_spec_7823 REFERENCE_SPEC_GIT_PATH = ref_spec_7823.git_path @@ -27,78 +27,72 @@ pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] -# overwrite the conftest fixture @pytest.fixture def call_succeeds(modexp_expected: ModExpOutput) -> bool: - """Override call_succeeds to use the parametrized ModExpOutput value.""" + """Override `call_succeeds` to use the parametrized ModExpOutput value.""" return modexp_expected.call_success -# @pytest.mark.exception_test @pytest.mark.parametrize( "modexp_input,modexp_expected", [ pytest.param( ModExpInput( - base="ca" * 3070, - exponent="ca", - modulus="fe", - declared_base_length=3070, - declared_exponent_length=1, - declared_modulus_length=1, + base=b"\x01" * Spec.MAX_LENGTH_BYTES, + exponent=b"\x00", + modulus=b"\x02", ), ModExpOutput( - call_success=False, - returned_data=Bytes(), - ), - id="3070-bytes-long-base", - ), - pytest.param( - ModExpInput( - base="cd", - exponent="ca" * 3070, - modulus="dc", - declared_base_length=1, - declared_exponent_length=3070, - declared_modulus_length=1, - ), - ModExpOutput( - call_success=False, - returned_data=Bytes(), + call_success=True, + returned_data=Bytes(bytes.fromhex("01")), ), - id="3070-bytes-long-exp", + id="base-boundary-1024-bytes", ), + ], +) +def test_modexp_boundary( + state_test: StateTestFiller, + pre: Alloc, + tx: Transaction, + post: Dict, +) -> None: + """ + Mainnet test at the 1024-byte boundary. + + Tests that the ModExp precompile correctly handles input at the maximum + allowed length (1024 bytes) per EIP-7823. + """ + state_test(env=Environment(), pre=pre, tx=tx, post=post) + + +@pytest.mark.parametrize( + "modexp_input,modexp_expected", + [ pytest.param( ModExpInput( - base="cd", - exponent="cf", - modulus="ee" * 3070, - declared_base_length=1, - declared_exponent_length=1, - declared_modulus_length=3070, + base=b"\x01" * (Spec.MAX_LENGTH_BYTES + 1), + exponent=b"\x00", + modulus=b"\x02", ), ModExpOutput( call_success=False, returned_data=Bytes(), ), - id="3070-bytes-long-mod", + id="base-over-boundary-1025-bytes", ), ], ) -def test_modexp_different_base_lengths( +def test_modexp_over_boundary( state_test: StateTestFiller, pre: Alloc, tx: Transaction, post: Dict, - modexp_input: ModExpInput, - modexp_expected: ModExpOutput, - call_succeeds: bool, ) -> None: """ - Mainnet test for triggering gas cost increase. - Upper bound per length param: 1024 bytes - There are 3 length params: base, e, mod - 3*1024 = 3072 - Therefore, we can do negative tests for 3070+1+1 for each of those three. + Mainnet test exceeding the 1024-byte boundary. + + Tests that the ModExp precompile correctly rejects input exceeding the + maximum allowed length (1024 bytes) per EIP-7823. This proves the EIP + is correctly activated. """ state_test(env=Environment(), pre=pre, tx=tx, post=post) diff --git a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py index 7da68eebdc..eca85a9d27 100644 --- a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py +++ b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py @@ -1,65 +1,67 @@ """ -Mainnet tests for transaction gas limit cap [EIP-7825: Transaction Gas Limit -Cap](https://eips.ethereum.org/EIPS/eip-7825). +Mainnet marked execute checklist tests for +[EIP-7825: Transaction Gas Limit Cap](https://eips.ethereum.org/EIPS/eip-7825). """ import pytest from execution_testing import ( + Account, Alloc, Environment, Op, StateTestFiller, + Storage, Transaction, TransactionException, ) -from .spec import ref_spec_7825 +from .spec import Spec, ref_spec_7825 -# Update reference spec constants REFERENCE_SPEC_GIT_PATH = ref_spec_7825.git_path REFERENCE_SPEC_VERSION = ref_spec_7825.version pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] -@pytest.mark.exception_test -def test_tx_gas_limit_cap_mainnet( +def test_tx_gas_limit_cap_at_maximum( state_test: StateTestFiller, pre: Alloc, env: Environment, ) -> None: - """Negative test going beyond transaction gas limit cap.""" - target_gas_wasted_min = 2 ^ 24 + 1 + """Test transaction at exactly the gas limit cap (2^24).""" + storage = Storage() + contract_address = pre.deploy_contract( + code=Op.SSTORE(storage.store_next(1), 1) + Op.STOP, + ) - # repeatedly call BALANCE on different addresses until we detect - # that we used up target_gas_wasted_min - code = ( - Op.PUSH4[target_gas_wasted_min] - + Op.GAS - + Op.PUSH1[0x0] - + Op.JUMPDEST - + Op.DUP1 - + Op.BALANCE - + Op.POP - + Op.PUSH1[0x1] - + Op.ADD - + Op.GAS - + Op.DUP4 - + Op.SWAP1 - + Op.SUB - + Op.DUP4 - + Op.GT - + Op.PUSH1[0x8] - + Op.JUMPI - + Op.STOP + tx = Transaction( + to=contract_address, + sender=pre.fund_eoa(), + gas_limit=Spec.tx_gas_limit_cap, ) - caller_address = pre.deploy_contract(code=code) + post = { + contract_address: Account(storage=storage), + } + + state_test(env=env, pre=pre, post=post, tx=tx) + + +@pytest.mark.exception_test +def test_tx_gas_limit_cap_exceeded( + state_test: StateTestFiller, + pre: Alloc, + env: Environment, +) -> None: + """Test transaction exceeding the gas limit cap (2^24 + 1).""" + contract_address = pre.deploy_contract( + code=Op.SSTORE(0, 1) + Op.STOP, + ) tx = Transaction( - to=caller_address, + to=contract_address, sender=pre.fund_eoa(), - gas_limit=17_000_000, # more than target_gas_wasted_min + gas_limit=Spec.tx_gas_limit_cap + 1, error=TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM, ) diff --git a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py index 767fb34357..507743bb30 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py +++ b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py @@ -1,7 +1,5 @@ """ -Mainnet marked tests for EIP-7883 ModExp gas cost increase. - -Tests for ModExp gas cost increase in +Mainnet marked execute checklist tests for [EIP-7883: ModExp Gas Cost Increase](https://eips.ethereum.org/EIPS/eip-7883). """ @@ -28,10 +26,9 @@ pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] -# overwrite the conftest fixture @pytest.fixture def call_succeeds(modexp_expected: ModExpOutput) -> bool: - """Override call_succeeds to use the parametrized ModExpOutput value.""" + """Override `call_succeeds` to use the parametrized ModExpOutput value.""" return modexp_expected.call_success @@ -128,9 +125,6 @@ def test_modexp_different_base_lengths( pre: Alloc, tx: Transaction, post: Dict, - modexp_input: ModExpInput, - modexp_expected: ModExpOutput, - call_succeeds: bool, ) -> None: """Mainnet test for triggering gas cost increase.""" state_test(env=Environment(), pre=pre, tx=tx, post=post) diff --git a/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py b/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py index 759d199fa8..b6ec0dc564 100644 --- a/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py +++ b/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py @@ -1,5 +1,6 @@ """ -Mainnet testing for osaka's [EIP-7939: Count leading zeros (CLZ)](https://eips.ethereum.org/EIPS/eip-7939). +Mainnet marked execute checklist tests for +[EIP-7939: Count leading zeros (CLZ)](https://eips.ethereum.org/EIPS/eip-7939). """ import pytest @@ -20,29 +21,17 @@ pytestmark = [pytest.mark.valid_at("Osaka"), pytest.mark.mainnet] -# ruff keeps making parameters unreadable by putting them in one line -# fmt: off @pytest.mark.parametrize( "clz_input,clz_expected", [ pytest.param( - 2**256 - 1, - 0, - id="max-size-input-clz" - ), - pytest.param( - 0, - 256, - id="min-size-input-clz" - ), - pytest.param( - 1231350950569847740520874169721133058840016695, - 106, - id="some-other-input-clz" + 0x00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, + 8, + id="clz-8-leading-zeros", ), + pytest.param(0, 256, id="clz-all-zeros"), ], ) -# fmt: on def test_clz_mainnet( state_test: StateTestFiller, pre: Alloc, diff --git a/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py b/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py index 8b8d2fb7b1..90aaacf43a 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py +++ b/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py @@ -1,5 +1,6 @@ """ -Mainnet marked tests for [EIP-7951: Precompile for secp256r1 Curve Support](https://eips.ethereum.org/EIPS/eip-7951). +Mainnet marked execute checklist tests for +[EIP-7951: Precompile for secp256r1 Curve Support](https://eips.ethereum.org/EIPS/eip-7951). """ import pytest @@ -25,7 +26,7 @@ "input_data", [ pytest.param( - H( # 'hello world' r1 signed with privkey 0xd946578401d1980aba1fc85df2a1ddc0d2d618aadd37b213f7f7f91a553b1499 # noqa: E501 + H( # 'hello world' r1 signed with private key 0xd946578401d1980aba1fc85df2a1ddc0d2d618aadd37b213f7f7f91a553b1499 # noqa: E501 0xB94D27B9934D3E08A52E52D7DA7DABFAC484EFE37A5380EE9088F7ACE2EFCDE9 ) + R( @@ -59,7 +60,7 @@ def test_valid( "input_data", [ pytest.param( - H( # 'hello world' k1 signed (with eth prefix) with privkey 0xd946578401d1980aba1fc85df2a1ddc0d2d618aadd37b213f7f7f91a553b1499 # noqa: E501 + H( # 'hello world' k1 signed (with eth prefix) with private key 0xd946578401d1980aba1fc85df2a1ddc0d2d618aadd37b213f7f7f91a553b1499 # noqa: E501 0xD9EBA16ED0ECAE432B71FE008C98CC872BB4CC214D3220A36F365326CF807D68 ) + R( From 5d8aeff10ca4ac4bbfc2b7eca371d5b7c8fe1e31 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 2 Dec 2025 15:22:09 +0000 Subject: [PATCH 5/9] chore(test-types): add logging for rejected txs --- .../execution_testing/execution/transaction_post.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/execution_testing/execution/transaction_post.py b/packages/testing/src/execution_testing/execution/transaction_post.py index 32a340f9ac..182a535f9a 100644 --- a/packages/testing/src/execution_testing/execution/transaction_post.py +++ b/packages/testing/src/execution_testing/execution/transaction_post.py @@ -7,6 +7,7 @@ from execution_testing.base_types import Address, Alloc, Hash from execution_testing.forks import Fork +from execution_testing.logging import get_logger from execution_testing.rpc import ( EngineRPC, EthRPC, @@ -19,6 +20,8 @@ from .base import BaseExecute +logger = get_logger(__name__) + class TransactionPost(BaseExecute): """ @@ -86,8 +89,15 @@ def execute( eth_rpc.send_wait_transaction(transaction) all_tx_hashes.append(transaction.hash) else: - with pytest.raises(SendTransactionExceptionError): + logger.info( + f"Sending transaction expecting rejection " + f"(expected error: {transaction.error})..." + ) + with pytest.raises(SendTransactionExceptionError) as exc_info: eth_rpc.send_transaction(transaction) + logger.info( + f"Transaction rejected as expected: {exc_info.value}" + ) else: eth_rpc.send_wait_transactions(signed_txs) all_tx_hashes.extend([tx.hash for tx in signed_txs]) From d67495fa4a3079ce1fe8bace0d811f7314e35ea7 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Tue, 2 Dec 2025 15:24:19 +0000 Subject: [PATCH 6/9] chore: fix static tox ruff format ci fail --- .../src/execution_testing/execution/transaction_post.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/execution_testing/execution/transaction_post.py b/packages/testing/src/execution_testing/execution/transaction_post.py index 182a535f9a..59c9924906 100644 --- a/packages/testing/src/execution_testing/execution/transaction_post.py +++ b/packages/testing/src/execution_testing/execution/transaction_post.py @@ -93,7 +93,9 @@ def execute( f"Sending transaction expecting rejection " f"(expected error: {transaction.error})..." ) - with pytest.raises(SendTransactionExceptionError) as exc_info: + with pytest.raises( + SendTransactionExceptionError + ) as exc_info: eth_rpc.send_transaction(transaction) logger.info( f"Transaction rejected as expected: {exc_info.value}" From 71ecfd9f935576aa67b5235b2b02edacd3c29c71 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 3 Dec 2025 14:50:13 +0100 Subject: [PATCH 7/9] Apply suggestions from code review --- .../test_eip_mainnet.py | 10 ++++------ .../test_eip_mainnet.py | 9 ++++----- .../test_eip_mainnet.py | 20 ++++++++----------- .../test_eip_mainnet.py | 4 ++-- 4 files changed, 18 insertions(+), 25 deletions(-) diff --git a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py index 409e097cc5..e84bb20b27 100644 --- a/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py +++ b/tests/osaka/eip7823_modexp_upper_bounds/test_eip_mainnet.py @@ -11,8 +11,6 @@ StateTestFiller, Transaction, ) -from execution_testing.base_types.base_types import Bytes -from execution_testing.test_types.block_types import Environment from ...byzantium.eip198_modexp_precompile.helpers import ( ModExpInput, @@ -44,7 +42,7 @@ def call_succeeds(modexp_expected: ModExpOutput) -> bool: ), ModExpOutput( call_success=True, - returned_data=Bytes(bytes.fromhex("01")), + returned_data="0x01", ), id="base-boundary-1024-bytes", ), @@ -62,7 +60,7 @@ def test_modexp_boundary( Tests that the ModExp precompile correctly handles input at the maximum allowed length (1024 bytes) per EIP-7823. """ - state_test(env=Environment(), pre=pre, tx=tx, post=post) + state_test(pre=pre, tx=tx, post=post) @pytest.mark.parametrize( @@ -76,7 +74,7 @@ def test_modexp_boundary( ), ModExpOutput( call_success=False, - returned_data=Bytes(), + returned_data="", ), id="base-over-boundary-1025-bytes", ), @@ -95,4 +93,4 @@ def test_modexp_over_boundary( maximum allowed length (1024 bytes) per EIP-7823. This proves the EIP is correctly activated. """ - state_test(env=Environment(), pre=pre, tx=tx, post=post) + state_test(pre=pre, tx=tx, post=post) diff --git a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py index eca85a9d27..967db84939 100644 --- a/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py +++ b/tests/osaka/eip7825_transaction_gas_limit_cap/test_eip_mainnet.py @@ -7,7 +7,6 @@ from execution_testing import ( Account, Alloc, - Environment, Op, StateTestFiller, Storage, @@ -26,7 +25,6 @@ def test_tx_gas_limit_cap_at_maximum( state_test: StateTestFiller, pre: Alloc, - env: Environment, ) -> None: """Test transaction at exactly the gas limit cap (2^24).""" storage = Storage() @@ -35,6 +33,7 @@ def test_tx_gas_limit_cap_at_maximum( ) tx = Transaction( + ty=0x02, to=contract_address, sender=pre.fund_eoa(), gas_limit=Spec.tx_gas_limit_cap, @@ -44,14 +43,13 @@ def test_tx_gas_limit_cap_at_maximum( contract_address: Account(storage=storage), } - state_test(env=env, pre=pre, post=post, tx=tx) + state_test(pre=pre, post=post, tx=tx) @pytest.mark.exception_test def test_tx_gas_limit_cap_exceeded( state_test: StateTestFiller, pre: Alloc, - env: Environment, ) -> None: """Test transaction exceeding the gas limit cap (2^24 + 1).""" contract_address = pre.deploy_contract( @@ -59,10 +57,11 @@ def test_tx_gas_limit_cap_exceeded( ) tx = Transaction( + ty=0x02, to=contract_address, sender=pre.fund_eoa(), gas_limit=Spec.tx_gas_limit_cap + 1, error=TransactionException.GAS_LIMIT_EXCEEDS_MAXIMUM, ) - state_test(env=env, pre=pre, post={}, tx=tx) + state_test(pre=pre, post={}, tx=tx) diff --git a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py index 507743bb30..d962eff196 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py +++ b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py @@ -46,7 +46,7 @@ def call_succeeds(modexp_expected: ModExpOutput) -> bool: ), ModExpOutput( call_success=True, - returned_data=Bytes(bytes.fromhex("04")), + returned_data="0x04", ), id="32-bytes-long-base", ), @@ -61,7 +61,7 @@ def call_succeeds(modexp_expected: ModExpOutput) -> bool: ), ModExpOutput( call_success=True, - returned_data=Bytes(bytes.fromhex("01")), + returned_data="0x01", ), id="33-bytes-long-base", # higher cost than 32 bytes ), @@ -76,7 +76,7 @@ def call_succeeds(modexp_expected: ModExpOutput) -> bool: ), ModExpOutput( call_success=True, - returned_data=Bytes(bytes.fromhex("02")), + returned_data="0x02", ), id="1024-bytes-long-exp", ), @@ -91,10 +91,8 @@ def call_succeeds(modexp_expected: ModExpOutput) -> bool: ), ModExpOutput( call_success=True, - returned_data=Bytes( - bytes.fromhex( - "c36d804180c35d4426b57b50c5bfcca5c01856d104564cd513b461d3c8b8409128a5573e416d0ebe38f5f736766d9dc27143e4da981dfa4d67f7dc474cbee6d2" - ) + returned_data=( + "0xc36d804180c35d4426b57b50c5bfcca5c01856d104564cd513b461d3c8b8409128a5573e416d0ebe38f5f736766d9dc27143e4da981dfa4d67f7dc474cbee6d2" ), ), id="nagydani-1-pow0x10001", @@ -110,10 +108,8 @@ def call_succeeds(modexp_expected: ModExpOutput) -> bool: ), ModExpOutput( call_success=True, - returned_data=Bytes( - bytes.fromhex( - "0000000000000000000000000000000000000000000000000000000000000001" - ) + returned_data=( + "0x0000000000000000000000000000000000000000000000000000000000000001" ), ), id="zero-exponent-64bytes", @@ -127,4 +123,4 @@ def test_modexp_different_base_lengths( post: Dict, ) -> None: """Mainnet test for triggering gas cost increase.""" - state_test(env=Environment(), pre=pre, tx=tx, post=post) + state_test(pre=pre, tx=tx, post=post) diff --git a/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py b/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py index b6ec0dc564..517ff16be2 100644 --- a/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py +++ b/tests/osaka/eip7939_count_leading_zeros/test_eip_mainnet.py @@ -11,7 +11,6 @@ StateTestFiller, Transaction, ) -from execution_testing.test_types.block_types import Environment from .spec import ref_spec_7939 @@ -47,6 +46,7 @@ def test_clz_mainnet( storage={"0x00": "0xdeadbeef"}, ) tx = Transaction( + ty=0x02, to=contract_address, sender=sender, gas_limit=200_000, @@ -54,4 +54,4 @@ def test_clz_mainnet( post = { contract_address: Account(storage={"0x00": clz_expected}), } - state_test(env=Environment(), pre=pre, post=post, tx=tx) + state_test(pre=pre, post=post, tx=tx) From e10409a1bbdefafdc53f9d1ecdb8a261f623b712 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 3 Dec 2025 14:08:37 +0000 Subject: [PATCH 8/9] fix(tests): Change all mainnet osaka tests to ty-2 tx --- tests/osaka/eip7823_modexp_upper_bounds/conftest.py | 1 + tests/osaka/eip7883_modexp_gas_increase/conftest.py | 1 + .../eip7883_modexp_gas_increase/test_eip_mainnet.py | 2 -- .../osaka/eip7951_p256verify_precompiles/conftest.py | 1 + .../test_eip_mainnet.py | 11 +++-------- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/tests/osaka/eip7823_modexp_upper_bounds/conftest.py b/tests/osaka/eip7823_modexp_upper_bounds/conftest.py index 314421a074..f9528d8e92 100644 --- a/tests/osaka/eip7823_modexp_upper_bounds/conftest.py +++ b/tests/osaka/eip7823_modexp_upper_bounds/conftest.py @@ -168,6 +168,7 @@ def tx( ) -> Transaction: """Transaction to measure gas consumption of the ModExp precompile.""" return Transaction( + ty=0x02, sender=pre.fund_eoa(), to=gas_measure_contract, data=bytes(modexp_input), diff --git a/tests/osaka/eip7883_modexp_gas_increase/conftest.py b/tests/osaka/eip7883_modexp_gas_increase/conftest.py index 319c234c23..bdfd6f055d 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/conftest.py +++ b/tests/osaka/eip7883_modexp_gas_increase/conftest.py @@ -259,6 +259,7 @@ def tx( ) -> Transaction: """Transaction to measure gas consumption of the ModExp precompile.""" return Transaction( + ty=0x02, sender=pre.fund_eoa(), to=gas_measure_contract, data=bytes(modexp_input), diff --git a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py index d962eff196..3f80c12d2a 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py +++ b/tests/osaka/eip7883_modexp_gas_increase/test_eip_mainnet.py @@ -11,8 +11,6 @@ StateTestFiller, Transaction, ) -from execution_testing.base_types.base_types import Bytes -from execution_testing.test_types.block_types import Environment from ...byzantium.eip198_modexp_precompile.helpers import ( ModExpInput, diff --git a/tests/osaka/eip7951_p256verify_precompiles/conftest.py b/tests/osaka/eip7951_p256verify_precompiles/conftest.py index 5c8b28b6bb..f42b987adb 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/conftest.py +++ b/tests/osaka/eip7951_p256verify_precompiles/conftest.py @@ -177,6 +177,7 @@ def tx( ) -> Transaction: """Transaction for the test.""" return Transaction( + ty=0x02, gas_limit=tx_gas_limit, data=input_data, to=call_contract_address, diff --git a/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py b/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py index 90aaacf43a..4aaf2b4166 100644 --- a/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py +++ b/tests/osaka/eip7951_p256verify_precompiles/test_eip_mainnet.py @@ -4,12 +4,7 @@ """ import pytest -from execution_testing import ( - Alloc, - Environment, - StateTestFiller, - Transaction, -) +from execution_testing import Alloc, StateTestFiller, Transaction from .spec import H, R, S, Spec, X, Y, ref_spec_7951 @@ -50,7 +45,7 @@ def test_valid( state_test: StateTestFiller, pre: Alloc, post: dict, tx: Transaction ) -> None: """Positive mainnet test for the P256VERIFY precompile.""" - state_test(env=Environment(), pre=pre, post=post, tx=tx) + state_test(pre=pre, post=post, tx=tx) @pytest.mark.parametrize( @@ -89,4 +84,4 @@ def test_invalid( The signature actually is a valid secp256k1 signature, so this is an interesting test case. """ - state_test(env=Environment(), pre=pre, post=post, tx=tx) + state_test(pre=pre, post=post, tx=tx) From 0ed610316537a98773517df8708306c979f212b1 Mon Sep 17 00:00:00 2001 From: Mario Vega Date: Wed, 3 Dec 2025 16:33:28 +0000 Subject: [PATCH 9/9] fix(tests): Fix EIP-7883 tests --- tests/osaka/eip7883_modexp_gas_increase/conftest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/osaka/eip7883_modexp_gas_increase/conftest.py b/tests/osaka/eip7883_modexp_gas_increase/conftest.py index bdfd6f055d..0f1114eeab 100644 --- a/tests/osaka/eip7883_modexp_gas_increase/conftest.py +++ b/tests/osaka/eip7883_modexp_gas_increase/conftest.py @@ -15,7 +15,7 @@ Transaction, keccak256, ) -from execution_testing.forks import Osaka +from execution_testing.forks import London, Osaka from ...byzantium.eip198_modexp_precompile.helpers import ModExpInput from .spec import Spec, Spec7883 @@ -252,6 +252,7 @@ def precompile_gas_modifier() -> int: @pytest.fixture def tx( + fork: Fork, pre: Alloc, gas_measure_contract: Address, modexp_input: ModExpInput, @@ -259,7 +260,7 @@ def tx( ) -> Transaction: """Transaction to measure gas consumption of the ModExp precompile.""" return Transaction( - ty=0x02, + ty=0x02 if fork >= London else 0x00, sender=pre.fund_eoa(), to=gas_measure_contract, data=bytes(modexp_input),