From a5cea903fe62f77bb1c13c35cda7fff2507c0b14 Mon Sep 17 00:00:00 2001 From: spencer-tb Date: Thu, 4 Jun 2026 12:48:00 +0100 Subject: [PATCH] chore(test-forks): include sibling BPO forks in `--until` ranges --- .../src/execution_testing/forks/helpers.py | 35 +++++++++++++ .../forks/tests/test_forks.py | 50 +++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/packages/testing/src/execution_testing/forks/helpers.py b/packages/testing/src/execution_testing/forks/helpers.py index 9a08b50ea52..7408be96afd 100644 --- a/packages/testing/src/execution_testing/forks/helpers.py +++ b/packages/testing/src/execution_testing/forks/helpers.py @@ -195,6 +195,38 @@ def get_last_descendants( return resulting_forks +def get_bpo_sibling_forks( + forks: Set[Type[BaseFork]] | FrozenSet[Type[BaseFork]], + forks_from: Set[Type[BaseFork]], + forks_until: Set[Type[BaseFork]], +) -> Set[Type[BaseFork]]: + """ + Return BPO forks that branch off an ancestor of an `--until` fork. + + BPO (Blob Parameter Only) forks form a chain hanging off the fork + they extend (e.g. the `BPO3`/`BPO4`/`BPO5` chain branches off `BPO2`). + A later fork such as `Amsterdam` descends from that same `BPO2` on a + parallel branch, so an ancestry-based `--until=Amsterdam` range never + reaches the BPO chain. Return those siblings, bounded below by + `forks_from`, so filling until such a fork still exercises the + blob-parameter paths the BPO forks cover. + """ + siblings: Set[Type[BaseFork]] = set() + for fork_until in forks_until: + if issubclass(fork_until, TransitionBaseClass): + continue + for fork in forks: + if not fork.bpo_fork(): + continue + if fork <= fork_until or fork >= fork_until: + continue + if fork.non_bpo_ancestor() <= fork_until and any( + fork >= fork_from for fork_from in forks_from + ): + siblings.add(fork) + return siblings + + def get_selected_fork_set( *, single_fork: Set[Type[BaseFork]], @@ -225,6 +257,9 @@ def get_selected_fork_set( for fork_until in forks_until: if issubclass(fork_until, TransitionBaseClass): selected_fork_set.discard(fork_until.transitions_to()) + selected_fork_set |= get_bpo_sibling_forks( + ALL_FORKS, forks_from, forks_until + ) selected_fork_set_with_transitions: Set[ Type[BaseFork | TransitionBaseClass] ] = set() | selected_fork_set diff --git a/packages/testing/src/execution_testing/forks/tests/test_forks.py b/packages/testing/src/execution_testing/forks/tests/test_forks.py index 8d9cec7882c..1e72440d347 100644 --- a/packages/testing/src/execution_testing/forks/tests/test_forks.py +++ b/packages/testing/src/execution_testing/forks/tests/test_forks.py @@ -13,6 +13,7 @@ BPO2, BPO3, BPO4, + BPO5, Amsterdam, Berlin, Cancun, @@ -682,6 +683,55 @@ def test_transition_from_normal_until(self) -> None: assert BPO1ToBPO2AtTime15k in result assert BPO2ToAmsterdamAtTime15k not in result + def test_until_amsterdam_includes_bpo_siblings(self) -> None: + """`--until=Amsterdam` pulls in the parallel BPO branch.""" + result = get_selected_fork_set( + single_fork=set(), + forks_from=set(), + forks_until={Amsterdam}, + ) + normal = self._normal_forks(result) + assert {BPO1, BPO2, BPO3, BPO4, BPO5, Amsterdam} <= normal + assert BPO2ToBPO3AtTime15k in result + assert BPO3ToBPO4AtTime15k in result + + def test_from_osaka_until_amsterdam_spans_bpo_branch(self) -> None: + """`--from=Osaka --until=Amsterdam` spans the full BPO branch.""" + result = get_selected_fork_set( + single_fork=set(), + forks_from={Osaka}, + forks_until={Amsterdam}, + ) + assert self._normal_forks(result) == { + Osaka, + BPO1, + BPO2, + BPO3, + BPO4, + BPO5, + Amsterdam, + } + + def test_until_bpo2_excludes_later_bpo_siblings(self) -> None: + """`--until=BPO2` must not pull in the later BPO branch.""" + result = get_selected_fork_set( + single_fork=set(), + forks_from=set(), + forks_until={BPO2}, + ) + normal = self._normal_forks(result) + assert {BPO1, BPO2} <= normal + assert not ({BPO3, BPO4, BPO5} & normal) + + def test_from_amsterdam_until_amsterdam_excludes_bpos(self) -> None: + """`--from=Amsterdam --until=Amsterdam` stays Amsterdam-only.""" + result = get_selected_fork_set( + single_fork=set(), + forks_from={Amsterdam}, + forks_until={Amsterdam}, + ) + assert self._normal_forks(result) == {Amsterdam} + def test_blob_constants() -> None: # noqa: D103 assert Osaka.get_blob_constant("AMOUNT_CELL_PROOFS") == 128