def test_proposer_in_committee_with_participation(spec, state): committee_indices = compute_committee_indices(spec, state, state.current_sync_committee) participation = [True for _ in committee_indices] # NOTE: seem to reliably be getting a matching proposer in the first epoch w/ ``MINIMAL`` preset. for _ in range(spec.SLOTS_PER_EPOCH): block = build_empty_block_for_next_slot(spec, state) proposer_index = block.proposer_index proposer_pubkey = state.validators[proposer_index].pubkey proposer_is_in_sync_committee = proposer_pubkey in state.current_sync_committee.pubkeys # Valid sync committee signature here... block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=participation, sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, block_root=block.parent_root, ) ) if proposer_is_in_sync_committee: assert state.validators[block.proposer_index].pubkey in state.current_sync_committee.pubkeys yield from run_sync_committee_processing(spec, state, block) return else: state_transition_and_sign_block(spec, state, block) raise AssertionError("failed to find a proposer in the sync committee set; check test setup")
def test_sync_committee_with_participating_withdrawable_member(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH # move forward via some blocks for _ in range(3): next_epoch_via_block(spec, state) committee_indices = compute_committee_indices(spec, state) rng = random.Random(1010) exited_index = _exit_validator_from_committee_and_transition_state( spec, state, committee_indices, rng, lambda v: v.withdrawable_epoch + 1, ) current_epoch = spec.get_current_epoch(state) assert current_epoch > state.validators[exited_index].withdrawable_epoch block = build_empty_block_for_next_slot(spec, state) block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(committee_indices), sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, # full committee signs block_root=block.parent_root, ) ) yield from run_sync_committee_processing(spec, state, block)
def test_invalid_signature_previous_committee(spec, state): # NOTE: the `state` provided is at genesis and the process to select # sync committees currently returns the same committee for the first and second # periods at genesis. # To get a distinct committee so we can generate an "old" signature, we need to advance # 2 EPOCHS_PER_SYNC_COMMITTEE_PERIOD periods. current_epoch = spec.get_current_epoch(state) old_sync_committee = state.next_sync_committee epoch_in_future_sync_commitee_period = current_epoch + 2 * spec.EPOCHS_PER_SYNC_COMMITTEE_PERIOD slot_in_future_sync_committee_period = epoch_in_future_sync_commitee_period * spec.SLOTS_PER_EPOCH transition_to(spec, state, slot_in_future_sync_committee_period) # Use the previous sync committee to produce the signature. # Ensure that the pubkey sets are different. assert set(old_sync_committee.pubkeys) != set(state.current_sync_committee.pubkeys) committee_indices = compute_committee_indices(spec, state, old_sync_committee) block = build_empty_block_for_next_slot(spec, state) block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(committee_indices), sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, block_root=block.parent_root, ) ) yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
def test_invalid_signature_past_block(spec, state): committee_indices = compute_committee_indices(spec, state) for _ in range(2): # NOTE: need to transition twice to move beyond the degenerate case at genesis block = build_empty_block_for_next_slot(spec, state) # Valid sync committee signature here... block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(committee_indices), sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, block_root=block.parent_root, ) ) state_transition_and_sign_block(spec, state, block) invalid_block = build_empty_block_for_next_slot(spec, state) # Invalid signature from a slot other than the previous invalid_block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(committee_indices), sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, invalid_block.slot - 2, committee_indices, ) ) yield from run_sync_committee_processing(spec, state, invalid_block, expect_exception=True)
def test_invalid_signature_infinite_signature_with_all_participants(spec, state): block = build_empty_block_for_next_slot(spec, state) # Include all participants, try the special-case signature for no-participants block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(block.body.sync_aggregate.sync_committee_bits), sync_committee_signature=spec.G2_POINT_AT_INFINITY ) yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
def test_invalid_signature_no_participants(spec, state): block = build_empty_block_for_next_slot(spec, state) # No participants is an allowed case, but needs a specific signature, not the full-zeroed signature. block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[False] * len(block.body.sync_aggregate.sync_committee_bits), sync_committee_signature=b'\x00' * 96 ) yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
def test_invalid_signature_bad_domain(spec, state): committee_indices = compute_committee_indices(spec, state) block = build_empty_block_for_next_slot(spec, state) block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(committee_indices), sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, # full committee signs block_root=block.parent_root, domain_type=spec.DOMAIN_BEACON_ATTESTER, # Incorrect domain ) ) yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
def test_invalid_signature_missing_participant(spec, state): committee_indices = compute_committee_indices(spec, state) rng = random.Random(2020) random_participant = rng.choice(committee_indices) block = build_empty_block_for_next_slot(spec, state) # Exclude one participant whose signature was included. block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[index != random_participant for index in committee_indices], sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, # full committee signs block_root=block.parent_root, ) ) yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
def test_invalid_signature_extra_participant(spec, state): committee_indices = compute_committee_indices(spec, state) rng = random.Random(3030) random_participant = rng.choice(committee_indices) block = build_empty_block_for_next_slot(spec, state) # Exclude one signature even though the block claims the entire committee participated. block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=[True] * len(committee_indices), sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, [index for index in committee_indices if index != random_participant], block_root=block.parent_root, ) ) yield from run_sync_committee_processing(spec, state, block, expect_exception=True)
def test_sync_committee_with_nonparticipating_exited_member(spec, state): # move state forward SHARD_COMMITTEE_PERIOD epochs to allow for exit state.slot += spec.config.SHARD_COMMITTEE_PERIOD * spec.SLOTS_PER_EPOCH # move forward via some blocks for _ in range(3): next_epoch_via_block(spec, state) committee_indices = compute_committee_indices(spec, state) rng = random.Random(1010) exited_index = _exit_validator_from_committee_and_transition_state( spec, state, committee_indices, rng, lambda v: v.exit_epoch, ) exited_pubkey = state.validators[exited_index].pubkey current_epoch = spec.get_current_epoch(state) assert current_epoch < state.validators[exited_index].withdrawable_epoch exited_committee_index = state.current_sync_committee.pubkeys.index(exited_pubkey) block = build_empty_block_for_next_slot(spec, state) committee_bits = [i != exited_committee_index for i in committee_indices] committee_indices = [index for index in committee_indices if index != exited_committee_index] block.body.sync_aggregate = spec.SyncAggregate( sync_committee_bits=committee_bits, sync_committee_signature=compute_aggregate_sync_committee_signature( spec, state, block.slot - 1, committee_indices, # with exited validator removed block_root=block.parent_root, ) ) yield from run_sync_committee_processing(spec, state, block)