From 69d043b4377ca649643041de308e66bfe7a463d8 Mon Sep 17 00:00:00 2001 From: Etan Kissling Date: Tue, 9 Jan 2024 15:33:43 +0100 Subject: [PATCH] Extract LC migration test helpers to `light_client.py` module The helpers needed to migrate LC data across forks are generic enough to allow extraction from a specific test into the common `light_client.py` helper module. This way, it is possible to use them from future tests. Also complete the missing functions for `LightClientFinalityUpdate`, `LightClientOptimisticUpdate` and `LightClientHeader` in same style. --- .../test/altair/light_client/test_sync.py | 95 +------------ .../eth2spec/test/helpers/light_client.py | 126 ++++++++++++++++++ 2 files changed, 131 insertions(+), 90 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py b/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py index f8faa2fdd..8aa3bb911 100644 --- a/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py +++ b/tests/core/pyspec/eth2spec/test/altair/light_client/test_sync.py @@ -29,6 +29,9 @@ from eth2spec.test.helpers.forks import ( ) from eth2spec.test.helpers.light_client import ( get_sync_aggregate, + upgrade_lc_bootstrap_to_new_spec, + upgrade_lc_update_to_new_spec, + upgrade_lc_store_to_new_spec, ) from eth2spec.test.helpers.state import ( next_slots, @@ -49,94 +52,6 @@ def get_spec_for_fork_version(spec, fork_version, phases): raise ValueError("Unknown fork version %s" % fork_version) -def needs_upgrade_to_capella(d_spec, s_spec): - return is_post_capella(s_spec) and not is_post_capella(d_spec) - - -def needs_upgrade_to_deneb(d_spec, s_spec): - return is_post_deneb(s_spec) and not is_post_deneb(d_spec) - - -def check_lc_header_equal(d_spec, s_spec, data, upgraded): - assert upgraded.beacon.slot == data.beacon.slot - assert upgraded.beacon.hash_tree_root() == data.beacon.hash_tree_root() - if is_post_capella(s_spec): - if is_post_capella(d_spec): - assert s_spec.get_lc_execution_root(upgraded) == d_spec.get_lc_execution_root(data) - else: - assert s_spec.get_lc_execution_root(upgraded) == s_spec.Root() - - -def check_lc_bootstrap_equal(d_spec, s_spec, data, upgraded): - check_lc_header_equal(d_spec, s_spec, data.header, upgraded.header) - assert upgraded.current_sync_committee == data.current_sync_committee - assert upgraded.current_sync_committee_branch == data.current_sync_committee_branch - - -def upgrade_lc_bootstrap_to_store(d_spec, s_spec, data): - upgraded = data - - if needs_upgrade_to_capella(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_bootstrap_to_capella(upgraded) - check_lc_bootstrap_equal(d_spec, s_spec, data, upgraded) - - if needs_upgrade_to_deneb(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_bootstrap_to_deneb(upgraded) - check_lc_bootstrap_equal(d_spec, s_spec, data, upgraded) - - return upgraded - - -def check_lc_update_equal(d_spec, s_spec, data, upgraded): - check_lc_header_equal(d_spec, s_spec, data.attested_header, upgraded.attested_header) - assert upgraded.next_sync_committee == data.next_sync_committee - assert upgraded.next_sync_committee_branch == data.next_sync_committee_branch - check_lc_header_equal(d_spec, s_spec, data.finalized_header, upgraded.finalized_header) - assert upgraded.sync_aggregate == data.sync_aggregate - assert upgraded.signature_slot == data.signature_slot - - -def upgrade_lc_update_to_store(d_spec, s_spec, data): - upgraded = data - - if needs_upgrade_to_capella(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_update_to_capella(upgraded) - check_lc_update_equal(d_spec, s_spec, data, upgraded) - - if needs_upgrade_to_deneb(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_update_to_deneb(upgraded) - check_lc_update_equal(d_spec, s_spec, data, upgraded) - - return upgraded - - -def check_lc_store_equal(d_spec, s_spec, data, upgraded): - check_lc_header_equal(d_spec, s_spec, data.finalized_header, upgraded.finalized_header) - assert upgraded.current_sync_committee == data.current_sync_committee - assert upgraded.next_sync_committee == data.next_sync_committee - if upgraded.best_valid_update is None: - assert data.best_valid_update is None - else: - check_lc_update_equal(d_spec, s_spec, data.best_valid_update, upgraded.best_valid_update) - check_lc_header_equal(d_spec, s_spec, data.optimistic_header, upgraded.optimistic_header) - assert upgraded.previous_max_active_participants == data.previous_max_active_participants - assert upgraded.current_max_active_participants == data.current_max_active_participants - - -def upgrade_lc_store_to_new_spec(d_spec, s_spec, data): - upgraded = data - - if needs_upgrade_to_capella(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_store_to_capella(upgraded) - check_lc_store_equal(d_spec, s_spec, data, upgraded) - - if needs_upgrade_to_deneb(d_spec, s_spec): - upgraded = s_spec.upgrade_lc_store_to_deneb(upgraded) - check_lc_store_equal(d_spec, s_spec, data, upgraded) - - return upgraded - - class LightClientSyncTest(object): steps: List[Dict[str, Any]] genesis_validators_root: Any @@ -175,7 +90,7 @@ def setup_test(spec, state, s_spec=None, phases=None): yield "bootstrap_fork_digest", "meta", encode_hex(data_fork_digest) yield "bootstrap", data - upgraded = upgrade_lc_bootstrap_to_store(d_spec, test.s_spec, data) + upgraded = upgrade_lc_bootstrap_to_new_spec(d_spec, test.s_spec, data) test.store = test.s_spec.initialize_light_client_store(trusted_block_root, upgraded) store_fork_version = get_store_fork_version(test.s_spec) store_fork_digest = test.s_spec.compute_fork_digest(store_fork_version, test.genesis_validators_root) @@ -251,7 +166,7 @@ def emit_update(test, spec, state, block, attested_state, attested_block, finali [spec.Bytes32() for _ in range(spec.floorlog2(spec.NEXT_SYNC_COMMITTEE_INDEX))] current_slot = state.slot - upgraded = upgrade_lc_update_to_store(d_spec, test.s_spec, data) + upgraded = upgrade_lc_update_to_new_spec(d_spec, test.s_spec, data) test.s_spec.process_light_client_update(test.store, upgraded, current_slot, test.genesis_validators_root) yield get_update_file_name(d_spec, data), data diff --git a/tests/core/pyspec/eth2spec/test/helpers/light_client.py b/tests/core/pyspec/eth2spec/test/helpers/light_client.py index 1878832c3..14db3e551 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/light_client.py +++ b/tests/core/pyspec/eth2spec/test/helpers/light_client.py @@ -1,6 +1,9 @@ from eth2spec.test.helpers.state import ( transition_to, ) +from eth2spec.test.helpers.forks import ( + is_post_capella, is_post_deneb, +) from eth2spec.test.helpers.sync_committee import ( compute_aggregate_sync_committee_signature, compute_committee_indices, @@ -66,3 +69,126 @@ def create_update(spec, spec, attested_state, num_participants) return update + + +def needs_upgrade_to_capella(spec, new_spec): + return is_post_capella(new_spec) and not is_post_capella(spec) + + +def needs_upgrade_to_deneb(spec, new_spec): + return is_post_deneb(new_spec) and not is_post_deneb(spec) + + +def check_lc_header_equal(spec, new_spec, data, upgraded): + assert upgraded.beacon.slot == data.beacon.slot + assert upgraded.beacon.hash_tree_root() == data.beacon.hash_tree_root() + if is_post_capella(new_spec): + if is_post_capella(spec): + assert new_spec.get_lc_execution_root(upgraded) == spec.get_lc_execution_root(data) + else: + assert new_spec.get_lc_execution_root(upgraded) == new_spec.Root() + + +def upgrade_lc_header_to_new_spec(spec, new_spec, data): + upgraded = data + + if needs_upgrade_to_capella(spec, new_spec): + upgraded = new_spec.upgrade_lc_header_to_capella(upgraded) + check_lc_header_equal(spec, new_spec, data, upgraded) + + if needs_upgrade_to_deneb(spec, new_spec): + upgraded = new_spec.upgrade_lc_header_to_deneb(upgraded) + check_lc_header_equal(spec, new_spec, data, upgraded) + + return upgraded + + +def check_lc_bootstrap_equal(spec, new_spec, data, upgraded): + check_lc_header_equal(spec, new_spec, data.header, upgraded.header) + assert upgraded.current_sync_committee == data.current_sync_committee + assert upgraded.current_sync_committee_branch == data.current_sync_committee_branch + + +def upgrade_lc_bootstrap_to_new_spec(spec, new_spec, data): + upgraded = data + + if needs_upgrade_to_capella(spec, new_spec): + upgraded = new_spec.upgrade_lc_bootstrap_to_capella(upgraded) + check_lc_bootstrap_equal(spec, new_spec, data, upgraded) + + if needs_upgrade_to_deneb(spec, new_spec): + upgraded = new_spec.upgrade_lc_bootstrap_to_deneb(upgraded) + check_lc_bootstrap_equal(spec, new_spec, data, upgraded) + + return upgraded + + +def check_lc_update_equal(spec, new_spec, data, upgraded): + check_lc_header_equal(spec, new_spec, data.attested_header, upgraded.attested_header) + assert upgraded.next_sync_committee == data.next_sync_committee + assert upgraded.next_sync_committee_branch == data.next_sync_committee_branch + check_lc_header_equal(spec, new_spec, data.finalized_header, upgraded.finalized_header) + assert upgraded.sync_aggregate == data.sync_aggregate + assert upgraded.signature_slot == data.signature_slot + + +def upgrade_lc_update_to_new_spec(spec, new_spec, data): + upgraded = data + + if needs_upgrade_to_capella(spec, new_spec): + upgraded = new_spec.upgrade_lc_update_to_capella(upgraded) + check_lc_update_equal(spec, new_spec, data, upgraded) + + if needs_upgrade_to_deneb(spec, new_spec): + upgraded = new_spec.upgrade_lc_update_to_deneb(upgraded) + check_lc_update_equal(spec, new_spec, data, upgraded) + + return upgraded + + +def check_lc_finality_update_equal(spec, new_spec, data, upgraded): + check_lc_header_equal(spec, new_spec, data.attested_header, upgraded.attested_header) + check_lc_header_equal(spec, new_spec, data.finalized_header, upgraded.finalized_header) + assert upgraded.sync_aggregate == data.sync_aggregate + assert upgraded.signature_slot == data.signature_slot + + +def upgrade_lc_finality_update_to_new_spec(spec, new_spec, data): + upgraded = data + + if needs_upgrade_to_capella(spec, new_spec): + upgraded = new_spec.upgrade_lc_finality_update_to_capella(upgraded) + check_lc_finality_update_equal(spec, new_spec, data, upgraded) + + if needs_upgrade_to_deneb(spec, new_spec): + upgraded = new_spec.upgrade_lc_finality_update_to_deneb(upgraded) + check_lc_finality_update_equal(spec, new_spec, data, upgraded) + + return upgraded + + +def check_lc_store_equal(spec, new_spec, data, upgraded): + check_lc_header_equal(spec, new_spec, data.finalized_header, upgraded.finalized_header) + assert upgraded.current_sync_committee == data.current_sync_committee + assert upgraded.next_sync_committee == data.next_sync_committee + if upgraded.best_valid_update is None: + assert data.best_valid_update is None + else: + check_lc_update_equal(spec, new_spec, data.best_valid_update, upgraded.best_valid_update) + check_lc_header_equal(spec, new_spec, data.optimistic_header, upgraded.optimistic_header) + assert upgraded.previous_max_active_participants == data.previous_max_active_participants + assert upgraded.current_max_active_participants == data.current_max_active_participants + + +def upgrade_lc_store_to_new_spec(spec, new_spec, data): + upgraded = data + + if needs_upgrade_to_capella(spec, new_spec): + upgraded = new_spec.upgrade_lc_store_to_capella(upgraded) + check_lc_store_equal(spec, new_spec, data, upgraded) + + if needs_upgrade_to_deneb(spec, new_spec): + upgraded = new_spec.upgrade_lc_store_to_deneb(upgraded) + check_lc_store_equal(spec, new_spec, data, upgraded) + + return upgraded