Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
d29cbd6535
|
@ -69,7 +69,7 @@
|
||||||
- [`get_shuffling`](#get_shuffling)
|
- [`get_shuffling`](#get_shuffling)
|
||||||
- [`get_previous_epoch_committee_count_per_slot`](#get_previous_epoch_committee_count_per_slot)
|
- [`get_previous_epoch_committee_count_per_slot`](#get_previous_epoch_committee_count_per_slot)
|
||||||
- [`get_current_epoch_committee_count_per_slot`](#get_current_epoch_committee_count_per_slot)
|
- [`get_current_epoch_committee_count_per_slot`](#get_current_epoch_committee_count_per_slot)
|
||||||
- [`get_shard_committees_at_slot`](#get_shard_committees_at_slot)
|
- [`get_crosslink_committees_at_slot`](#get_crosslink_committees_at_slot)
|
||||||
- [`get_block_root`](#get_block_root)
|
- [`get_block_root`](#get_block_root)
|
||||||
- [`get_randao_mix`](#get_randao_mix)
|
- [`get_randao_mix`](#get_randao_mix)
|
||||||
- [`get_beacon_proposer_index`](#get_beacon_proposer_index)
|
- [`get_beacon_proposer_index`](#get_beacon_proposer_index)
|
||||||
|
@ -850,7 +850,7 @@ def shuffle(values: List[Any], seed: Hash32) -> List[Any]:
|
||||||
#### `split`
|
#### `split`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def split(values: List[Any], split_count: int) -> List[Any]:
|
def split(values: List[Any], split_count: int) -> List[List[Any]]:
|
||||||
"""
|
"""
|
||||||
Splits ``values`` into ``split_count`` pieces.
|
Splits ``values`` into ``split_count`` pieces.
|
||||||
"""
|
"""
|
||||||
|
@ -881,7 +881,7 @@ def get_shuffling(seed: Hash32,
|
||||||
validators: List[ValidatorRecord],
|
validators: List[ValidatorRecord],
|
||||||
slot: int) -> List[List[int]]
|
slot: int) -> List[List[int]]
|
||||||
"""
|
"""
|
||||||
Shuffles ``validators`` into shard committees seeded by ``seed`` and ``slot``.
|
Shuffles ``validators`` into crosslink committees seeded by ``seed`` and ``slot``.
|
||||||
Returns a list of ``EPOCH_LENGTH * committees_per_slot`` committees where each
|
Returns a list of ``EPOCH_LENGTH * committees_per_slot`` committees where each
|
||||||
committee is itself a list of validator indices.
|
committee is itself a list of validator indices.
|
||||||
"""
|
"""
|
||||||
|
@ -927,11 +927,11 @@ def get_current_epoch_committee_count_per_slot(state: BeaconState) -> int:
|
||||||
return get_committee_count_per_slot(len(current_active_validators))
|
return get_committee_count_per_slot(len(current_active_validators))
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `get_shard_committees_at_slot`
|
#### `get_crosslink_committees_at_slot`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def get_shard_committees_at_slot(state: BeaconState,
|
def get_crosslink_committees_at_slot(state: BeaconState,
|
||||||
slot: int) -> List[Tuple[List[int], int]]:
|
slot: int) -> List[Tuple[List[int], int]]:
|
||||||
"""
|
"""
|
||||||
Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
||||||
"""
|
"""
|
||||||
|
@ -981,7 +981,7 @@ def get_block_root(state: BeaconState,
|
||||||
return state.latest_block_roots[slot % LATEST_BLOCK_ROOTS_LENGTH]
|
return state.latest_block_roots[slot % LATEST_BLOCK_ROOTS_LENGTH]
|
||||||
```
|
```
|
||||||
|
|
||||||
`get_block_root(_, s)` should always return `hash_tree_root` of the block in the beacon chain at slot `s`, and `get_shard_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes.
|
`get_block_root(_, s)` should always return `hash_tree_root` of the block in the beacon chain at slot `s`, and `get_crosslink_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes.
|
||||||
|
|
||||||
#### `get_randao_mix`
|
#### `get_randao_mix`
|
||||||
|
|
||||||
|
@ -1004,14 +1004,14 @@ def get_beacon_proposer_index(state: BeaconState,
|
||||||
"""
|
"""
|
||||||
Returns the beacon proposer index for the ``slot``.
|
Returns the beacon proposer index for the ``slot``.
|
||||||
"""
|
"""
|
||||||
first_committee, _ = get_shard_committees_at_slot(state, slot)[0]
|
first_committee, _ = get_crosslink_committees_at_slot(state, slot)[0]
|
||||||
return first_committee[slot % len(first_committee)]
|
return first_committee[slot % len(first_committee)]
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `merkle_root`
|
#### `merkle_root`
|
||||||
|
|
||||||
```python
|
```python
|
||||||
def merkle_root(values):
|
def merkle_root(values: List[Hash32]) -> Hash32:
|
||||||
"""
|
"""
|
||||||
Merkleize ``values`` (where ``len(values)`` is a power of two) and return the Merkle root.
|
Merkleize ``values`` (where ``len(values)`` is a power of two) and return the Merkle root.
|
||||||
"""
|
"""
|
||||||
|
@ -1032,15 +1032,15 @@ def get_attestation_participants(state: BeaconState,
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Find the committee in the list with the desired shard
|
# Find the committee in the list with the desired shard
|
||||||
shard_committees = get_shard_committees_at_slot(state, attestation_data.slot)
|
crosslink_committees = get_crosslink_committees_at_slot(state, attestation_data.slot)
|
||||||
|
|
||||||
assert attestation.shard in [shard for _, shard in shard_committees]
|
assert attestation_data.shard in [shard for _, shard in crosslink_committees]
|
||||||
shard_committee = [committee for committee, shard in shard_committees if shard == attestation_data.shard][0]
|
crosslink_committee = [committee for committee, shard in crosslink_committees if shard == attestation_data.shard][0]
|
||||||
assert len(participation_bitfield) == (len(committee) + 7) // 8
|
assert len(participation_bitfield) == (len(committee) + 7) // 8
|
||||||
|
|
||||||
# Find the participating attesters in the committee
|
# Find the participating attesters in the committee
|
||||||
participants = []
|
participants = []
|
||||||
for i, validator_index in enumerate(shard_committee):
|
for i, validator_index in enumerate(crosslink_committee):
|
||||||
participation_bit = (participation_bitfield[i//8] >> (7 - (i % 8))) % 2
|
participation_bit = (participation_bitfield[i//8] >> (7 - (i % 8))) % 2
|
||||||
if participation_bit == 1:
|
if participation_bit == 1:
|
||||||
participants.append(validator_index)
|
participants.append(validator_index)
|
||||||
|
@ -1093,8 +1093,8 @@ def verify_slashable_vote_data(state: BeaconState, vote_data: SlashableVoteData)
|
||||||
|
|
||||||
return bls_verify_multiple(
|
return bls_verify_multiple(
|
||||||
pubkeys=[
|
pubkeys=[
|
||||||
aggregate_pubkey([state.validators[i].pubkey for i in vote_data.custody_bit_0_indices]),
|
bls_aggregate_pubkeys([state.validator_registry[i].pubkey for i in vote_data.custody_bit_0_indices]),
|
||||||
aggregate_pubkey([state.validators[i].pubkey for i in vote_data.custody_bit_1_indices]),
|
bls_aggregate_pubkeys([state.validator_registry[i].pubkey for i in vote_data.custody_bit_1_indices]),
|
||||||
],
|
],
|
||||||
messages=[
|
messages=[
|
||||||
hash_tree_root(AttestationDataAndCustodyBit(vote_data.data, False)),
|
hash_tree_root(AttestationDataAndCustodyBit(vote_data.data, False)),
|
||||||
|
@ -1372,7 +1372,7 @@ def activate_validator(state: BeaconState, index: int, genesis: bool) -> None:
|
||||||
validator.activation_slot = GENESIS_SLOT if genesis else (state.slot + ENTRY_EXIT_DELAY)
|
validator.activation_slot = GENESIS_SLOT if genesis else (state.slot + ENTRY_EXIT_DELAY)
|
||||||
state.validator_registry_delta_chain_tip = hash_tree_root(
|
state.validator_registry_delta_chain_tip = hash_tree_root(
|
||||||
ValidatorRegistryDeltaBlock(
|
ValidatorRegistryDeltaBlock(
|
||||||
current_validator_registry_delta_chain_tip=state.validator_registry_delta_chain_tip,
|
latest_registry_delta_root=state.validator_registry_delta_chain_tip,
|
||||||
validator_index=index,
|
validator_index=index,
|
||||||
pubkey=validator.pubkey,
|
pubkey=validator.pubkey,
|
||||||
slot=validator.activation_slot,
|
slot=validator.activation_slot,
|
||||||
|
@ -1401,7 +1401,7 @@ def exit_validator(state: BeaconState, index: int) -> None:
|
||||||
validator.exit_count = state.validator_registry_exit_count
|
validator.exit_count = state.validator_registry_exit_count
|
||||||
state.validator_registry_delta_chain_tip = hash_tree_root(
|
state.validator_registry_delta_chain_tip = hash_tree_root(
|
||||||
ValidatorRegistryDeltaBlock(
|
ValidatorRegistryDeltaBlock(
|
||||||
current_validator_registry_delta_chain_tip=state.validator_registry_delta_chain_tip,
|
latest_registry_delta_root=state.validator_registry_delta_chain_tip,
|
||||||
validator_index=index,
|
validator_index=index,
|
||||||
pubkey=validator.pubkey,
|
pubkey=validator.pubkey,
|
||||||
slot=validator.exit_slot,
|
slot=validator.exit_slot,
|
||||||
|
@ -1485,7 +1485,7 @@ For each `proposer_slashing` in `block.body.proposer_slashings`:
|
||||||
* Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`.
|
* Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`.
|
||||||
* Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`.
|
* Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`.
|
||||||
* Verify that `proposer_slashing.proposal_data_1.block_root != proposer_slashing.proposal_data_2.block_root`.
|
* Verify that `proposer_slashing.proposal_data_1.block_root != proposer_slashing.proposal_data_2.block_root`.
|
||||||
* Verify that `validator.penalized_slot > state.slot`.
|
* Verify that `proposer.penalized_slot > state.slot`.
|
||||||
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_1), signature=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`.
|
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_1), signature=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`.
|
||||||
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_2), signature=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`.
|
* Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_2), signature=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`.
|
||||||
* Run `penalize_validator(state, proposer_slashing.proposer_index)`.
|
* Run `penalize_validator(state, proposer_slashing.proposer_index)`.
|
||||||
|
@ -1617,14 +1617,14 @@ All [validators](#dfn-validator):
|
||||||
|
|
||||||
**Note**: `previous_epoch_boundary_attesting_balance` balance might be marginally different than `current_epoch_boundary_attesting_balance` during the previous epoch transition. Due to the tight bound on validator churn each epoch and small per-epoch rewards/penalties, the potential balance difference is very low and only marginally affects consensus safety.
|
**Note**: `previous_epoch_boundary_attesting_balance` balance might be marginally different than `current_epoch_boundary_attesting_balance` during the previous epoch transition. Due to the tight bound on validator churn each epoch and small per-epoch rewards/penalties, the potential balance difference is very low and only marginally affects consensus safety.
|
||||||
|
|
||||||
For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `shard_committee_at_slot = get_shard_committees_at_slot(slot)`. For every `(shard_committee, shard)` in `shard_committee_at_slot`, compute:
|
For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `crosslink_committee_at_slot = get_crosslink_committees_at_slot(slot)`. For every `(crosslink_committee, shard)` in `crosslink_committee_at_slot`, compute:
|
||||||
|
|
||||||
* Let `shard_block_root` be `state.latest_crosslinks[shard].shard_block_root`
|
* Let `shard_block_root` be `state.latest_crosslinks[shard].shard_block_root`
|
||||||
* Let `attesting_validator_indices(shard_committee, shard_block_root)` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.participation_bitfield) for a in current_epoch_attestations + previous_epoch_attestations if a.shard == shard and a.shard_block_root == shard_block_root]`.
|
* Let `attesting_validator_indices(crosslink_committee, shard_block_root)` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.participation_bitfield) for a in current_epoch_attestations + previous_epoch_attestations if a.shard == shard and a.shard_block_root == shard_block_root]`.
|
||||||
* Let `winning_root(shard_committee)` be equal to the value of `shard_block_root` such that `sum([get_effective_balance(state, i) for i in attesting_validator_indices(shard_committee, shard_block_root)])` is maximized (ties broken by favoring lower `shard_block_root` values).
|
* Let `winning_root(crosslink_committee)` be equal to the value of `shard_block_root` such that `sum([get_effective_balance(state, i) for i in attesting_validator_indices(crosslink_committee, shard_block_root)])` is maximized (ties broken by favoring lower `shard_block_root` values).
|
||||||
* Let `attesting_validators(shard_committee)` be equal to `attesting_validator_indices(shard_committee, winning_root(shard_committee))` for convenience.
|
* Let `attesting_validators(crosslink_committee)` be equal to `attesting_validator_indices(crosslink_committee, winning_root(crosslink_committee))` for convenience.
|
||||||
* Let `total_attesting_balance(shard_committee) = sum([get_effective_balance(state, i) for i in attesting_validators(shard_committee)])`.
|
* Let `total_attesting_balance(crosslink_committee) = sum([get_effective_balance(state, i) for i in attesting_validators(crosslink_committee)])`.
|
||||||
* Let `total_balance(shard_committee) = sum([get_effective_balance(state, i) for i in shard_committee])`.
|
* Let `total_balance(crosslink_committee) = sum([get_effective_balance(state, i) for i in crosslink_committee])`.
|
||||||
|
|
||||||
Define the following helpers to process attestation inclusion rewards and inclusion distance reward/penalty. For every attestation `a` in `previous_epoch_attestations`:
|
Define the following helpers to process attestation inclusion rewards and inclusion distance reward/penalty. For every attestation `a` in `previous_epoch_attestations`:
|
||||||
|
|
||||||
|
@ -1653,9 +1653,9 @@ Set `state.finalized_slot = state.previous_justified_slot` if any of the followi
|
||||||
|
|
||||||
### Crosslinks
|
### Crosslinks
|
||||||
|
|
||||||
For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `shard_committee_at_slot = get_shard_committees_at_slot(slot)`. For every `(shard_committee, shard)` in `shard_committee_at_slot`, compute:
|
For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `crosslink_committee_at_slot = get_crosslink_committees_at_slot(slot)`. For every `(crosslink_committee, shard)` in `crosslink_committee_at_slot`, compute:
|
||||||
|
|
||||||
* Set `state.latest_crosslinks[shard] = CrosslinkRecord(slot=state.slot, shard_block_root=winning_root(shard_committee))` if `3 * total_attesting_balance(shard_committee) >= 2 * total_balance(shard_committee)`.
|
* Set `state.latest_crosslinks[shard] = CrosslinkRecord(slot=state.slot, shard_block_root=winning_root(crosslink_committee))` if `3 * total_attesting_balance(crosslink_committee) >= 2 * total_balance(crosslink_committee)`.
|
||||||
|
|
||||||
### Rewards and penalties
|
### Rewards and penalties
|
||||||
|
|
||||||
|
@ -1699,10 +1699,10 @@ For each `index` in `previous_epoch_attester_indices`, we determine the proposer
|
||||||
|
|
||||||
#### Crosslinks
|
#### Crosslinks
|
||||||
|
|
||||||
For every `i in range(state.slot - 2 * EPOCH_LENGTH, state.slot - EPOCH_LENGTH)`, let `shard_committee_at_slot, start_shard = get_shard_committees_at_slot(i)`. For every `j in range(len(shard_committee_at_slot))`, let `shard_committee = shard_committee_at_slot[j]`, `shard = (start_shard + j) % SHARD_COUNT`, and compute:
|
For every `i in range(state.slot - 2 * EPOCH_LENGTH, state.slot - EPOCH_LENGTH)`, let `crosslink_committee_at_slot, start_shard = get_crosslink_committees_at_slot(i)`. For every `j in range(len(crosslink_committee_at_slot))`, let `crosslink_committee = crosslink_committee_at_slot[j]`, `shard = (start_shard + j) % SHARD_COUNT`, and compute:
|
||||||
|
|
||||||
* If `index in attesting_validators(shard_committee)`, `state.validator_balances[index] += base_reward(state, index) * total_attesting_balance(shard_committee) // total_balance(shard_committee))`.
|
* If `index in attesting_validators(crosslink_committee)`, `state.validator_balances[index] += base_reward(state, index) * total_attesting_balance(crosslink_committee) // total_balance(crosslink_committee))`.
|
||||||
* If `index not in attesting_validators(shard_committee)`, `state.validator_balances[index] -= base_reward(state, index)`.
|
* If `index not in attesting_validators(crosslink_committee)`, `state.validator_balances[index] -= base_reward(state, index)`.
|
||||||
|
|
||||||
### Ejections
|
### Ejections
|
||||||
|
|
||||||
|
@ -1714,7 +1714,7 @@ def process_ejections(state: BeaconState) -> None:
|
||||||
Iterate through the validator registry
|
Iterate through the validator registry
|
||||||
and eject active validators with balance below ``EJECTION_BALANCE``.
|
and eject active validators with balance below ``EJECTION_BALANCE``.
|
||||||
"""
|
"""
|
||||||
for index in active_validator_indices(state.validator_registry):
|
for index in get_active_validator_indices(state.validator_registry, state.slot):
|
||||||
if state.validator_balances[index] < EJECTION_BALANCE * GWEI_PER_ETH:
|
if state.validator_balances[index] < EJECTION_BALANCE * GWEI_PER_ETH:
|
||||||
exit_validator(state, index)
|
exit_validator(state, index)
|
||||||
```
|
```
|
||||||
|
|
Loading…
Reference in New Issue