From dcdbff07285efc5216d0c053d1508e5237016f81 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 7 Oct 2021 02:11:50 +0800 Subject: [PATCH 1/4] Combine the conflicting handler names --- .../gen_helpers/gen_from_tests/gen.py | 21 +++++++++++++++++++ .../eth2spec/test/merge/sanity/test_blocks.py | 2 +- tests/generators/genesis/main.py | 17 ++++++++------- tests/generators/sanity/main.py | 14 ++++++++----- 4 files changed, 40 insertions(+), 14 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 88bc6d601..65a9fe46d 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 @@ -109,3 +109,24 @@ def run_state_test_generators(runner_name: str, preset_name=preset_name, all_mods=all_mods, )) + + +def combine_mods(dict_1, dict_2): + """ + Return the merged dicts, where the result value would be a list of the values from two dicts. + """ + # The duplicate dict_1 items would be ignored here. + dict_3 = {**dict_1, **dict_2} + + intersection = list(dict_1.keys() & dict_2.keys()) + for key in intersection: + # To list + if not isinstance(dict_3[key], List): + dict_3[key] = [dict_3[key], ] + # Append dict_1 value to list + if isinstance(dict_1[key], List): + dict_3[key] += dict_1[key] + else: + dict_3[key].append(dict_1[key]) + + return dict_3 diff --git a/tests/core/pyspec/eth2spec/test/merge/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/merge/sanity/test_blocks.py index 4a6db4106..09cb547c2 100644 --- a/tests/core/pyspec/eth2spec/test/merge/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/merge/sanity/test_blocks.py @@ -11,7 +11,7 @@ from eth2spec.test.context import ( @with_merge_and_later @spec_state_test -def test_empty_block_transition(spec, state): +def test_empty_block_transition_no_tx(spec, state): yield 'pre', state block = build_empty_block_for_next_slot(spec, state) diff --git a/tests/generators/genesis/main.py b/tests/generators/genesis/main.py index a595db612..331381aa7 100644 --- a/tests/generators/genesis/main.py +++ b/tests/generators/genesis/main.py @@ -1,4 +1,4 @@ -from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators +from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods from eth2spec.test.helpers.constants import PHASE0, ALTAIR, MERGE @@ -7,14 +7,15 @@ if __name__ == "__main__": 'initialization', 'validity', ]} - altair_mods = phase_0_mods + # we have new unconditional lines in `initialize_beacon_state_from_eth1` and we want to test it - merge_mods = { - **{key: 'eth2spec.test.merge.genesis.test_' + key for key in [ - 'initialization', - ]}, - **altair_mods, - } + altair_mods = phase_0_mods + + _new_merge_mods = {key: 'eth2spec.test.merge.genesis.test_' + key for key in [ + 'initialization', + ]} + merge_mods = combine_mods(_new_merge_mods, altair_mods) + all_mods = { PHASE0: phase_0_mods, ALTAIR: altair_mods, diff --git a/tests/generators/sanity/main.py b/tests/generators/sanity/main.py index f5a6ccb41..705456824 100644 --- a/tests/generators/sanity/main.py +++ b/tests/generators/sanity/main.py @@ -1,5 +1,5 @@ from eth2spec.test.helpers.constants import PHASE0, ALTAIR, MERGE -from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators +from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods if __name__ == "__main__": @@ -7,12 +7,16 @@ if __name__ == "__main__": 'blocks', 'slots', ]} - altair_mods = {**{key: 'eth2spec.test.altair.sanity.test_' + key for key in [ + + _new_altair_mods = {key: 'eth2spec.test.altair.sanity.test_' + key for key in [ 'blocks', - ]}, **phase_0_mods} - merge_mods = {**{key: 'eth2spec.test.merge.sanity.test_' + key for key in [ + ]} + altair_mods = combine_mods(_new_altair_mods, phase_0_mods) + + _new_merge_mods = {key: 'eth2spec.test.merge.sanity.test_' + key for key in [ 'blocks', - ]}, **altair_mods} + ]} + merge_mods = combine_mods(_new_merge_mods, altair_mods) all_mods = { PHASE0: phase_0_mods, From 7a7ab81306a6cefb7441c5cb50f8e0e2020a3aed Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 7 Oct 2021 02:32:17 +0800 Subject: [PATCH 2/4] Also update other generators so that we won't write the bad pattern again --- tests/generators/epoch_processing/main.py | 17 +++++++------ tests/generators/fork_choice/main.py | 13 +++++----- tests/generators/operations/main.py | 29 ++++++++++------------- 3 files changed, 27 insertions(+), 32 deletions(-) diff --git a/tests/generators/epoch_processing/main.py b/tests/generators/epoch_processing/main.py index 4c1a68d0a..f9c71f5e2 100644 --- a/tests/generators/epoch_processing/main.py +++ b/tests/generators/epoch_processing/main.py @@ -1,4 +1,4 @@ -from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators +from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods from eth2spec.test.helpers.constants import PHASE0, ALTAIR, MERGE @@ -15,14 +15,13 @@ if __name__ == "__main__": 'historical_roots_update', 'participation_record_updates', ]} - altair_mods = { - **{key: 'eth2spec.test.altair.epoch_processing.test_process_' + key for key in [ - 'inactivity_updates', - 'participation_flag_updates', - 'sync_committee_updates', - ]}, - **phase_0_mods, - } # also run the previous phase 0 tests + + _new_altair_mods = {key: 'eth2spec.test.altair.epoch_processing.test_process_' + key for key in [ + 'inactivity_updates', + 'participation_flag_updates', + 'sync_committee_updates', + ]}, + altair_mods = combine_mods(_new_altair_mods, phase_0_mods) # No epoch-processing changes in Merge and previous testing repeats with new types, so no additional tests required. merge_mods = altair_mods diff --git a/tests/generators/fork_choice/main.py b/tests/generators/fork_choice/main.py index 94516a39c..452b5854a 100644 --- a/tests/generators/fork_choice/main.py +++ b/tests/generators/fork_choice/main.py @@ -1,4 +1,4 @@ -from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators +from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods from eth2spec.test.helpers.constants import PHASE0, ALTAIR, MERGE @@ -9,14 +9,13 @@ if __name__ == "__main__": ]} # No additional Altair specific finality tests, yet. altair_mods = phase_0_mods + # For merge `on_merge_block` test kind added with `pow_block_N.ssz` files with several # PowBlock's which should be resolved by `get_pow_block(hash: Hash32) -> PowBlock` function - merge_mods = { - **{key: 'eth2spec.test.merge.fork_choice.test_' + key for key in [ - 'on_merge_block', - ]}, - **altair_mods, - } + _new_merge_mods = {key: 'eth2spec.test.merge.fork_choice.test_' + key for key in [ + 'on_merge_block', + ]}, + merge_mods = combine_mods(_new_merge_mods, altair_mods) all_mods = { PHASE0: phase_0_mods, diff --git a/tests/generators/operations/main.py b/tests/generators/operations/main.py index 3844ce186..4467b71b7 100644 --- a/tests/generators/operations/main.py +++ b/tests/generators/operations/main.py @@ -1,4 +1,4 @@ -from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators +from eth2spec.gen_helpers.gen_from_tests.gen import run_state_test_generators, combine_mods from eth2spec.test.helpers.constants import PHASE0, ALTAIR, MERGE @@ -11,29 +11,26 @@ if __name__ == "__main__": 'proposer_slashing', 'voluntary_exit', ]} - altair_mods = { - **{'sync_aggregate': [ - 'eth2spec.test.altair.block_processing.sync_aggregate.test_process_' + key - for key in ['sync_aggregate', 'sync_aggregate_random'] - ]}, - **phase_0_mods, - } # also run the previous phase 0 tests + _new_altair_mods = {'sync_aggregate': [ + 'eth2spec.test.altair.block_processing.sync_aggregate.test_process_' + key + for key in ['sync_aggregate', 'sync_aggregate_random'] + ]} + altair_mods = combine_mods(_new_altair_mods, phase_0_mods) - merge_mods = { - **{key: 'eth2spec.test.merge.block_processing.test_process_' + key for key in [ - 'execution_payload', - ]}, - **altair_mods, - } + _new_merge_mods = {key: 'eth2spec.test.merge.block_processing.test_process_' + key for key in [ + 'execution_payload', + ]} + merge_mods = combine_mods(_new_merge_mods, altair_mods) # TODO Custody Game testgen is disabled for now - # custody_game_mods = {**{key: 'eth2spec.test.custody_game.block_processing.test_process_' + key for key in [ + # _new_custody_game_mods = {key: 'eth2spec.test.custody_game.block_processing.test_process_' + key for key in [ # 'attestation', # 'chunk_challenge', # 'custody_key_reveal', # 'custody_slashing', # 'early_derived_secret_reveal', - # ]}, **phase_0_mods} # also run the previous phase 0 tests (but against custody game spec) + # ]} + # custody_game_mods = combine_mods(_new_custody_game_mods, phase0_mods) all_mods = { PHASE0: phase_0_mods, From 4ae8fb182e8977daeafb4e1ccf0d7330b641235a Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 7 Oct 2021 03:29:09 +0800 Subject: [PATCH 3/4] Fix `run_sync_committee_sanity_test` so that it works with duplicate committee indices --- .../pyspec/eth2spec/test/altair/sanity/test_blocks.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py index 662891762..581ab6fdd 100644 --- a/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py @@ -23,13 +23,19 @@ from eth2spec.test.helpers.inactivity_scores import randomize_inactivity_scores def run_sync_committee_sanity_test(spec, state, fraction_full=1.0, rng=Random(454545)): all_pubkeys = [v.pubkey for v in state.validators] committee = [all_pubkeys.index(pubkey) for pubkey in state.current_sync_committee.pubkeys] - participants = rng.sample(committee, int(len(committee) * fraction_full)) + selected_indices = rng.sample(list(range(len(committee))), int(len(committee) * fraction_full)) + sync_committee_bits = [True if i in selected_indices else False for i in range(len(committee))] + participants = [ + validator_index + for i, validator_index in enumerate(committee) + if sync_committee_bits[i] + ] yield 'pre', state block = build_empty_block_for_next_slot(spec, state) block.body.sync_aggregate = spec.SyncAggregate( - sync_committee_bits=[index in participants for index in committee], + sync_committee_bits=sync_committee_bits, sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, From ff15d0bc390ebd340aa3aba2a4e2836048b572a3 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 7 Oct 2021 16:04:06 +0800 Subject: [PATCH 4/4] Apply PR feedback from @ralexstokes --- tests/core/pyspec/eth2spec/gen_helpers/gen_from_tests/gen.py | 4 ++-- tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py | 4 ++-- 2 files changed, 4 insertions(+), 4 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 65a9fe46d..328b7edf1 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 @@ -118,11 +118,11 @@ def combine_mods(dict_1, dict_2): # The duplicate dict_1 items would be ignored here. dict_3 = {**dict_1, **dict_2} - intersection = list(dict_1.keys() & dict_2.keys()) + intersection = dict_1.keys() & dict_2.keys() for key in intersection: # To list if not isinstance(dict_3[key], List): - dict_3[key] = [dict_3[key], ] + dict_3[key] = [dict_3[key]] # Append dict_1 value to list if isinstance(dict_1[key], List): dict_3[key] += dict_1[key] diff --git a/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py index 581ab6fdd..058db2ee6 100644 --- a/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks.py @@ -23,8 +23,8 @@ from eth2spec.test.helpers.inactivity_scores import randomize_inactivity_scores def run_sync_committee_sanity_test(spec, state, fraction_full=1.0, rng=Random(454545)): all_pubkeys = [v.pubkey for v in state.validators] committee = [all_pubkeys.index(pubkey) for pubkey in state.current_sync_committee.pubkeys] - selected_indices = rng.sample(list(range(len(committee))), int(len(committee) * fraction_full)) - sync_committee_bits = [True if i in selected_indices else False for i in range(len(committee))] + selected_indices = rng.sample(range(len(committee)), int(len(committee) * fraction_full)) + sync_committee_bits = [i in selected_indices for i in range(len(committee))] participants = [ validator_index for i, validator_index in enumerate(committee)