From 6bd1efc73bf45ae5658e115a8b2956144d4f4559 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 8 Mar 2021 17:16:13 -0700 Subject: [PATCH 01/14] rename fork files --- setup.py | 4 ++-- specs/lightclient/{lightclient-fork.md => fork.md} | 0 specs/phase1/{phase1-fork.md => fork.md} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename specs/lightclient/{lightclient-fork.md => fork.md} (100%) rename specs/phase1/{phase1-fork.md => fork.md} (100%) diff --git a/setup.py b/setup.py index 6cfa0910a..ca85a83ac 100644 --- a/setup.py +++ b/setup.py @@ -449,7 +449,7 @@ class PySpecCommand(Command): specs/phase1/beacon-chain.md specs/phase1/shard-transition.md specs/phase1/fork-choice.md - specs/phase1/phase1-fork.md + specs/phase1/fork.md specs/phase1/shard-fork-choice.md specs/phase1/validator.md """ @@ -460,7 +460,7 @@ class PySpecCommand(Command): specs/phase0/validator.md specs/phase0/weak-subjectivity.md specs/lightclient/beacon-chain.md - specs/lightclient/lightclient-fork.md + specs/lightclient/fork.md """ # TODO: add specs/lightclient/sync-protocol.md back when the GeneralizedIndex helpers are included. else: diff --git a/specs/lightclient/lightclient-fork.md b/specs/lightclient/fork.md similarity index 100% rename from specs/lightclient/lightclient-fork.md rename to specs/lightclient/fork.md diff --git a/specs/phase1/phase1-fork.md b/specs/phase1/fork.md similarity index 100% rename from specs/phase1/phase1-fork.md rename to specs/phase1/fork.md From d6961f636de17b31ecb3350b0a5710a1d102d669 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 8 Mar 2021 17:16:29 -0700 Subject: [PATCH 02/14] add base hf1 fork function tests --- tests/core/pyspec/eth2spec/test/context.py | 10 +- .../test/lightclient_patch/fork/test_fork.py | 104 ++++++++++++++++++ 2 files changed, 108 insertions(+), 6 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 5c2a3bf4d..3f247b400 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -346,13 +346,11 @@ def with_phases(phases, other_phases=None): # A new state-creation helper for phase 1 may be in place, and then phase1+ tests can run without phase0 available_phases.add(PHASE0) + # Populate all phases for multi-phase tests phase_dir = {} - if PHASE0 in available_phases: - phase_dir[PHASE0] = spec_phase0 - if PHASE1 in available_phases: - phase_dir[PHASE1] = spec_phase1 - if LIGHTCLIENT_PATCH in available_phases: - phase_dir[LIGHTCLIENT_PATCH] = spec_lightclient_patch + phase_dir[PHASE0] = spec_phase0 + phase_dir[PHASE1] = spec_phase1 + phase_dir[LIGHTCLIENT_PATCH] = spec_lightclient_patch # return is ignored whenever multiple phases are ran. If if PHASE0 in run_phases: diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py new file mode 100644 index 000000000..08c6e6d29 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -0,0 +1,104 @@ +from operator import attrgetter + +from eth2spec.test.context import ( + PHASE0, LIGHTCLIENT_PATCH, + spec_state_test, with_phases, + with_custom_state, + spec_test, with_state, + low_balances, misc_balances, large_validator_set, +) +from eth2spec.test.helpers.state import ( + next_slots, + next_epoch, + next_epoch_via_block, + transition_to_slot_via_block, +) + + +def run_fork_test(spec, pre_state): + yield 'pre', pre_state + + post_state = spec.upgrade_to_lightclient_patch(pre_state) + + # Stable fields + stable_fields = [ + 'genesis_time', 'genesis_validators_root', 'slot', + # History + 'latest_block_header', 'block_roots', 'state_roots', 'historical_roots', + # Eth1 + 'eth1_data', 'eth1_data_votes', 'eth1_deposit_index', + # Registry + 'validators', 'balances', + # Randomness + 'randao_mixes', + # Slashings + 'slashings', + # Finality + 'justification_bits', 'previous_justified_checkpoint', 'current_justified_checkpoint', 'finalized_checkpoint', + ] + for field in stable_fields: + assert getattr(pre_state, field) == getattr(post_state, field) + + # Modified fields + modified_fields = ['fork'] + for field in modified_fields: + assert getattr(pre_state, field) != getattr(post_state, field) + + assert pre_state.fork.current_version == post_state.fork.previous_version + assert post_state.fork.current_version == spec.LIGHTCLIENT_PATCH_FORK_VERSION + assert post_state.fork.epoch == spec.get_current_epoch(post_state) + + yield 'post', post_state + + +@with_phases(([PHASE0])) +@with_state +@spec_test +def test_fork_base_state(spec, phases, state): + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) + + +@with_phases(([PHASE0])) +@with_state +@spec_test +def test_fork_next_epoch(spec, phases, state): + next_epoch(spec, state) + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) + + +@with_phases(([PHASE0])) +@with_state +@spec_test +def test_fork_next_epoch_with_block(spec, phases, state): + next_epoch_via_block(spec, state) + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) + + +@with_phases(([PHASE0])) +@with_state +@spec_test +def test_fork_many_next_epoch(spec, phases, state): + for _ in range(3): + next_epoch(spec, state) + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) + + +@with_phases(([PHASE0])) +@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) +@spec_test +def test_fork_random_low_balances(spec, phases, state): + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) + + +@with_phases(([PHASE0])) +@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) +@spec_test +def test_fork_random_misc_balances(spec, phases, state): + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) + + +@with_phases(([PHASE0])) +@with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) +@spec_test +def test_fork_random_large_validator_set(spec, phases, state): + yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) From 6c406753f150563cac1253cfef8d99d9111bd906 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 8 Mar 2021 19:11:31 -0700 Subject: [PATCH 03/14] working through test gens --- tests/core/pyspec/eth2spec/test/context.py | 18 +++++-- .../test/lightclient_patch/fork/__init__.py | 0 .../test/lightclient_patch/fork/test_fork.py | 44 +++++++++++------ tests/formats/forks/README.md | 47 +++++++++++++++++++ tests/generators/forks/main.py | 40 ++++++++++++++++ tests/generators/forks/requirements.txt | 2 + 6 files changed, 133 insertions(+), 18 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/lightclient_patch/fork/__init__.py create mode 100644 tests/formats/forks/README.md create mode 100644 tests/generators/forks/main.py create mode 100644 tests/generators/forks/requirements.txt diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 3f247b400..9c45049a2 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -70,7 +70,7 @@ class SpecForks(TypedDict, total=False): def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Callable[[Any], int], - spec: Spec, phases: SpecForks): + spec: Spec, phases: SpecForks, is_fork_test: bool): p0 = phases[PHASE0] balances = balances_fn(p0) @@ -82,7 +82,7 @@ def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Ca # TODO: instead of upgrading a test phase0 genesis state we can also write a phase1 state helper. # Decide based on performance/consistency results later. state = phases[PHASE1].upgrade_to_phase1(state) - elif spec.fork == LIGHTCLIENT_PATCH: # not generalizing this just yet, unclear final spec fork/patch order. + elif spec.fork == LIGHTCLIENT_PATCH and not fork_test: # do not upgrade if spec ttttest state = phases[LIGHTCLIENT_PATCH].upgrade_to_lightclient_patch(state) return state @@ -98,10 +98,11 @@ def with_custom_state(balances_fn: Callable[[Any], Sequence[int]], def entry(*args, spec: Spec, phases: SpecForks, **kw): # make a key for the state # genesis fork version separates configs during test-generation runtime. - key = (spec.fork, spec.GENESIS_FORK_VERSION, spec.__file__, balances_fn, threshold_fn) + is_fork_test = kw.pop('fork_test') if 'fork_test' in kw else False + key = (spec.fork, spec.GENESIS_FORK_VERSION, spec.__file__, balances_fn, threshold_fn, is_fork_test) global _custom_state_cache_dict if key not in _custom_state_cache_dict: - state = _prepare_state(balances_fn, threshold_fn, spec, phases) + state = _prepare_state(balances_fn, threshold_fn, spec, phases, is_fork_test) _custom_state_cache_dict[key] = state.get_backing() # Take an entry out of the LRU. @@ -287,6 +288,15 @@ def bls_switch(fn): return entry +def fork_test(fn): + """ + """ + def entry(*args, **kw): + # override fork test setting + kw['fork_test'] = True + return entry + + def disable_process_reveal_deadlines(fn): """ Decorator to make a function execute with `process_reveal_deadlines` OFF. diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/__init__.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py index 08c6e6d29..527ad746c 100644 --- a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -1,20 +1,22 @@ -from operator import attrgetter - from eth2spec.test.context import ( - PHASE0, LIGHTCLIENT_PATCH, - spec_state_test, with_phases, - with_custom_state, + LIGHTCLIENT_PATCH, + with_phases, + with_custom_state, fork_test, spec_test, with_state, low_balances, misc_balances, large_validator_set, ) +from eth2spec.test.utils import with_meta_tags from eth2spec.test.helpers.state import ( - next_slots, next_epoch, next_epoch_via_block, - transition_to_slot_via_block, ) +HF1_FORK_TEST_META_TAGS = { + 'fork': 'altair', +} + + def run_fork_test(spec, pre_state): yield 'pre', pre_state @@ -51,54 +53,68 @@ def run_fork_test(spec, pre_state): yield 'post', post_state -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_state @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_base_state(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_state @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_next_epoch(spec, phases, state): next_epoch(spec, state) yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_state @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_next_epoch_with_block(spec, phases, state): next_epoch_via_block(spec, state) yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_state @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_many_next_epoch(spec, phases, state): for _ in range(3): next_epoch(spec, state) yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_low_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_misc_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(([LIGHTCLIENT_PATCH])) @with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test +@fork_test +@with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_large_validator_set(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) diff --git a/tests/formats/forks/README.md b/tests/formats/forks/README.md new file mode 100644 index 000000000..1a7ee64ad --- /dev/null +++ b/tests/formats/forks/README.md @@ -0,0 +1,47 @@ +# Forks + +The aim of the fork tests is to ensure that a pre-fork state can be transformed + into a valid post-fork state, utilizing the `upgrade` function found in the relevant `fork.md` spec. + +There is only one handler: `core`. Each fork (after genesis) is handled with the same format, + and the particular fork boundary being tested is noted in `meta.yaml`. + +## Test case format + +### `meta.yaml` + +A yaml file to signify which fork boundary is being tested. + +```yaml +fork: str -- Fork being transitioned to +``` + +#### Fork strings + +Key of valid `fork` strings that might be found in `meta.yaml` + +| String ID | Pre-fork | Post-fork | Function | +| - | - | - | - | +| `altair` | Phase 0 | Altair | `upgrade_to_lightclient_patch` | + +### `pre.yaml` + +A YAML-encoded `BeaconState`, the state before running the fork transition. + +Also available as `pre.ssz`. + +### `post.yaml` + +A YAML-encoded `BeaconState`, the state after applying the fork transition. + +Also available as `post.ssz`. + +*Note*: This type is the `BeaconState` after the fork and is *not* the same type as `pre`. + +## Processing + +To process this test, pass `pre` into the upgrade function defined by the `fork` in `meta.yaml`. + +## Condition + +The resulting state should match the expected `post`. diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py new file mode 100644 index 000000000..a32ece712 --- /dev/null +++ b/tests/generators/forks/main.py @@ -0,0 +1,40 @@ +from importlib import reload +from typing import Iterable + +from eth2spec.test.context import LIGHTCLIENT_PATCH +from eth2spec.config import config_util +from eth2spec.test.lightclient_patch.fork import test_fork as test_altair_forks +from eth2spec.phase0 import spec as spec_phase0 + +from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing +from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests + + +pre_specs = { + LIGHTCLIENT_PATCH: spec_phase0, +} + + +def create_provider(fork_name: str, tests_src, config_name: str) -> gen_typing.TestProvider: + + def prepare_fn(configs_path: str) -> str: + config_util.prepare_config(configs_path, config_name) + reload(pre_specs[fork_name]) + return config_name + + def cases_fn() -> Iterable[gen_typing.TestCase]: + return generate_from_tests( + runner_name='forks', + handler_name='core', + src=tests_src, + fork_name=fork_name, + ) + + return gen_typing.TestProvider(prepare=prepare_fn, make_cases=cases_fn) + + +if __name__ == "__main__": + gen_runner.run_generator("forks", [ + create_provider(LIGHTCLIENT_PATCH, test_altair_forks, 'minimal'), + create_provider(LIGHTCLIENT_PATCH, test_altair_forks, 'minimal'), + ]) diff --git a/tests/generators/forks/requirements.txt b/tests/generators/forks/requirements.txt new file mode 100644 index 000000000..816df6e63 --- /dev/null +++ b/tests/generators/forks/requirements.txt @@ -0,0 +1,2 @@ +pytest>=4.4 +../../../ \ No newline at end of file From 50fb3da0729429179e6a24abaf1150b6c023a94b Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 9 Mar 2021 20:31:06 +0800 Subject: [PATCH 04/14] Make test_fork.py truly pass --- tests/core/pyspec/eth2spec/test/context.py | 3 +- .../test/lightclient_patch/fork/test_fork.py | 45 ++++++++++--------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 9c45049a2..f3d8e2a8f 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -82,7 +82,7 @@ def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Ca # TODO: instead of upgrading a test phase0 genesis state we can also write a phase1 state helper. # Decide based on performance/consistency results later. state = phases[PHASE1].upgrade_to_phase1(state) - elif spec.fork == LIGHTCLIENT_PATCH and not fork_test: # do not upgrade if spec ttttest + elif spec.fork == LIGHTCLIENT_PATCH and not is_fork_test: # do not upgrade if spec ttttest state = phases[LIGHTCLIENT_PATCH].upgrade_to_lightclient_patch(state) return state @@ -294,6 +294,7 @@ def fork_test(fn): def entry(*args, **kw): # override fork test setting kw['fork_test'] = True + return fn(*args, **kw) return entry diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py index 527ad746c..88ff68a06 100644 --- a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -1,5 +1,5 @@ from eth2spec.test.context import ( - LIGHTCLIENT_PATCH, + PHASE0, LIGHTCLIENT_PATCH, with_phases, with_custom_state, fork_test, spec_test, with_state, @@ -53,39 +53,39 @@ def run_fork_test(spec, pre_state): yield 'post', post_state -@with_phases(([LIGHTCLIENT_PATCH])) -@with_state -@spec_test @fork_test +@with_phases(([PHASE0])) +@spec_test +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_base_state(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([LIGHTCLIENT_PATCH])) -@with_state -@spec_test @fork_test +@with_phases(([PHASE0])) +@spec_test +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_next_epoch(spec, phases, state): next_epoch(spec, state) yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([LIGHTCLIENT_PATCH])) -@with_state -@spec_test @fork_test +@with_phases(([PHASE0])) +@spec_test +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_next_epoch_with_block(spec, phases, state): next_epoch_via_block(spec, state) yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([LIGHTCLIENT_PATCH])) -@with_state -@spec_test @fork_test +@with_phases(([PHASE0])) +@spec_test +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_many_next_epoch(spec, phases, state): for _ in range(3): @@ -93,28 +93,29 @@ def test_fork_many_next_epoch(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([LIGHTCLIENT_PATCH])) -@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) -@spec_test @fork_test +@with_phases(([PHASE0])) +@spec_test +@with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_low_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([LIGHTCLIENT_PATCH])) -@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) -@spec_test @fork_test +@with_phases(([PHASE0])) +@with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_misc_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([LIGHTCLIENT_PATCH])) -@with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) -@spec_test @fork_test +@with_phases(([PHASE0])) +@with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) +@with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_large_validator_set(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) From f97ea9e172e88a7527e7c7fa97e104a90df99a69 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 9 Mar 2021 20:55:39 +0800 Subject: [PATCH 05/14] Generate basic tests. Still having problem with generating `with_custom_state` tests --- .../gen_helpers/gen_from_tests/gen.py | 11 +++++++--- tests/generators/forks/main.py | 21 +++++++------------ 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py b/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py index 67d29b194..f04bf46a7 100644 --- a/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py +++ b/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py @@ -1,6 +1,6 @@ from importlib import reload, import_module from inspect import getmembers, isfunction -from typing import Any, Callable, Dict, Iterable +from typing import Any, Callable, Dict, Iterable, Optional from eth2spec.config import config_util from eth2spec.utils import bls @@ -11,7 +11,7 @@ from eth2spec.gen_helpers.gen_base.gen_typing import TestCase, TestProvider def generate_from_tests(runner_name: str, handler_name: str, src: Any, - fork_name: SpecForkName, bls_active: bool = True) -> Iterable[TestCase]: + fork_name: SpecForkName, bls_active: bool = True, phase: Optional[str]=None) -> Iterable[TestCase]: """ Generate a list of test cases by running tests from the given src in generator-mode. :param runner_name: to categorize the test in general as. @@ -20,12 +20,17 @@ def generate_from_tests(runner_name: str, handler_name: str, src: Any, :param fork_name: to run tests against particular phase and/or fork. (if multiple forks are applicable, indicate the last fork) :param bls_active: optional, to override BLS switch preference. Defaults to True. + :param phase: optional, specific phase name :return: an iterable of test cases. """ fn_names = [ name for (name, _) in getmembers(src, isfunction) if name.startswith('test_') ] + + if phase is None: + phase = fork_name + print("generating test vectors from tests source: %s" % src.__name__) for name in fn_names: tfn = getattr(src, name) @@ -42,7 +47,7 @@ def generate_from_tests(runner_name: str, handler_name: str, src: Any, suite_name='pyspec_tests', case_name=case_name, # TODO: with_all_phases and other per-phase tooling, should be replaced with per-fork equivalent. - case_fn=lambda: tfn(generator_mode=True, phase=fork_name, bls_active=bls_active) + case_fn=lambda: tfn(generator_mode=True, phase=phase, bls_active=bls_active) ) diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py index a32ece712..d39af802a 100644 --- a/tests/generators/forks/main.py +++ b/tests/generators/forks/main.py @@ -1,7 +1,7 @@ from importlib import reload from typing import Iterable -from eth2spec.test.context import LIGHTCLIENT_PATCH +from eth2spec.test.context import PHASE0, LIGHTCLIENT_PATCH, MINIMAL, MAINNET from eth2spec.config import config_util from eth2spec.test.lightclient_patch.fork import test_fork as test_altair_forks from eth2spec.phase0 import spec as spec_phase0 @@ -10,24 +10,20 @@ from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests -pre_specs = { - LIGHTCLIENT_PATCH: spec_phase0, -} - - -def create_provider(fork_name: str, tests_src, config_name: str) -> gen_typing.TestProvider: +def create_provider(tests_src, config_name: str) -> gen_typing.TestProvider: def prepare_fn(configs_path: str) -> str: config_util.prepare_config(configs_path, config_name) - reload(pre_specs[fork_name]) + reload(spec_phase0) return config_name def cases_fn() -> Iterable[gen_typing.TestCase]: return generate_from_tests( - runner_name='forks', - handler_name='core', + runner_name='fork', + handler_name='fork', src=tests_src, - fork_name=fork_name, + fork_name=LIGHTCLIENT_PATCH, + phase=PHASE0, ) return gen_typing.TestProvider(prepare=prepare_fn, make_cases=cases_fn) @@ -35,6 +31,5 @@ def create_provider(fork_name: str, tests_src, config_name: str) -> gen_typing.T if __name__ == "__main__": gen_runner.run_generator("forks", [ - create_provider(LIGHTCLIENT_PATCH, test_altair_forks, 'minimal'), - create_provider(LIGHTCLIENT_PATCH, test_altair_forks, 'minimal'), + create_provider(test_altair_forks, MINIMAL), ]) From 7a10c7108ad5b21efac726afe2a5799383457a3f Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 9 Mar 2021 21:17:02 +0800 Subject: [PATCH 06/14] Fix decorator calls --- .../eth2spec/test/lightclient_patch/fork/test_fork.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py index 88ff68a06..c5b9b8981 100644 --- a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -95,9 +95,8 @@ def test_fork_many_next_epoch(spec, phases, state): @fork_test @with_phases(([PHASE0])) -@spec_test @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) -@with_state +@spec_test @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_low_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) @@ -106,7 +105,7 @@ def test_fork_random_low_balances(spec, phases, state): @fork_test @with_phases(([PHASE0])) @with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) -@with_state +@spec_test @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_misc_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) @@ -115,7 +114,7 @@ def test_fork_random_misc_balances(spec, phases, state): @fork_test @with_phases(([PHASE0])) @with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) -@with_state +@spec_test @with_meta_tags(HF1_FORK_TEST_META_TAGS) def test_fork_random_large_validator_set(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) From f025ec40c584e45517aeed1f93ce4fa4db1f0f3d Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 9 Mar 2021 21:21:32 +0800 Subject: [PATCH 07/14] Fix linter error --- tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py b/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py index f04bf46a7..057aa1a2c 100644 --- a/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py +++ b/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py @@ -11,7 +11,8 @@ from eth2spec.gen_helpers.gen_base.gen_typing import TestCase, TestProvider def generate_from_tests(runner_name: str, handler_name: str, src: Any, - fork_name: SpecForkName, bls_active: bool = True, phase: Optional[str]=None) -> Iterable[TestCase]: + fork_name: SpecForkName, bls_active: bool = True, + phase: Optional[str]=None) -> Iterable[TestCase]: """ Generate a list of test cases by running tests from the given src in generator-mode. :param runner_name: to categorize the test in general as. From 5e864af67a161878c294a41dce579a20f98b62bd Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 9 Mar 2021 21:32:37 +0800 Subject: [PATCH 08/14] Reload Altair spec --- tests/generators/forks/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py index d39af802a..dd4c0051c 100644 --- a/tests/generators/forks/main.py +++ b/tests/generators/forks/main.py @@ -5,6 +5,7 @@ from eth2spec.test.context import PHASE0, LIGHTCLIENT_PATCH, MINIMAL, MAINNET from eth2spec.config import config_util from eth2spec.test.lightclient_patch.fork import test_fork as test_altair_forks from eth2spec.phase0 import spec as spec_phase0 +from eth2spec.lightclient_patch import spec as spec_lightclient_patch from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests @@ -15,6 +16,7 @@ def create_provider(tests_src, config_name: str) -> gen_typing.TestProvider: def prepare_fn(configs_path: str) -> str: config_util.prepare_config(configs_path, config_name) reload(spec_phase0) + reload(spec_lightclient_patch) return config_name def cases_fn() -> Iterable[gen_typing.TestCase]: From f71a3c6b22fe23f28eb49216618a20ef194d1025 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 9 Mar 2021 21:34:45 +0800 Subject: [PATCH 09/14] Generate with mainnet config --- tests/generators/forks/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py index dd4c0051c..b22707786 100644 --- a/tests/generators/forks/main.py +++ b/tests/generators/forks/main.py @@ -34,4 +34,5 @@ def create_provider(tests_src, config_name: str) -> gen_typing.TestProvider: if __name__ == "__main__": gen_runner.run_generator("forks", [ create_provider(test_altair_forks, MINIMAL), + create_provider(test_altair_forks, MAINNET), ]) From 956a7a2ef1a20da3472307768d41e28b69c80840 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Tue, 9 Mar 2021 16:09:08 -0700 Subject: [PATCH 10/14] Update tests/core/pyspec/eth2spec/test/context.py --- tests/core/pyspec/eth2spec/test/context.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index f3d8e2a8f..916c74e6a 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -82,7 +82,7 @@ def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Ca # TODO: instead of upgrading a test phase0 genesis state we can also write a phase1 state helper. # Decide based on performance/consistency results later. state = phases[PHASE1].upgrade_to_phase1(state) - elif spec.fork == LIGHTCLIENT_PATCH and not is_fork_test: # do not upgrade if spec ttttest + elif spec.fork == LIGHTCLIENT_PATCH and not is_fork_test: # do not upgrade if spec test state = phases[LIGHTCLIENT_PATCH].upgrade_to_lightclient_patch(state) return state From f9b54ea03ba57ee3335721596513c45f1f2eaa7c Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Tue, 9 Mar 2021 16:18:30 -0700 Subject: [PATCH 11/14] remove fork_test --- tests/core/pyspec/eth2spec/test/context.py | 19 ++++--------------- .../test/lightclient_patch/fork/test_fork.py | 9 +-------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 916c74e6a..1272485de 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -70,7 +70,7 @@ class SpecForks(TypedDict, total=False): def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Callable[[Any], int], - spec: Spec, phases: SpecForks, is_fork_test: bool): + spec: Spec, phases: SpecForks): p0 = phases[PHASE0] balances = balances_fn(p0) @@ -82,7 +82,7 @@ def _prepare_state(balances_fn: Callable[[Any], Sequence[int]], threshold_fn: Ca # TODO: instead of upgrading a test phase0 genesis state we can also write a phase1 state helper. # Decide based on performance/consistency results later. state = phases[PHASE1].upgrade_to_phase1(state) - elif spec.fork == LIGHTCLIENT_PATCH and not is_fork_test: # do not upgrade if spec test + elif spec.fork == LIGHTCLIENT_PATCH: state = phases[LIGHTCLIENT_PATCH].upgrade_to_lightclient_patch(state) return state @@ -98,11 +98,10 @@ def with_custom_state(balances_fn: Callable[[Any], Sequence[int]], def entry(*args, spec: Spec, phases: SpecForks, **kw): # make a key for the state # genesis fork version separates configs during test-generation runtime. - is_fork_test = kw.pop('fork_test') if 'fork_test' in kw else False - key = (spec.fork, spec.GENESIS_FORK_VERSION, spec.__file__, balances_fn, threshold_fn, is_fork_test) + key = (spec.fork, spec.GENESIS_FORK_VERSION, spec.__file__, balances_fn, threshold_fn) global _custom_state_cache_dict if key not in _custom_state_cache_dict: - state = _prepare_state(balances_fn, threshold_fn, spec, phases, is_fork_test) + state = _prepare_state(balances_fn, threshold_fn, spec, phases) _custom_state_cache_dict[key] = state.get_backing() # Take an entry out of the LRU. @@ -288,16 +287,6 @@ def bls_switch(fn): return entry -def fork_test(fn): - """ - """ - def entry(*args, **kw): - # override fork test setting - kw['fork_test'] = True - return fn(*args, **kw) - return entry - - def disable_process_reveal_deadlines(fn): """ Decorator to make a function execute with `process_reveal_deadlines` OFF. diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py index c5b9b8981..5904805cf 100644 --- a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -1,7 +1,7 @@ from eth2spec.test.context import ( PHASE0, LIGHTCLIENT_PATCH, with_phases, - with_custom_state, fork_test, + with_custom_state, spec_test, with_state, low_balances, misc_balances, large_validator_set, ) @@ -53,7 +53,6 @@ def run_fork_test(spec, pre_state): yield 'post', post_state -@fork_test @with_phases(([PHASE0])) @spec_test @with_state @@ -62,7 +61,6 @@ def test_fork_base_state(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@fork_test @with_phases(([PHASE0])) @spec_test @with_state @@ -72,7 +70,6 @@ def test_fork_next_epoch(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@fork_test @with_phases(([PHASE0])) @spec_test @with_state @@ -82,7 +79,6 @@ def test_fork_next_epoch_with_block(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@fork_test @with_phases(([PHASE0])) @spec_test @with_state @@ -93,7 +89,6 @@ def test_fork_many_next_epoch(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@fork_test @with_phases(([PHASE0])) @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test @@ -102,7 +97,6 @@ def test_fork_random_low_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@fork_test @with_phases(([PHASE0])) @with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test @@ -111,7 +105,6 @@ def test_fork_random_misc_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@fork_test @with_phases(([PHASE0])) @with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test From 338be1f636b7eae6a6bb3182d4b6682984e788c7 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Tue, 9 Mar 2021 16:27:06 -0700 Subject: [PATCH 12/14] clean up fork gens --- tests/formats/forks/README.md | 2 +- tests/generators/forks/main.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/formats/forks/README.md b/tests/formats/forks/README.md index 1a7ee64ad..57cc09227 100644 --- a/tests/formats/forks/README.md +++ b/tests/formats/forks/README.md @@ -3,7 +3,7 @@ The aim of the fork tests is to ensure that a pre-fork state can be transformed into a valid post-fork state, utilizing the `upgrade` function found in the relevant `fork.md` spec. -There is only one handler: `core`. Each fork (after genesis) is handled with the same format, +There is only one handler: `fork`. Each fork (after genesis) is handled with the same format, and the particular fork boundary being tested is noted in `meta.yaml`. ## Test case format diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py index b22707786..1a603a0dc 100644 --- a/tests/generators/forks/main.py +++ b/tests/generators/forks/main.py @@ -11,7 +11,7 @@ from eth2spec.gen_helpers.gen_base import gen_runner, gen_typing from eth2spec.gen_helpers.gen_from_tests.gen import generate_from_tests -def create_provider(tests_src, config_name: str) -> gen_typing.TestProvider: +def create_provider(tests_src, config_name: str, phase: str, fork_name: str) -> gen_typing.TestProvider: def prepare_fn(configs_path: str) -> str: config_util.prepare_config(configs_path, config_name) @@ -24,8 +24,9 @@ def create_provider(tests_src, config_name: str) -> gen_typing.TestProvider: runner_name='fork', handler_name='fork', src=tests_src, - fork_name=LIGHTCLIENT_PATCH, - phase=PHASE0, + fork_name=fork_name, + phase=phase, + ) return gen_typing.TestProvider(prepare=prepare_fn, make_cases=cases_fn) @@ -33,6 +34,6 @@ def create_provider(tests_src, config_name: str) -> gen_typing.TestProvider: if __name__ == "__main__": gen_runner.run_generator("forks", [ - create_provider(test_altair_forks, MINIMAL), - create_provider(test_altair_forks, MAINNET), + create_provider(test_altair_forks, MINIMAL, PHASE0, LIGHTCLIENT_PATCH), + create_provider(test_altair_forks, MAINNET, PHASE0, LIGHTCLIENT_PATCH), ]) From e792c27c915f96e9b576b0a21f3c2cab73a93894 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Wed, 10 Mar 2021 12:27:50 -0700 Subject: [PATCH 13/14] @hwwhww review Co-authored-by: Hsiao-Wei Wang --- .../pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py | 4 ++-- .../eth2spec/test/lightclient_patch/fork/test_fork.py | 8 ++++---- tests/generators/forks/main.py | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py b/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py index 057aa1a2c..c090869d5 100644 --- a/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py +++ b/tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py @@ -18,10 +18,10 @@ def generate_from_tests(runner_name: str, handler_name: str, src: Any, :param runner_name: to categorize the test in general as. :param handler_name: to categorize the test specialization as. :param src: to retrieve tests from (discovered using inspect.getmembers). - :param fork_name: to run tests against particular phase and/or fork. + :param fork_name: the folder name for these tests. (if multiple forks are applicable, indicate the last fork) :param bls_active: optional, to override BLS switch preference. Defaults to True. - :param phase: optional, specific phase name + :param phase: optional, to run tests against a particular spec version. Default to `fork_name` value. :return: an iterable of test cases. """ fn_names = [ diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py index 5904805cf..dada24af9 100644 --- a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -17,10 +17,10 @@ HF1_FORK_TEST_META_TAGS = { } -def run_fork_test(spec, pre_state): +def run_fork_test(post_spec, pre_state): yield 'pre', pre_state - post_state = spec.upgrade_to_lightclient_patch(pre_state) + post_state = post_spec.upgrade_to_lightclient_patch(pre_state) # Stable fields stable_fields = [ @@ -47,8 +47,8 @@ def run_fork_test(spec, pre_state): assert getattr(pre_state, field) != getattr(post_state, field) assert pre_state.fork.current_version == post_state.fork.previous_version - assert post_state.fork.current_version == spec.LIGHTCLIENT_PATCH_FORK_VERSION - assert post_state.fork.epoch == spec.get_current_epoch(post_state) + assert post_state.fork.current_version == post_spec.LIGHTCLIENT_PATCH_FORK_VERSION + assert post_state.fork.epoch == post_spec.get_current_epoch(post_state) yield 'post', post_state diff --git a/tests/generators/forks/main.py b/tests/generators/forks/main.py index 1a603a0dc..190d4620c 100644 --- a/tests/generators/forks/main.py +++ b/tests/generators/forks/main.py @@ -26,7 +26,6 @@ def create_provider(tests_src, config_name: str, phase: str, fork_name: str) -> src=tests_src, fork_name=fork_name, phase=phase, - ) return gen_typing.TestProvider(prepare=prepare_fn, make_cases=cases_fn) From 1f3e73703c10c5e9c8c3dc182632a535222a8d7f Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Wed, 10 Mar 2021 12:38:30 -0700 Subject: [PATCH 14/14] use 'other_phases' for fork tests --- tests/core/pyspec/eth2spec/test/context.py | 11 +++++++---- .../test/lightclient_patch/fork/test_fork.py | 14 +++++++------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index 1272485de..e197124c0 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -340,7 +340,7 @@ def with_phases(phases, other_phases=None): available_phases = set(run_phases) if other_phases is not None: - available_phases += set(other_phases) + available_phases |= set(other_phases) # TODO: test state is dependent on phase0 but is immediately transitioned to phase1. # A new state-creation helper for phase 1 may be in place, and then phase1+ tests can run without phase0 @@ -348,9 +348,12 @@ def with_phases(phases, other_phases=None): # Populate all phases for multi-phase tests phase_dir = {} - phase_dir[PHASE0] = spec_phase0 - phase_dir[PHASE1] = spec_phase1 - phase_dir[LIGHTCLIENT_PATCH] = spec_lightclient_patch + if PHASE0 in available_phases: + phase_dir[PHASE0] = spec_phase0 + if PHASE1 in available_phases: + phase_dir[PHASE1] = spec_phase1 + if LIGHTCLIENT_PATCH in available_phases: + phase_dir[LIGHTCLIENT_PATCH] = spec_lightclient_patch # return is ignored whenever multiple phases are ran. If if PHASE0 in run_phases: diff --git a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py index dada24af9..27d181510 100644 --- a/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py +++ b/tests/core/pyspec/eth2spec/test/lightclient_patch/fork/test_fork.py @@ -53,7 +53,7 @@ def run_fork_test(post_spec, pre_state): yield 'post', post_state -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @spec_test @with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) @@ -61,7 +61,7 @@ def test_fork_base_state(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @spec_test @with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) @@ -70,7 +70,7 @@ def test_fork_next_epoch(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @spec_test @with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) @@ -79,7 +79,7 @@ def test_fork_next_epoch_with_block(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @spec_test @with_state @with_meta_tags(HF1_FORK_TEST_META_TAGS) @@ -89,7 +89,7 @@ def test_fork_many_next_epoch(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @with_custom_state(balances_fn=low_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test @with_meta_tags(HF1_FORK_TEST_META_TAGS) @@ -97,7 +97,7 @@ def test_fork_random_low_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @with_custom_state(balances_fn=misc_balances, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test @with_meta_tags(HF1_FORK_TEST_META_TAGS) @@ -105,7 +105,7 @@ def test_fork_random_misc_balances(spec, phases, state): yield from run_fork_test(phases[LIGHTCLIENT_PATCH], state) -@with_phases(([PHASE0])) +@with_phases(phases=[PHASE0], other_phases=[LIGHTCLIENT_PATCH]) @with_custom_state(balances_fn=large_validator_set, threshold_fn=lambda spec: spec.EJECTION_BALANCE) @spec_test @with_meta_tags(HF1_FORK_TEST_META_TAGS)