Skip to content
Open
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
2 changes: 1 addition & 1 deletion docs/filling_tests/filling_tests_dev_fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ just binary-trie-fork [paths]

A bare invocation fills only the scoped `tests/binary_tree` suite; `just binary-trie-fork tests` instead reinterprets the entire `tests/` tree against `BinaryTree`.

When porting existing tests: `valid_from(...)` markers select `BinaryTree` (it subclasses `Amsterdam`), but `valid_at(...)` silently does not, so a handful of `valid_at`-pinned tests are invisible to the port with no warning at collection time.
When porting existing tests: `valid_from(...)` markers select `BinaryTree` (it subclasses `Amsterdam`), and `valid_at(...)` markers naming `Amsterdam` — or an EIP that resolves to it — select it too, because the fork is declared with `inherits_exact_fork_validity=True` (it keeps Amsterdam's execution semantics). Tests pinned to earlier forks (e.g. `valid_at("Prague")`) remain excluded, as do `valid_at_transition_to(...)` tests: no transition fork to `BinaryTree` exists.

## Further Help

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1092,6 +1092,34 @@ def _process_with_marker_args(
return resulting_set


def expand_forks_with_inherited_validity(
forks: Set[Fork | TransitionFork],
) -> Set[Fork | TransitionFork]:
"""
Add every fork that declares `inherits_exact_fork_validity` and
whose parent is in `forks` (transitively, so a chain of such forks
is followed).

This lets a development fork that keeps its parent's semantics,
such as `BinaryTree` over `Amsterdam`, run tests pinned to the
parent with `valid_at`, without naming the development fork in
every marker.
"""
expanded = set(forks)
changed = True
while changed:
changed = False
for fork in ALL_FORKS:
if fork in expanded:
continue
if not fork.inherits_exact_fork_validity():
continue
if fork.parent() in expanded:
expanded.add(fork)
changed = True
return expanded


class ValidAt(ValidityMarker):
"""
Marker to specify each fork individually for which the test is valid.
Expand All @@ -1111,13 +1139,20 @@ def test_something_only_valid_at_london_and_cancun(

In this example, the test will only be filled for the London and Cancun
forks.

A development fork declared with `inherits_exact_fork_validity=True`
is additionally selected wherever its parent fork is: `BinaryTree`
keeps Amsterdam's execution semantics, so `valid_at("Amsterdam")`
(or an EIP name resolving to Amsterdam) also selects `BinaryTree`.
"""

def _process_with_marker_args(
self, *fork_args: str
) -> Set[Fork | TransitionFork]:
"""Process the fork arguments."""
return self.process_fork_arguments(*fork_args)
return expand_forks_with_inherited_validity(
self.process_fork_arguments(*fork_args)
)


class ValidAtTransitionTo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,46 @@ def test_case(state_test):
{"passed": 3, "failed": 0, "skipped": 0, "errors": 0},
id="valid_from_until",
),
pytest.param(
generate_test(
valid_at='"London", "Cancun"',
),
[],
{"passed": 2, "failed": 0, "skipped": 0, "errors": 0},
id="valid_at",
),
pytest.param(
generate_test(
valid_at='"Amsterdam"',
),
["--fork=BinaryTree"],
# BinaryTree is declared with
# `inherits_exact_fork_validity=True`, so a test pinned to
# its parent Amsterdam also fills for it.
{"passed": 1, "failed": 0, "skipped": 0, "errors": 0},
id="valid_at_dev_fork_inherits_validity",
),
pytest.param(
generate_test(
valid_at='"EIP7981"',
),
["--fork=BinaryTree"],
# The EIP name resolves to Amsterdam, which BinaryTree
# inherits exact-fork validity from.
{"passed": 1, "failed": 0, "skipped": 0, "errors": 0},
id="valid_at_eip_dev_fork_inherits_validity",
),
pytest.param(
generate_test(
valid_at='"Cancun"',
),
["--fork=BinaryTree"],
# Inheritance follows the parent link only: BinaryTree's
# parent is Amsterdam, so a test pinned to an older fork
# stays excluded.
{"passed": 0, "failed": 0, "skipped": 0, "errors": 0},
id="valid_at_dev_fork_older_fork_excluded",
),
pytest.param(
generate_test(
valid_from='"EIP3675"',
Expand Down
15 changes: 15 additions & 0 deletions packages/testing/src/execution_testing/forks/base_fork.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ class BaseFork(ForkOpcodeInterface, metaclass=BaseForkMeta):
_fork_by_timestamp: ClassVar[bool] = False
_blob_constants: ClassVar[Dict[str, int]] = {}
_deployed: ClassVar[bool] = True
_inherits_exact_fork_validity: ClassVar[bool] = False
_enabled_eips: ClassVar[Set[int]] = set()
_enabling_forks: ClassVar[Set[Type["BaseFork"]]] = set()

Expand All @@ -362,6 +363,7 @@ def __init_subclass__(
ruleset_name: Optional[str] = None,
fork_by_timestamp: Optional[bool] = None,
deployed: Optional[bool] = None,
inherits_exact_fork_validity: bool = False,
update_blob_constants: Optional[Dict[str, int]] = None,
engine_new_payload_version_bump: Optional[bool] = None,
engine_forkchoice_updated_version_bump: Optional[bool] = None,
Expand All @@ -376,6 +378,7 @@ def __init_subclass__(
cls._solc_name = solc_name
cls._ignore = ignore
cls._bpo_fork = bpo_fork
cls._inherits_exact_fork_validity = inherits_exact_fork_validity
cls._ruleset_name = ruleset_name
cls._children = set()
if fork_by_timestamp is None:
Expand Down Expand Up @@ -1324,6 +1327,18 @@ def ignore(cls) -> bool:
"""Return whether the fork should be ignored during test generation."""
return cls._ignore

@classmethod
def inherits_exact_fork_validity(cls) -> bool:
"""
Return whether markers that name this fork's parent exactly
(`valid_at`) also select this fork.

Declared per fork with the `inherits_exact_fork_validity` class
argument; meant for development forks that keep their parent's
semantics, so tests pinned to the parent remain meaningful.
"""
return cls._inherits_exact_fork_validity

@classmethod
def bpo_fork(cls) -> bool:
"""Return whether the fork is a BPO fork."""
Expand Down
5 changes: 5 additions & 0 deletions packages/testing/src/execution_testing/forks/forks/forks.py
Original file line number Diff line number Diff line change
Expand Up @@ -1654,12 +1654,17 @@ class Amsterdam(
class BinaryTree(
Amsterdam,
deployed=False,
inherits_exact_fork_validity=True,
):
"""
Experimental EIP-8297 fork: state is committed through the
Partitioned Binary Tree instead of the Merkle Patricia Trie.
For testing purposes only. The commitment scheme is selected by
the spec fork's own imports; the transition tool reflects it.

The fork keeps Amsterdam's execution semantics, so it inherits
exact-fork validity: tests pinned to Amsterdam with `valid_at`
also run here.
"""

pass
Loading