Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/configs/feature.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ monad_runloop:
evm-type: eels
# Like `monad`, but `--monad-runloop` and eestnet chain id `30143`
fill-params: -m blockchain_test --from=MONAD_EIGHT --until=MONAD_TEN --chain-id=30143 --monad-runloop -k "not invalid_header"

monad_eip7997:
evm-type: eels
fill-params: -m blockchain_test --fork=MONAD_NEXT --chain-id=143 -k "not invalid_header"
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,9 @@ def _process_with_marker_args(
"Missing fork argument with 'valid_at_transition_to' marker."
)

if len(forks) > 1:
# A single EIP argument expands to one fork per enabling fork, so
# the limit is on the arguments rather than on the resolved forks.
if len(fork_args) > 1:
raise Exception(
"Too many forks specified to 'valid_at_transition_to' marker."
)
Expand Down
30 changes: 27 additions & 3 deletions packages/testing/src/execution_testing/forks/base_fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,25 @@ def _maybe_transitioned(fork_cls: "BaseForkMeta") -> "BaseForkMeta":
@staticmethod
def _is_subclass_of(a: "BaseForkMeta", b: "BaseForkMeta") -> bool:
"""
Check if `a` is a subclass of `b`, taking fork transitions into
account.
Check if `a` is a subclass of `b`, taking fork transitions and
declared succession into account.

A fork can follow another fork it does not inherit from, which
places it after that fork (and after everything that fork comes
after) in the fork order without adopting its behavior.
"""
a = BaseForkMeta._maybe_transitioned(a)
b = BaseForkMeta._maybe_transitioned(b)
return issubclass(a, b)
if issubclass(a, b):
return True
# The metaclass sees its instances as plain classes, so the
# trait is reached through a cast, as elsewhere in this class.
followed = cast(Type["BaseFork"], a).follows()
while followed is not None:
if issubclass(followed, b):
return True
followed = followed.follows()
return False

def __gt__(cls, other: "BaseForkMeta") -> bool:
"""Compare if a fork is newer than some other fork (cls > other)."""
Expand Down Expand Up @@ -1407,6 +1420,17 @@ def enabling_forks(cls) -> Set[Type["BaseFork"]]:
raise Exception(f"Class {cls.__name__} is not an EIP.")
return cls._enabling_forks

@classmethod
def follows(cls) -> Type["BaseFork"] | None:
"""
Return the fork this one comes after without inheriting it.

A fork that reuses another lineage's ordering overrides this;
comparisons then place it after that fork, and after everything
that fork comes after, while its behavior stays its own.
"""
return None

@classmethod
def parent(cls) -> Type["BaseFork"] | None:
"""Return the parent fork."""
Expand Down
27 changes: 21 additions & 6 deletions packages/testing/src/execution_testing/forks/forks/forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1805,12 +1805,6 @@ def _calculate_sstore_gas_mip8(
return gas_cost


class MONAD_NEXT(MONAD_TEN): # noqa: N801
"""MONAD_NEXT fork, a placeholder identical to MONAD_TEN."""

pass


class BPO1(
Osaka,
bpo_fork=True,
Expand Down Expand Up @@ -1904,3 +1898,24 @@ def engine_payload_attribute_target_gas_limit(cls) -> bool:
limit.
"""
return True


class MONAD_NEXT( # noqa: N801
eips.EIP7997,
MONAD_TEN,
):
"""
MONAD_NEXT fork.

Amsterdam-based successor to MONAD_TEN, adopting the EIP-7997
changes. The Amsterdam changes it does not adopt stay out of the
fork by not being inherited at all; the fork order still places
MONAD_NEXT after Amsterdam through `follows`.
"""

@classmethod
def follows(cls) -> type[BaseFork] | None:
"""MONAD_NEXT comes after Amsterdam without inheriting it."""
return Amsterdam

pass
10 changes: 10 additions & 0 deletions tests/amsterdam/eip2780_reduce_intrinsic_tx_gas/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-2780 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
10 changes: 10 additions & 0 deletions tests/amsterdam/eip7708_eth_transfer_logs/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-7708 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-7778 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
10 changes: 10 additions & 0 deletions tests/amsterdam/eip7843_slotnum/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-7843 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
10 changes: 10 additions & 0 deletions tests/amsterdam/eip7928_block_level_access_lists/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-7928 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
Original file line number Diff line number Diff line change
Expand Up @@ -370,3 +370,10 @@ def tx(
blob_versioned_hashes=blob_versioned_hashes,
error=tx_error,
)


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
compute_create2_address,
keccak256,
)
from execution_testing.forks import MONAD_EIGHT

from ...prague.eip7702_set_code_tx.spec import Spec as Spec7702
from .spec import Spec, ref_spec_7997
Expand Down Expand Up @@ -538,6 +539,7 @@ def test_factory_receives_balance_via_selfdestruct(
def test_factory_via_eip7702_delegation(
state_test: StateTestFiller,
pre: Alloc,
fork: Fork,
) -> None:
"""
An EOA delegates its code to the factory via an EIP-7702
Expand All @@ -549,6 +551,10 @@ def test_factory_via_eip7702_delegation(
auth_signer = pre.fund_eoa()
auth_signer_nonce = auth_signer.nonce

# Monad forbids the `CREATE2` of a delegated account's context, so
# the factory reverts there instead of deploying.
factory_reverts = fork >= MONAD_EIGHT

salt = 0x42
runtime_code = Op.PUSH1(0x01) + Op.PUSH1(0x00) + Op.RETURN
initcode = Initcode(deploy_code=runtime_code)
Expand Down Expand Up @@ -586,10 +592,12 @@ def test_factory_via_eip7702_delegation(
),
post={
auth_signer: Account(
nonce=auth_signer_nonce + 2,
nonce=auth_signer_nonce + (1 if factory_reverts else 2),
code=Spec7702.delegation_designation(Address(FACTORY)),
),
expected_address: Account(nonce=1, code=bytes(runtime_code)),
expected_address: Account.NONEXISTENT
if factory_reverts
else Account(nonce=1, code=bytes(runtime_code)),
FACTORY: Account(
nonce=1,
balance=0,
Expand Down
10 changes: 10 additions & 0 deletions tests/amsterdam/eip8024_dupn_swapn_exchange/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-8024 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-8037 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-8038 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
7 changes: 7 additions & 0 deletions tests/amsterdam/eip8070_sparse_blobpool/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,10 @@ def txs(
)
txs.append(network_wrapped_tx)
return txs


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
10 changes: 10 additions & 0 deletions tests/amsterdam/eip8246_selfdestruct_no_burn/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""Pytest (plugin) definitions local to EIP-8246 tests."""

import pytest


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
"""Fixtures for the EIP-8282 builder execution request tests."""

import pytest

from ...common.system_contract_request_fixtures import (
blocks, # noqa: F401
included_requests, # noqa: F401
system_contract_interactions_per_block_copy, # noqa: F401
timestamp, # noqa: F401
)


def pytest_generate_tests(metafunc: pytest.Metafunc) -> None:
"""Mark all tests in this subdir as not valid for Monad forks."""
metafunc.definition.add_marker(
pytest.mark.not_valid_for("MONAD_EIGHT", subsequent_forks=True)
)