Skip to content

Commit

Permalink
Merge pull request #2406 from ethereum/sync-seed
Browse files Browse the repository at this point in the history
remove sync committee seed and restrict period calculation boundaries
  • Loading branch information
djrtwo authored May 12, 2021
2 parents 84830e8 + 133875a commit 9a0be85
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 127 deletions.
39 changes: 19 additions & 20 deletions specs/altair/beacon-chain.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
- [`add_flag`](#add_flag)
- [`has_flag`](#has_flag)
- [Beacon state accessors](#beacon-state-accessors)
- [`get_sync_committee_indices`](#get_sync_committee_indices)
- [`get_sync_committee`](#get_sync_committee)
- [`get_next_sync_committee_indices`](#get_next_sync_committee_indices)
- [`get_next_sync_committee`](#get_next_sync_committee)
- [`get_base_reward_per_increment`](#get_base_reward_per_increment)
- [`get_base_reward`](#get_base_reward)
- [`get_unslashed_participating_indices`](#get_unslashed_participating_indices)
Expand Down Expand Up @@ -270,22 +270,20 @@ def has_flag(flags: ParticipationFlags, flag_index: int) -> bool:

### Beacon state accessors

#### `get_sync_committee_indices`
#### `get_next_sync_committee_indices`

```python
def get_sync_committee_indices(state: BeaconState, epoch: Epoch) -> Sequence[ValidatorIndex]:
def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorIndex]:
"""
Return the sequence of sync committee indices (which may include duplicate indices)
for a given ``state`` and ``epoch``.
Note: This function is not stable during a sync committee period as
a validator's effective balance may change enough to affect the sampling.
for the next sync committee, given a ``state`` at a sync committee period boundary.
"""
epoch = Epoch(get_current_epoch(state) + 1)

MAX_RANDOM_BYTE = 2**8 - 1
base_epoch = Epoch((max(epoch // EPOCHS_PER_SYNC_COMMITTEE_PERIOD, 1) - 1) * EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
active_validator_indices = get_active_validator_indices(state, base_epoch)
active_validator_indices = get_active_validator_indices(state, epoch)
active_validator_count = uint64(len(active_validator_indices))
seed = get_seed(state, base_epoch, DOMAIN_SYNC_COMMITTEE)
seed = get_seed(state, epoch, DOMAIN_SYNC_COMMITTEE)
i = 0
sync_committee_indices: List[ValidatorIndex] = []
while len(sync_committee_indices) < SYNC_COMMITTEE_SIZE:
Expand All @@ -299,25 +297,25 @@ def get_sync_committee_indices(state: BeaconState, epoch: Epoch) -> Sequence[Val
return sync_committee_indices
```

#### `get_sync_committee`
#### `get_next_sync_committee`

```python
def get_sync_committee(state: BeaconState, epoch: Epoch) -> SyncCommittee:
def get_next_sync_committee(state: BeaconState) -> SyncCommittee:
"""
Return the sync committee for a given ``state`` and ``epoch``.
Return the *next* sync committee for a given ``state``.
``SyncCommittee`` contains an aggregate pubkey that enables
resource-constrained clients to save some computation when verifying
the sync committee's signature.
``SyncCommittee`` can also contain duplicate pubkeys, when ``get_sync_committee_indices``
``SyncCommittee`` can also contain duplicate pubkeys, when ``get_next_sync_committee_indices``
returns duplicate indices. Implementations must take care when handling
optimizations relating to aggregation and verification in the presence of duplicates.
Note: This function should only be called at sync committee period boundaries, as
``get_sync_committee_indices`` is not stable within a given period.
``get_next_sync_committee_indices`` is not stable within a given period.
"""
indices = get_sync_committee_indices(state, epoch)
indices = get_next_sync_committee_indices(state)
pubkeys = [state.validators[index].pubkey for index in indices]
aggregate_pubkey = bls.AggregatePKs(pubkeys)
return SyncCommittee(pubkeys=pubkeys, aggregate_pubkey=aggregate_pubkey)
Expand Down Expand Up @@ -690,7 +688,7 @@ def process_sync_committee_updates(state: BeaconState) -> None:
next_epoch = get_current_epoch(state) + Epoch(1)
if next_epoch % EPOCHS_PER_SYNC_COMMITTEE_PERIOD == 0:
state.current_sync_committee = state.next_sync_committee
state.next_sync_committee = get_sync_committee(state, next_epoch + EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
state.next_sync_committee = get_next_sync_committee(state)
```

## Initialize state for pure Altair testnets and test vectors
Expand Down Expand Up @@ -735,8 +733,9 @@ def initialize_beacon_state_from_eth1(eth1_block_hash: Bytes32,
state.genesis_validators_root = hash_tree_root(state.validators)

# [New in Altair] Fill in sync committees
state.current_sync_committee = get_sync_committee(state, get_current_epoch(state))
state.next_sync_committee = get_sync_committee(state, get_current_epoch(state) + EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
# Note: A duplicate committee is assigned for the current and next committee at genesis
state.current_sync_committee = get_next_sync_committee(state)
state.next_sync_committee = get_next_sync_committee(state)

return state
```
6 changes: 4 additions & 2 deletions specs/altair/fork.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ def upgrade_to_altair(pre: phase0.BeaconState) -> BeaconState:
# Inactivity
inactivity_scores=[uint64(0) for _ in range(len(pre.validators))],
)

# Fill in sync committees
post.current_sync_committee = get_sync_committee(post, get_current_epoch(post))
post.next_sync_committee = get_sync_committee(post, get_current_epoch(post) + EPOCHS_PER_SYNC_COMMITTEE_PERIOD)
# Note: A duplicate committee is assigned for the current and next committee at the fork boundary
post.current_sync_committee = get_next_sync_committee(post)
post.next_sync_committee = get_next_sync_committee(post)
return post
```
Loading

0 comments on commit 9a0be85

Please sign in to comment.