From cdaf7e84dd8e4af2400fabd5505f6c8d46ea4c87 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Thu, 27 Oct 2022 21:59:17 +0200 Subject: [PATCH 1/2] Allow extending LC merkle proof tests Currently, `test_single_merkle_proof` only supports `BeaconState` tests. For future tests, different object classes are desirable. Update format to allow testing other objects as well. --- .../light_client/test_single_merkle_proof.py | 18 ++++++++++++------ .../light_client/single_merkle_proof.md | 18 ++++++++++++------ 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py index 064760bf0..5628cb70d 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py @@ -7,8 +7,10 @@ from eth2spec.test.context import ( @with_altair_and_later @spec_state_test def test_current_sync_committee_merkle_proof(spec, state): - yield "state", state - current_sync_committee_branch = spec.compute_merkle_proof_for_state(state, spec.CURRENT_SYNC_COMMITTEE_INDEX) + yield "object_class", "meta", "BeaconState" + yield "object", state + current_sync_committee_branch = \ + spec.compute_merkle_proof_for_state(state, spec.CURRENT_SYNC_COMMITTEE_INDEX) yield "proof", { "leaf": "0x" + state.current_sync_committee.hash_tree_root().hex(), "leaf_index": spec.CURRENT_SYNC_COMMITTEE_INDEX, @@ -26,8 +28,10 @@ def test_current_sync_committee_merkle_proof(spec, state): @with_altair_and_later @spec_state_test def test_next_sync_committee_merkle_proof(spec, state): - yield "state", state - next_sync_committee_branch = spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX) + yield "object_class", "meta", "BeaconState" + yield "object", state + next_sync_committee_branch = \ + spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX) yield "proof", { "leaf": "0x" + state.next_sync_committee.hash_tree_root().hex(), "leaf_index": spec.NEXT_SYNC_COMMITTEE_INDEX, @@ -45,8 +49,10 @@ def test_next_sync_committee_merkle_proof(spec, state): @with_altair_and_later @spec_state_test def test_finality_root_merkle_proof(spec, state): - yield "state", state - finality_branch = spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX) + yield "object_class", "meta", "BeaconState" + yield "object", state + finality_branch = \ + spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX) yield "proof", { "leaf": "0x" + state.finalized_checkpoint.root.hex(), "leaf_index": spec.FINALIZED_ROOT_INDEX, diff --git a/tests/formats/light_client/single_merkle_proof.md b/tests/formats/light_client/single_merkle_proof.md index 65fe7c988..c8b2dea6e 100644 --- a/tests/formats/light_client/single_merkle_proof.md +++ b/tests/formats/light_client/single_merkle_proof.md @@ -5,24 +5,30 @@ generation and verification of merkle proofs based on static data. ## Test case format -### `state.ssz_snappy` +### `meta.yaml` -An SSZ-snappy encoded `BeaconState` object from which other data is generated. +```yaml +object_class: string -- 'BeaconState' +``` + +### `object.yaml` + +A SSZ-snappy encoded object of type `object_class` from which other data is generated. ### `proof.yaml` -A proof of the leaf value (a merkle root) at generalized-index `leaf_index` in the given `state`. +A proof of the leaf value (a merkle root) at generalized-index `leaf_index` in the given `object`. ```yaml leaf: Bytes32 # string, hex encoded, with 0x prefix leaf_index: int # integer, decimal -branch: list of Bytes32 # list, each element is a string, hex encoded, with 0x prefix +branch: list of Bytes32 # list, each element is a string, hex encoded, with 0x prefix ``` ## Condition A test-runner can implement the following assertions: - Check that `is_valid_merkle_branch` confirms `leaf` at `leaf_index` to verify - against `has_tree_root(state)` and `proof`. + against `hash_tree_root(object)` and `branch`. - If the implementation supports generating merkle proofs, check that the - self-generated proof matches the `proof` provided with the test. + self-generated proof matches the `branch` provided with the test. From 5c663001711ae6507862731801cb161adc122802 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Fri, 28 Oct 2022 20:32:33 +0200 Subject: [PATCH 2/2] Use `suite_name` instead of `meta.yaml` for SSZ type --- .../pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py | 2 +- .../test/altair/light_client/test_single_merkle_proof.py | 7 ++++--- tests/core/pyspec/eth2spec/test/context.py | 7 +++++++ tests/formats/light_client/single_merkle_proof.md | 8 ++------ 4 files changed, 14 insertions(+), 10 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 328b7edf1..b951a6a85 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 @@ -49,7 +49,7 @@ def generate_from_tests(runner_name: str, handler_name: str, src: Any, preset_name=preset_name, runner_name=runner_name, handler_name=handler_name, - suite_name='pyspec_tests', + suite_name=getattr(tfn, '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=phase, preset=preset_name, bls_active=bls_active) diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py index 5628cb70d..465fa629f 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_single_merkle_proof.py @@ -1,13 +1,14 @@ from eth2spec.test.context import ( spec_state_test, with_altair_and_later, + with_test_suite_name, ) +@with_test_suite_name("BeaconState") @with_altair_and_later @spec_state_test def test_current_sync_committee_merkle_proof(spec, state): - yield "object_class", "meta", "BeaconState" yield "object", state current_sync_committee_branch = \ spec.compute_merkle_proof_for_state(state, spec.CURRENT_SYNC_COMMITTEE_INDEX) @@ -25,10 +26,10 @@ def test_current_sync_committee_merkle_proof(spec, state): ) +@with_test_suite_name("BeaconState") @with_altair_and_later @spec_state_test def test_next_sync_committee_merkle_proof(spec, state): - yield "object_class", "meta", "BeaconState" yield "object", state next_sync_committee_branch = \ spec.compute_merkle_proof_for_state(state, spec.NEXT_SYNC_COMMITTEE_INDEX) @@ -46,10 +47,10 @@ def test_next_sync_committee_merkle_proof(spec, state): ) +@with_test_suite_name("BeaconState") @with_altair_and_later @spec_state_test def test_finality_root_merkle_proof(spec, state): - yield "object_class", "meta", "BeaconState" yield "object", state finality_branch = \ spec.compute_merkle_proof_for_state(state, spec.FINALIZED_ROOT_INDEX) diff --git a/tests/core/pyspec/eth2spec/test/context.py b/tests/core/pyspec/eth2spec/test/context.py index bc04c05f2..bcc77398c 100644 --- a/tests/core/pyspec/eth2spec/test/context.py +++ b/tests/core/pyspec/eth2spec/test/context.py @@ -620,6 +620,13 @@ def only_generator(reason): return _decorator +def with_test_suite_name(suite_name: str): + def _decorator(inner): + inner.suite_name = suite_name + return inner + return _decorator + + # # Fork transition state tests # diff --git a/tests/formats/light_client/single_merkle_proof.md b/tests/formats/light_client/single_merkle_proof.md index c8b2dea6e..d2137605e 100644 --- a/tests/formats/light_client/single_merkle_proof.md +++ b/tests/formats/light_client/single_merkle_proof.md @@ -5,15 +5,11 @@ generation and verification of merkle proofs based on static data. ## Test case format -### `meta.yaml` - -```yaml -object_class: string -- 'BeaconState' -``` +Tests for each individual SSZ type are grouped into a `suite` indicating the SSZ type name. ### `object.yaml` -A SSZ-snappy encoded object of type `object_class` from which other data is generated. +A SSZ-snappy encoded object from which other data is generated. The SSZ type can be determined from the test `suite` name. ### `proof.yaml`