def test_get_next_epoch_committee_count(n_validators_state, shard_count, slots_per_epoch, target_committee_size, expected_committee_count, config): state = n_validators_state current_epoch_committee_count = get_current_epoch_committee_count( state, shard_count, slots_per_epoch, target_committee_size, ) next_epoch_committee_count = get_next_epoch_committee_count( state, shard_count, slots_per_epoch, target_committee_size, ) assert current_epoch_committee_count == expected_committee_count assert next_epoch_committee_count == expected_committee_count # Exit all validators exit_epoch = state.current_epoch(slots_per_epoch) + 1 for index, validator in enumerate(state.validator_registry): state = state.update_validator_registry( validator_index=index, validator=validator.copy( exit_epoch=exit_epoch, ), ) current_epoch_committee_count = get_current_epoch_committee_count( state, shard_count, slots_per_epoch, target_committee_size, ) next_epoch_committee_count = get_next_epoch_committee_count( state, shard_count, slots_per_epoch, target_committee_size, ) assert current_epoch_committee_count == expected_committee_count assert next_epoch_committee_count == slots_per_epoch
def test_check_if_update_validator_registry(genesis_state, state_slot, validator_registry_update_epoch, finalized_epoch, has_crosslink, crosslink_epoch, expected_need_to_update, config): state = genesis_state.copy( slot=state_slot, finalized_epoch=finalized_epoch, validator_registry_update_epoch=validator_registry_update_epoch, ) if has_crosslink: crosslink = CrosslinkRecord( epoch=crosslink_epoch, crosslink_data_root=ZERO_HASH32, ) latest_crosslinks = state.latest_crosslinks for shard in range(config.SHARD_COUNT): latest_crosslinks = update_tuple_item( latest_crosslinks, shard, crosslink, ) state = state.copy( latest_crosslinks=latest_crosslinks, ) need_to_update, num_shards_in_committees = _check_if_update_validator_registry(state, config) assert need_to_update == expected_need_to_update if expected_need_to_update: expected_num_shards_in_committees = get_current_epoch_committee_count( state, shard_count=config.SHARD_COUNT, slots_per_epoch=config.SLOTS_PER_EPOCH, target_committee_size=config.TARGET_COMMITTEE_SIZE, ) assert num_shards_in_committees == expected_num_shards_in_committees else: assert num_shards_in_committees == 0
def _check_if_update_validator_registry( state: BeaconState, config: BeaconConfig) -> Tuple[bool, int]: if state.finalized_epoch <= state.validator_registry_update_epoch: return False, 0 current_epoch_committee_count = get_current_epoch_committee_count( state, shard_count=config.SHARD_COUNT, slots_per_epoch=config.SLOTS_PER_EPOCH, target_committee_size=config.TARGET_COMMITTEE_SIZE, ) # Get every shard in the current committees shards = set((state.current_shuffling_start_shard + i) % config.SHARD_COUNT for i in range(current_epoch_committee_count)) for shard in shards: if state.latest_crosslinks[ shard].epoch <= state.validator_registry_update_epoch: return False, 0 return True, current_epoch_committee_count
def _check_if_update_validator_registry( state: BeaconState, config: BeaconConfig) -> Tuple[bool, int]: if state.finalized_epoch <= state.validator_registry_update_epoch: return False, 0 num_shards_in_committees = get_current_epoch_committee_count( state, shard_count=config.SHARD_COUNT, epoch_length=config.EPOCH_LENGTH, target_committee_size=config.TARGET_COMMITTEE_SIZE, ) # Get every shard in the current committees shards = set((state.current_epoch_start_shard + i) % config.SHARD_COUNT for i in range(num_shards_in_committees)) for shard in shards: if state.latest_crosslinks[ shard].epoch <= state.validator_registry_update_epoch: return False, 0 return True, num_shards_in_committees
def test_get_crosslink_committees_at_slot( monkeypatch, genesis_slot, n_validators_state, current_slot, slot, slots_per_epoch, target_committee_size, shard_count, genesis_epoch, committee_config, registry_change, should_reseed, previous_shuffling_epoch, current_shuffling_epoch, shuffling_epoch): # Mock generate_seed new_seed = b'\x88' * 32 def mock_generate_seed(state, epoch, committee_config): return new_seed monkeypatch.setattr('eth2.beacon.helpers.generate_seed', mock_generate_seed) state = n_validators_state.copy( slot=current_slot, previous_shuffling_epoch=previous_shuffling_epoch, current_shuffling_epoch=current_shuffling_epoch, previous_shuffling_seed=b'\x11' * 32, current_shuffling_seed=b'\x22' * 32, ) crosslink_committees_at_slot = get_crosslink_committees_at_slot( state=state, slot=slot, committee_config=committee_config, registry_change=registry_change, ) assert len(crosslink_committees_at_slot) > 0 for crosslink_committee in crosslink_committees_at_slot: committee, shard = crosslink_committee assert len(committee) > 0 assert shard < shard_count # # Check shuffling_start_shard # offset = slot % slots_per_epoch result_slot_start_shard = crosslink_committees_at_slot[0][1] current_committees_per_epoch = get_current_epoch_committee_count( state=state, shard_count=shard_count, slots_per_epoch=slots_per_epoch, target_committee_size=target_committee_size, ) if registry_change: committees_per_epoch = current_committees_per_epoch shuffling_start_shard = (state.current_shuffling_start_shard + current_committees_per_epoch) % shard_count elif should_reseed: committees_per_epoch = get_next_epoch_committee_count( state=state, shard_count=shard_count, slots_per_epoch=slots_per_epoch, target_committee_size=target_committee_size, ) shuffling_start_shard = state.current_shuffling_start_shard else: committees_per_epoch = current_committees_per_epoch shuffling_start_shard = state.current_shuffling_start_shard committees_per_slot = committees_per_epoch // slots_per_epoch assert result_slot_start_shard == ( shuffling_start_shard + committees_per_slot * offset) % shard_count # # Check seed # epoch = slot_to_epoch(slot, slots_per_epoch) current_epoch = state.current_epoch(slots_per_epoch) previous_epoch = state.previous_epoch(slots_per_epoch) next_epoch = current_epoch + 1 if epoch == current_epoch: seed = state.current_shuffling_seed elif epoch == previous_epoch: seed = state.previous_shuffling_seed elif epoch == next_epoch: if registry_change or should_reseed: seed = new_seed else: seed = state.current_shuffling_seed shuffling = get_shuffling( seed=seed, validators=state.validator_registry, epoch=shuffling_epoch, committee_config=committee_config, ) assert shuffling[committees_per_slot * offset] == crosslink_committees_at_slot[0][0]