Merge pull request #549 from ethereum/registry_change

Misc fixes of `get_next_epoch_crosslink_committees`
This commit is contained in:
Danny Ryan 2019-02-07 13:31:57 -07:00 committed by GitHub
commit cc2df634cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 9 deletions

View File

@ -857,7 +857,7 @@ def get_next_epoch_committee_count(state: BeaconState) -> int:
```python ```python
def get_crosslink_committees_at_slot(state: BeaconState, def get_crosslink_committees_at_slot(state: BeaconState,
slot: SlotNumber, slot: SlotNumber,
registry_change=False: bool) -> List[Tuple[List[ValidatorIndex], ShardNumber]]: registry_change: bool=False) -> List[Tuple[List[ValidatorIndex], ShardNumber]]:
""" """
Return the list of ``(committee, shard)`` tuples for the ``slot``. Return the list of ``(committee, shard)`` tuples for the ``slot``.

View File

@ -344,24 +344,48 @@ Either (2) or (3) occurs if (1) fails. The choice between (2) and (3) is determi
`get_crosslink_committees_at_slot` is designed to be able to query slots in the next epoch. When querying slots in the next epoch there are two options -- with and without a `registry_change` -- which is the optional third parameter of the function. The following helper can be used to get the potential crosslink committees in the next epoch for a given `validator_index`. This function returns a list of 2 shard committee tuples. `get_crosslink_committees_at_slot` is designed to be able to query slots in the next epoch. When querying slots in the next epoch there are two options -- with and without a `registry_change` -- which is the optional third parameter of the function. The following helper can be used to get the potential crosslink committees in the next epoch for a given `validator_index`. This function returns a list of 2 shard committee tuples.
```python ```python
def get_next_epoch_crosslink_committees(state: BeaconState, def get_next_epoch_committee_assignments(
validator_index: ValidatorIndex) -> List[Tuple[ValidatorIndex], ShardNumber]: state: BeaconState,
validator_index: ValidatorIndex) -> List[Tuple[List[ValidatorIndex], ShardNumber, SlotNumber, bool]]:
"""
Return a list of the two possible committee assignments for ``validator_index`` at the next epoch.
Possible committee ``assignment`` is of the form (List[ValidatorIndex], ShardNumber, SlotNumber, bool).
* ``assignment[0]`` is the list of validators in the committee
* ``assignment[1]`` is the shard to which the committee is assigned
* ``assignment[2]`` is the slot at which the committee is assigned
* ``assignment[3]`` is a bool signalling if the validator is expected to propose
a beacon block at the assigned slot.
"""
current_epoch = get_current_epoch(state) current_epoch = get_current_epoch(state)
next_epoch = current_epoch + 1 next_epoch = current_epoch + 1
next_epoch_start_slot = get_epoch_start_slot(next_epoch) next_epoch_start_slot = get_epoch_start_slot(next_epoch)
potential_committees = [] potential_assignments = []
for validator_registry in [False, True]: for registry_change in [False, True]:
for slot in range(next_epoch_start_slot, next_epoch_start_slot + EPOCH_LENGTH): for slot in range(next_epoch_start_slot, next_epoch_start_slot + EPOCH_LENGTH):
shard_committees = get_crosslink_committees_at_slot(state, slot, validator_registry) crosslink_committees = get_crosslink_committees_at_slot(
selected_committees = [committee for committee in shard_committees if validator_index in committee[0]] state,
slot,
registry_change=registry_change,
)
selected_committees = [
committee # Tuple[List[ValidatorIndex], ShardNumber]
for committee in crosslink_committees
if validator_index in committee[0]
]
if len(selected_committees) > 0: if len(selected_committees) > 0:
potential_assignments.append(selected_committees) assignment = selected_committees[0]
assignment += (slot,)
first_committee_at_slot = crosslink_committees[0][0] # List[ValidatorIndex]
is_proposer = first_committee_at_slot[slot % len(first_committee_at_slot)] == validator_index
assignment += (is_proposer,)
potential_assignments.append(assignment)
break break
return potential_assignments return potential_assignments
``` ```
`get_next_epoch_crosslink_committees` should be called at the beginning of each epoch to plan for the next epoch. A validator should always plan for both values of `registry_change` as a possibility unless the validator can concretely eliminate one of the options. Planning for a future shuffling involves noting at which slot one might have to attest and propose and also which shard one should begin syncing (in phase 1+). `get_next_epoch_committee_assignments` should be called at the beginning of each epoch to plan for the next epoch. A validator should always plan for both values of `registry_change` as a possibility unless the validator can concretely eliminate one of the options. Planning for a future shuffling involves noting at which slot one might have to attest and propose and also which shard one should begin syncing (in phase 1+).
## How to avoid slashing ## How to avoid slashing