def _process_validator_registry_without_update( state: BeaconState, config: BeaconConfig) -> BeaconState: epochs_since_last_registry_update = ( state.current_epoch(config.SLOTS_PER_EPOCH) - state.validator_registry_update_epoch) if epochs_since_last_registry_update <= 1: return state if is_power_of_two(epochs_since_last_registry_update): # Update step-by-step since updated `state.current_shuffling_epoch` # is used to calculate other value). Follow the spec tightly now. state = _update_shuffling_epoch(state, config.SLOTS_PER_EPOCH) # NOTE: We do NOT update the "start shard" as we have not # produced a full set of new crosslinks; validators should have a chance to # complete this goal in future epochs. state = _update_shuffling_seed( state, config.SLOTS_PER_EPOCH, config.MIN_SEED_LOOKAHEAD, config.ACTIVATION_EXIT_DELAY, config.LATEST_ACTIVE_INDEX_ROOTS_LENGTH, config.LATEST_RANDAO_MIXES_LENGTH, ) return state
def process_validator_registry(state: BeaconState, config: BeaconConfig) -> BeaconState: state = state.copy( previous_epoch_calculation_slot=state.current_epoch_calculation_slot, previous_epoch_start_shard=state.current_epoch_start_shard, previous_epoch_seed=state.current_epoch_seed, ) state = _update_latest_index_roots(state, config) need_to_update, num_shards_in_committees = _check_if_update_validator_registry( state, config) if need_to_update: state = update_validator_registry(state) # Update step-by-step since updated `state.current_epoch_calculation_slot` # is used to calculate other value). Follow the spec tightly now. state = state.copy(current_epoch_calculation_slot=state.slot, ) state = state.copy( current_epoch_start_shard=(state.current_epoch_start_shard + num_shards_in_committees) % config.SHARD_COUNT, ) # The `helpers.generate_seed` function is only present to provide an entry point # for mocking this out in tests. current_epoch_seed = helpers.generate_seed( state=state, slot=state.current_epoch_calculation_slot, epoch_length=config.EPOCH_LENGTH, seed_lookahead=config.SEED_LOOKAHEAD, latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ) state = state.copy(current_epoch_seed=current_epoch_seed, ) else: epochs_since_last_registry_change = ( state.slot - state.validator_registry_update_slot) // config.EPOCH_LENGTH if is_power_of_two(epochs_since_last_registry_change): # Update step-by-step since updated `state.current_epoch_calculation_slot` # is used to calculate other value). Follow the spec tightly now. state = state.copy(current_epoch_calculation_slot=state.slot, ) # The `helpers.generate_seed` function is only present to provide an entry point # for mocking this out in tests. current_epoch_seed = helpers.generate_seed( state=state, slot=state.current_epoch_calculation_slot, epoch_length=config.EPOCH_LENGTH, seed_lookahead=config.SEED_LOOKAHEAD, latest_index_roots_length=config.LATEST_INDEX_ROOTS_LENGTH, latest_randao_mixes_length=config.LATEST_RANDAO_MIXES_LENGTH, ) state = state.copy(current_epoch_seed=current_epoch_seed, ) else: pass return state
def process_validator_registry(state: BeaconState, config: BeaconConfig) -> BeaconState: state = state.copy( previous_epoch_calculation_slot=state.current_epoch_calculation_slot, previous_epoch_start_shard=state.current_epoch_start_shard, previous_epoch_randao_mix=state.current_epoch_randao_mix, ) need_to_update, num_shards_in_committees = _check_if_update_validator_registry(state, config) if need_to_update: state = update_validator_registry(state) # Update step-by-step since updated `state.current_epoch_calculation_slot` # is used to calculate other value). Follow the spec tightly now. state = state.copy( current_epoch_calculation_slot=state.slot, ) state = state.copy( current_epoch_start_shard=( state.current_epoch_start_shard + num_shards_in_committees ) % config.SHARD_COUNT, ) state = state.copy( current_epoch_randao_mix=get_randao_mix( state, state.current_epoch_calculation_slot - config.SEED_LOOKAHEAD, config.LATEST_RANDAO_MIXES_LENGTH, ), ) else: epochs_since_last_registry_change = ( state.slot - state.validator_registry_update_slot ) // config.EPOCH_LENGTH if is_power_of_two(epochs_since_last_registry_change): # Update step-by-step since updated `state.current_epoch_calculation_slot` # is used to calculate other value). Follow the spec tightly now. state = state.copy( current_epoch_calculation_slot=state.slot, ) state = state.copy( current_epoch_randao_mix=get_randao_mix( state, state.current_epoch_calculation_slot - config.SEED_LOOKAHEAD, config.LATEST_RANDAO_MIXES_LENGTH, ), ) return state
def _process_validator_registry_without_update( state: BeaconState, config: Eth2Config) -> BeaconState: epochs_since_last_registry_update = ( state.current_epoch(config.SLOTS_PER_EPOCH) - state.validator_registry_update_epoch) if epochs_since_last_registry_update <= 1: return state if is_power_of_two(epochs_since_last_registry_update): # Update step-by-step since updated `state.current_shuffling_epoch` # is used to calculate other value). Follow the spec tightly now. state = _update_shuffling_epoch(state, config.SLOTS_PER_EPOCH) # NOTE: We do NOT update the "start shard" as we have not # produced a full set of new crosslinks; validators should have a chance to # complete this goal in future epochs. state = _update_shuffling_seed(state, CommitteeConfig(config)) return state
def get_crosslink_committees_at_slot( state: 'BeaconState', slot: SlotNumber, committee_config: CommitteeConfig, registry_change: bool = False ) -> Iterable[Tuple[Iterable[ValidatorIndex], ShardNumber]]: """ Return the list of ``(committee, shard)`` tuples for the ``slot``. """ genesis_epoch = committee_config.GENESIS_EPOCH shard_count = committee_config.SHARD_COUNT epoch_length = committee_config.EPOCH_LENGTH target_committee_size = committee_config.TARGET_COMMITTEE_SIZE seed_lookahead = committee_config.SEED_LOOKAHEAD entry_exit_delay = committee_config.ENTRY_EXIT_DELAY latest_index_roots_length = committee_config.LATEST_INDEX_ROOTS_LENGTH latest_randao_mixes_length = committee_config.LATEST_RANDAO_MIXES_LENGTH epoch = slot_to_epoch(slot, epoch_length) current_epoch = state.current_epoch(epoch_length) previous_epoch = state.previous_epoch(epoch_length, genesis_epoch) next_epoch = state.next_epoch(epoch_length) validate_epoch_for_current_epoch( current_epoch=current_epoch, given_epoch=epoch, genesis_epoch=genesis_epoch, ) if epoch == previous_epoch: committees_per_epoch = get_previous_epoch_committee_count( state=state, shard_count=shard_count, epoch_length=epoch_length, target_committee_size=target_committee_size, ) seed = state.previous_epoch_seed shuffling_epoch = state.previous_calculation_epoch shuffling_start_shard = state.previous_epoch_start_shard elif epoch == current_epoch: committees_per_epoch = get_current_epoch_committee_count( state=state, shard_count=shard_count, epoch_length=epoch_length, target_committee_size=target_committee_size, ) seed = state.current_epoch_seed shuffling_epoch = state.current_calculation_epoch shuffling_start_shard = state.current_epoch_start_shard elif epoch == next_epoch: current_committees_per_epoch = get_current_epoch_committee_count( state=state, shard_count=shard_count, epoch_length=epoch_length, target_committee_size=target_committee_size, ) committees_per_epoch = get_next_epoch_committee_count( state=state, shard_count=shard_count, epoch_length=epoch_length, target_committee_size=target_committee_size, ) shuffling_epoch = next_epoch epochs_since_last_registry_update = current_epoch - state.validator_registry_update_epoch should_reseed = (epochs_since_last_registry_update > 1 and is_power_of_two(epochs_since_last_registry_update)) if registry_change: # for mocking this out in tests. seed = helpers.generate_seed( state=state, epoch=next_epoch, epoch_length=epoch_length, seed_lookahead=seed_lookahead, entry_exit_delay=entry_exit_delay, latest_index_roots_length=latest_index_roots_length, latest_randao_mixes_length=latest_randao_mixes_length, ) shuffling_start_shard = ( state.current_epoch_start_shard + current_committees_per_epoch) % shard_count elif should_reseed: # for mocking this out in tests. seed = helpers.generate_seed( state=state, epoch=next_epoch, epoch_length=epoch_length, seed_lookahead=seed_lookahead, entry_exit_delay=entry_exit_delay, latest_index_roots_length=latest_index_roots_length, latest_randao_mixes_length=latest_randao_mixes_length, ) shuffling_start_shard = state.current_epoch_start_shard else: seed = state.current_epoch_seed shuffling_start_shard = state.current_epoch_start_shard shuffling = get_shuffling( seed=seed, validators=state.validator_registry, epoch=shuffling_epoch, epoch_length=epoch_length, target_committee_size=target_committee_size, shard_count=shard_count, ) offset = slot % epoch_length committees_per_slot = committees_per_epoch // epoch_length slot_start_shard = (shuffling_start_shard + committees_per_slot * offset) % shard_count for index in range(committees_per_slot): committee = shuffling[committees_per_slot * offset + index] yield ( committee, ShardNumber((slot_start_shard + index) % shard_count), )
def get_crosslink_committees_at_slot( state: 'BeaconState', slot: Slot, committee_config: CommitteeConfig, registry_change: bool=False) -> Iterable[Tuple[Sequence[ValidatorIndex], Shard]]: """ Return the list of ``(committee, shard)`` tuples for the ``slot``. """ shard_count = committee_config.SHARD_COUNT slots_per_epoch = committee_config.SLOTS_PER_EPOCH 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 = state.next_epoch(slots_per_epoch) validate_epoch_within_previous_and_next(epoch, previous_epoch, next_epoch) if epoch == current_epoch: shuffling_context = _get_shuffling_context_is_current_epoch(state, committee_config) elif epoch == previous_epoch: shuffling_context = _get_shuffling_context_is_previous_epoch(state, committee_config) elif epoch == next_epoch: epochs_since_last_registry_update = current_epoch - state.validator_registry_update_epoch should_reseed = ( epochs_since_last_registry_update > 1 and is_power_of_two(epochs_since_last_registry_update) ) if registry_change: shuffling_context = _get_shuffling_contextis_next_epoch_registry_change( state, next_epoch, committee_config, ) elif should_reseed: shuffling_context = _get_shuffling_contextis_next_epoch_should_reseed( state, next_epoch, committee_config, ) else: shuffling_context = _get_shuffling_contextis_next_epoch_no_registry_change_no_reseed( state, committee_config, ) shuffling = get_shuffling( seed=shuffling_context.seed, validators=state.validator_registry, epoch=shuffling_context.shuffling_epoch, committee_config=committee_config, ) offset = slot % slots_per_epoch committees_per_slot = shuffling_context.committees_per_epoch // slots_per_epoch slot_start_shard = ( shuffling_context.shuffling_start_shard + committees_per_slot * offset ) % shard_count for index in range(committees_per_slot): committee = shuffling[committees_per_slot * offset + index] yield ( committee, Shard((slot_start_shard + index) % shard_count), )
def test_is_power_of_two(value): expected = slow_is_power_of_two(value) assert expected == is_power_of_two(value)
def test_is_power_of_two(value): slow_expected = slow_is_power_of_two(value) fast_expected = fast_is_power_of_two(value) assert slow_expected == fast_expected assert fast_expected == is_power_of_two(value)