Merge branch 'dev' into SyncCommitteeSignature-to-SyncCommitteeMessage

This commit is contained in:
Hsiao-Wei Wang 2021-06-03 22:13:53 +08:00
commit 45d554aee8
No known key found for this signature in database
GPG Key ID: 1111A8A81778319E
4 changed files with 35 additions and 35 deletions

View File

@ -137,8 +137,8 @@ This patch updates a few configuration values to move penalty parameters closer
| Name | Value | Description |
| - | - | - |
| `INACTIVITY_SCORE_BIAS` | `uint64(4)` | score points per inactive epoch |
| `INACTIVITY_SCORE_RECOVERY_RATE` | `uint64(16)` | score points per recovering epoch |
| `INACTIVITY_SCORE_BIAS` | `uint64(2**2)` (= 4) | score points per inactive epoch |
| `INACTIVITY_SCORE_RECOVERY_RATE` | `uint64(2**4)` (= 16) | score points per leak-free epoch |
## Containers
@ -157,8 +157,7 @@ class BeaconBlockBody(Container):
attestations: List[Attestation, MAX_ATTESTATIONS]
deposits: List[Deposit, MAX_DEPOSITS]
voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS]
# [New in Altair]
sync_aggregate: SyncAggregate
sync_aggregate: SyncAggregate # [New in Altair]
```
#### `BeaconState`
@ -266,10 +265,7 @@ def has_flag(flags: ParticipationFlags, flag_index: int) -> bool:
```python
def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorIndex]:
"""
Return the sequence of sync committee indices (which may include duplicate indices)
for the next sync committee, given a ``state`` at a sync committee period boundary.
Note: Committee can contain duplicate indices for small validator sets (< SYNC_COMMITTEE_SIZE + 128)
Return the sync committee indices, with possible duplicates, for the next sync committee.
"""
epoch = Epoch(get_current_epoch(state) + 1)
@ -292,21 +288,12 @@ def get_next_sync_committee_indices(state: BeaconState) -> Sequence[ValidatorInd
#### `get_next_sync_committee`
*Note*: The function `get_next_sync_committee` should only be called at sync committee period boundaries.
```python
def get_next_sync_committee(state: BeaconState) -> SyncCommittee:
"""
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_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 by ``process_sync_committee_updates``
as ``get_next_sync_committee_indices`` is not stable within a given period.
Return the next sync committee, with possible pubkey duplicates.
"""
indices = get_next_sync_committee_indices(state)
pubkeys = [state.validators[index].pubkey for index in indices]
@ -325,14 +312,12 @@ def get_base_reward_per_increment(state: BeaconState) -> Gwei:
*Note*: The function `get_base_reward` is modified with the removal of `BASE_REWARDS_PER_EPOCH` and the use of increment based accounting.
*Note*: On average an optimally performing validator earns one base reward per epoch.
```python
def get_base_reward(state: BeaconState, index: ValidatorIndex) -> Gwei:
"""
Return the base reward for the validator defined by ``index`` with respect to the current ``state``.
Note: An optimally performing validator can earn one base reward per epoch over a long time horizon.
This takes into account both per-epoch (e.g. attestation) and intermittent duties (e.g. block proposal
and sync committees).
"""
increments = state.validators[index].effective_balance // EFFECTIVE_BALANCE_INCREMENT
return Gwei(increments * get_base_reward_per_increment(state))
@ -559,6 +544,8 @@ def process_deposit(state: BeaconState, deposit: Deposit) -> None:
#### Sync committee processing
*Note*: The function `process_sync_committee` is new.
```python
def process_sync_committee(state: BeaconState, aggregate: SyncAggregate) -> None:
# Verify sync committee aggregate signature signing over the previous slot block root
@ -627,17 +614,17 @@ def process_justification_and_finalization(state: BeaconState) -> None:
```python
def process_inactivity_updates(state: BeaconState) -> None:
# Score updates based on previous epoch participation, skip genesis epoch
# Skip the genesis epoch as score updates are based on the previous epoch participation
if get_current_epoch(state) == GENESIS_EPOCH:
return
for index in get_eligible_validator_indices(state):
# Increase inactivity score of inactive validators
# Increase the inactivity score of inactive validators
if index in get_unslashed_participating_indices(state, TIMELY_TARGET_FLAG_INDEX, get_previous_epoch(state)):
state.inactivity_scores[index] -= min(1, state.inactivity_scores[index])
else:
state.inactivity_scores[index] += INACTIVITY_SCORE_BIAS
# Decrease the score of all validators for forgiveness when not during a leak
# Decrease the inactivity score of all eligible validators during a leak-free epoch
if not is_in_inactivity_leak(state):
state.inactivity_scores[index] -= min(INACTIVITY_SCORE_RECOVERY_RATE, state.inactivity_scores[index])
```

View File

@ -282,7 +282,12 @@ def get_sync_committee_message(state: BeaconState,
signing_root = compute_signing_root(block_root, domain)
signature = bls.Sign(privkey, signing_root)
return SyncCommitteeMessage(slot=state.slot, validator_index=validator_index, signature=signature)
return SyncCommitteeMessage(
slot=state.slot,
beacon_block_root=block_root,
validator_index=validator_index,
signature=signature,
)
```
##### Broadcast sync committee message

View File

@ -1,7 +1,7 @@
import random
from eth2spec.test.context import fork_transition_test
from eth2spec.test.helpers.constants import PHASE0, ALTAIR
from eth2spec.test.helpers.state import state_transition_and_sign_block, next_slot, next_epoch_via_block
from eth2spec.test.helpers.state import state_transition_and_sign_block, next_slot, next_epoch_via_signed_block
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, build_empty_block, sign_block
from eth2spec.test.helpers.attestations import next_slots_with_attestations
@ -261,12 +261,12 @@ def _run_transition_test_with_attestations(state,
assert current_epoch == spec.GENESIS_EPOCH
# skip genesis epoch to avoid dealing with some edge cases...
block = next_epoch_via_block(spec, state)
block = next_epoch_via_signed_block(spec, state)
# regular state transition until fork:
fill_cur_epoch = False
fill_prev_epoch = True
blocks = [pre_tag(sign_block(spec, state, block))]
blocks = [pre_tag(block)]
current_epoch = spec.get_current_epoch(state)
for _ in range(current_epoch, fork_epoch - 1):
_, blocks_in_epoch, state = next_slots_with_attestations(
@ -414,8 +414,8 @@ def test_transition_with_no_attestations_until_after_fork(state, fork_epoch, spe
# continue regular state transition but add attestations
# for enough epochs to finalize the ``fork_epoch``
block = next_epoch_via_block(post_spec, state)
blocks.append(post_tag(sign_block(post_spec, state, block)))
block = next_epoch_via_signed_block(post_spec, state)
blocks.append(post_tag(block))
for _ in range(4):
_, blocks_in_epoch, state = next_slots_with_attestations(
post_spec,

View File

@ -58,11 +58,19 @@ def next_epoch(spec, state):
spec.process_slots(state, slot)
def next_epoch_via_block(spec, state):
def next_epoch_via_block(spec, state, insert_state_root=False):
"""
Transition to the start slot of the next epoch via a full block transition
"""
return apply_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH)
block = apply_empty_block(spec, state, state.slot + spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH)
if insert_state_root:
block.state_root = state.hash_tree_root()
return block
def next_epoch_via_signed_block(spec, state):
block = next_epoch_via_block(spec, state, insert_state_root=True)
return sign_block(spec, state, block)
def get_state_root(spec, state, slot) -> bytes: