From cc04da8e795ca9d8774f033434765e5be2edafe6 Mon Sep 17 00:00:00 2001 From: Alex Stokes Date: Mon, 23 Aug 2021 12:30:05 -0700 Subject: [PATCH] add randomized block tests for altair --- .../test/altair/sanity/test_blocks_random.py | 63 +++++++++++++++++++ .../eth2spec/test/helpers/multi_operations.py | 20 ++++++ .../core/pyspec/eth2spec/test/utils/random.py | 4 +- tests/generators/sanity/main.py | 1 + 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks_random.py diff --git a/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks_random.py b/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks_random.py new file mode 100644 index 000000000..b0c0e86b5 --- /dev/null +++ b/tests/core/pyspec/eth2spec/test/altair/sanity/test_blocks_random.py @@ -0,0 +1,63 @@ +from tests.core.pyspec.eth2spec.test.helpers.constants import ALTAIR +from tests.core.pyspec.eth2spec.test.context import ( + misc_balances_in_default_range_with_many_validators, + with_phases, + zero_activation_threshold, +) +from eth2spec.test.helpers.multi_operations import ( + get_random_sync_aggregate, +) +from eth2spec.test.helpers.inactivity_scores import ( + randomize_inactivity_scores, +) +from eth2spec.test.context import ( + always_bls, + spec_test, + with_custom_state, + single_phase, +) +from eth2spec.test.utils.random import ( + generate_randomized_tests, + pytest_generate_tests_adapter, + run_generated_randomized_test, + random_block, + randomize_state, +) + +SYNC_AGGREGATE_PARTICIPATION_BUCKETS = 4 + +def _randomize_altair_state(spec, state): + randomize_state(spec, state, exit_fraction=0.1, slash_fraction=0.1) + randomize_inactivity_scores(spec, state) + + +def _randomize_altair_block(spec, state, signed_blocks): + block = random_block(spec, state, signed_blocks) + fraction_missed = len(signed_blocks) / SYNC_AGGREGATE_PARTICIPATION_BUCKETS + fraction_participated = 1.0 - fraction_missed + block.body.sync_aggregate = get_random_sync_aggregate(spec, state, fraction_participated=fraction_participated) + return block + + +def pytest_generate_tests(metafunc): + """ + Pytest hook to generate test cases from dynamically computed data + """ + generate_randomized_tests( + metafunc, + state_randomizer=_randomize_altair_state, + block_randomizer=_randomize_altair_block, + ) + + +@pytest_generate_tests_adapter +@with_phases([ALTAIR]) +@with_custom_state( + balances_fn=misc_balances_in_default_range_with_many_validators, + threshold_fn=zero_activation_threshold +) +@spec_test +@single_phase +@always_bls +def test_harness_for_randomized_blocks(spec, state, test_description): + yield from run_generated_randomized_test(spec, state, test_description) diff --git a/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py b/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py index 68ca02b91..10de14253 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py +++ b/tests/core/pyspec/eth2spec/test/helpers/multi_operations.py @@ -7,6 +7,10 @@ from eth2spec.test.helpers.state import ( from eth2spec.test.helpers.block import ( build_empty_block_for_next_slot, ) +from eth2spec.test.helpers.sync_committee import ( + compute_committee_indices, + compute_aggregate_sync_committee_signature, +) from eth2spec.test.helpers.proposer_slashings import get_valid_proposer_slashing from eth2spec.test.helpers.attester_slashings import get_valid_attester_slashing_by_indices from eth2spec.test.helpers.attestations import get_valid_attestation @@ -192,3 +196,19 @@ def run_test_full_random_operations(spec, state, rng=Random(2080)): yield 'blocks', [signed_block] yield 'post', state + + +def get_random_sync_aggregate(spec, state, fraction_participated=1.0, rng=Random(2099)): + committee_indices = compute_committee_indices(spec, state, state.current_sync_committee) + participant_count = int(len(committee_indices) * fraction_participated) + participants = rng.sample(committee_indices, participant_count) + signature = compute_aggregate_sync_committee_signature( + spec, + state, + state.slot, + participants, + ) + return spec.SyncAggregate( + sync_committee_bits=[index in participants for index in committee_indices], + sync_committee_signature=signature, + ) diff --git a/tests/core/pyspec/eth2spec/test/utils/random.py b/tests/core/pyspec/eth2spec/test/utils/random.py index b50a67349..5a7067b3f 100644 --- a/tests/core/pyspec/eth2spec/test/utils/random.py +++ b/tests/core/pyspec/eth2spec/test/utils/random.py @@ -47,8 +47,8 @@ BLOCK_TRANSITIONS_COUNT = 2 # primitives ## state -def randomize_state(spec, state): - randomize_state_helper(spec, state, exit_fraction=0.1, slash_fraction=0.1) +def randomize_state(spec, state, exit_fraction=0.1, slash_fraction=0.1): + randomize_state_helper(spec, state, exit_fraction=exit_fraction, slash_fraction=slash_fraction) ## epochs diff --git a/tests/generators/sanity/main.py b/tests/generators/sanity/main.py index 63efa3897..89e622f1c 100644 --- a/tests/generators/sanity/main.py +++ b/tests/generators/sanity/main.py @@ -10,6 +10,7 @@ if __name__ == "__main__": ]} altair_mods = {**{key: 'eth2spec.test.altair.sanity.test_' + key for key in [ 'blocks', + 'blocks_random', ]}, **phase_0_mods} # also run the previous phase 0 tests # Altair-specific test cases are ignored, but should be included after the Merge is rebased onto Altair work.