Merge branch 'dev' into JustinDrake-patch-1

This commit is contained in:
Danny Ryan 2019-02-17 21:16:45 -07:00
commit 9eb3be5471
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
4 changed files with 35 additions and 25 deletions

View File

@ -180,7 +180,7 @@ Code snippets appearing in `this style` are to be interpreted as Python code.
### Misc ### Misc
| Name | Value | | Name | Value |
| - | - | :-: | | - | - |
| `SHARD_COUNT` | `2**10` (= 1,024) | | `SHARD_COUNT` | `2**10` (= 1,024) |
| `TARGET_COMMITTEE_SIZE` | `2**7` (= 128) | | `TARGET_COMMITTEE_SIZE` | `2**7` (= 128) |
| `MAX_BALANCE_CHURN_QUOTIENT` | `2**5` (= 32) | | `MAX_BALANCE_CHURN_QUOTIENT` | `2**5` (= 32) |
@ -997,6 +997,7 @@ def get_beacon_proposer_index(state: BeaconState,
def merkle_root(values: List[Bytes32]) -> Bytes32: def merkle_root(values: List[Bytes32]) -> Bytes32:
""" """
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.
Note that the leaves are not hashed.
""" """
o = [0] * len(values) + values o = [0] * len(values) + values
for i in range(len(values) - 1, 0, -1): for i in range(len(values) - 1, 0, -1):
@ -1170,7 +1171,7 @@ def verify_slashable_attestation(state: BeaconState, slashable_attestation: Slas
hash_tree_root(AttestationDataAndCustodyBit(data=slashable_attestation.data, custody_bit=0b1)), hash_tree_root(AttestationDataAndCustodyBit(data=slashable_attestation.data, custody_bit=0b1)),
], ],
signature=slashable_attestation.aggregate_signature, signature=slashable_attestation.aggregate_signature,
domain=get_domain(state.fork, slot_to_epoch(vote_data.data.slot), DOMAIN_ATTESTATION), domain=get_domain(state.fork, slot_to_epoch(slashable_attestation.data.slot), DOMAIN_ATTESTATION),
) )
``` ```
@ -1347,9 +1348,9 @@ def slash_validator(state: BeaconState, index: ValidatorIndex) -> None:
Slash the validator with index ``index``. Slash the validator with index ``index``.
Note that this function mutates ``state``. Note that this function mutates ``state``.
""" """
assert state.slot < validator.withdrawable_epoch # [TO BE REMOVED IN PHASE 2]
exit_validator(state, index)
validator = state.validator_registry[index] validator = state.validator_registry[index]
assert state.slot < get_epoch_start_slot(validator.withdrawable_epoch) # [TO BE REMOVED IN PHASE 2]
exit_validator(state, index)
state.latest_slashed_balances[get_current_epoch(state) % LATEST_SLASHED_EXIT_LENGTH] += get_effective_balance(state, index) state.latest_slashed_balances[get_current_epoch(state) % LATEST_SLASHED_EXIT_LENGTH] += get_effective_balance(state, index)
whistleblower_index = get_beacon_proposer_index(state, state.slot) whistleblower_index = get_beacon_proposer_index(state, state.slot)
@ -1524,7 +1525,7 @@ For a beacon chain block, `block`, to be processed by a node, the following cond
* The parent block with root `block.parent_root` has been processed and accepted. * The parent block with root `block.parent_root` has been processed and accepted.
* An Ethereum 1.0 block pointed to by the `state.latest_eth1_data.block_hash` has been processed and accepted. * An Ethereum 1.0 block pointed to by the `state.latest_eth1_data.block_hash` has been processed and accepted.
* The node's Unix time is greater than or equal to `state.genesis_time + block.slot * SECONDS_PER_SLOT`. (Note that leap seconds mean that slots will occasionally last `SECONDS_PER_SLOT + 1` or `SECONDS_PER_SLOT - 1` seconds, possibly several times a year.) * The node's Unix time is greater than or equal to `state.genesis_time + (block.slot - GENESIS_SLOT) * SECONDS_PER_SLOT`. (Note that leap seconds mean that slots will occasionally last `SECONDS_PER_SLOT + 1` or `SECONDS_PER_SLOT - 1` seconds, possibly several times a year.)
If these conditions are not met, the client should delay processing the beacon block until the conditions are all satisfied. If these conditions are not met, the client should delay processing the beacon block until the conditions are all satisfied.
@ -1634,7 +1635,7 @@ Below are the processing steps that happen at every `block`.
#### Eth1 data #### Eth1 data
* If there exists an `eth1_data_vote` in `states.eth1_data_votes` for which `eth1_data_vote.eth1_data == block.eth1_data` (there will be at most one), set `eth1_data_vote.vote_count += 1`. * If there exists an `eth1_data_vote` in `state.eth1_data_votes` for which `eth1_data_vote.eth1_data == block.eth1_data` (there will be at most one), set `eth1_data_vote.vote_count += 1`.
* Otherwise, append to `state.eth1_data_votes` a new `Eth1DataVote(eth1_data=block.eth1_data, vote_count=1)`. * Otherwise, append to `state.eth1_data_votes` a new `Eth1DataVote(eth1_data=block.eth1_data, vote_count=1)`.
#### Transactions #### Transactions
@ -2058,7 +2059,7 @@ def process_exit_queue(state: BeaconState) -> None:
#### Final updates #### Final updates
* Set `state.latest_active_index_roots[(next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state, next_epoch + ACTIVATION_EXIT_DELAY))`. * Set `state.latest_active_index_roots[(next_epoch + ACTIVATION_EXIT_DELAY) % LATEST_ACTIVE_INDEX_ROOTS_LENGTH] = hash_tree_root(get_active_validator_indices(state.validator_registry, next_epoch + ACTIVATION_EXIT_DELAY))`.
* Set `state.latest_slashed_balances[(next_epoch) % LATEST_SLASHED_EXIT_LENGTH] = state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH]`. * Set `state.latest_slashed_balances[(next_epoch) % LATEST_SLASHED_EXIT_LENGTH] = state.latest_slashed_balances[current_epoch % LATEST_SLASHED_EXIT_LENGTH]`.
* Set `state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = get_randao_mix(state, current_epoch)`. * Set `state.latest_randao_mixes[next_epoch % LATEST_RANDAO_MIXES_LENGTH] = get_randao_mix(state, current_epoch)`.
* Remove any `attestation` in `state.latest_attestations` such that `slot_to_epoch(attestation.data.slot) < current_epoch`. * Remove any `attestation` in `state.latest_attestations` such that `slot_to_epoch(attestation.data.slot) < current_epoch`.

View File

@ -47,8 +47,8 @@ def get_split_offset(list_size: int, chunks: int, index: int) -> int:
```python ```python
def get_shuffled_committee(state: BeaconState, def get_shuffled_committee(state: BeaconState,
shard: ShardNumber, shard: Shard,
committee_start_epoch: EpochNumber) -> List[ValidatorIndex]: committee_start_epoch: Epoch) -> List[ValidatorIndex]:
""" """
Return shuffled committee. Return shuffled committee.
""" """
@ -66,8 +66,8 @@ def get_shuffled_committee(state: BeaconState,
```python ```python
def get_persistent_committee(state: BeaconState, def get_persistent_committee(state: BeaconState,
shard: ShardNumber, shard: Shard,
epoch: EpochNumber) -> List[ValidatorIndex]: epoch: Epoch) -> List[ValidatorIndex]:
""" """
Return the persistent committee for the given ``shard`` at the given ``epoch``. Return the persistent committee for the given ``shard`` at the given ``epoch``.
""" """
@ -94,10 +94,10 @@ def get_persistent_committee(state: BeaconState,
```python ```python
def get_shard_proposer_index(state: BeaconState, def get_shard_proposer_index(state: BeaconState,
shard: ShardNumber, shard: Shard,
slot: SlotNumber) -> ValidatorIndex: slot: Slot) -> ValidatorIndex:
seed = hash( seed = hash(
state.current_epoch_seed + state.current_shuffling_seed +
int_to_bytes8(shard) + int_to_bytes8(shard) +
int_to_bytes8(slot) int_to_bytes8(slot)
) )
@ -177,8 +177,8 @@ A node should sign a crosslink only if the following conditions hold. **If a nod
First, the conditions must recursively apply to the crosslink referenced in `last_crosslink_root` for the same shard (unless `last_crosslink_root` equals zero, in which case we are at the genesis). First, the conditions must recursively apply to the crosslink referenced in `last_crosslink_root` for the same shard (unless `last_crosslink_root` equals zero, in which case we are at the genesis).
Second, we verify the `shard_chain_commitment`. Second, we verify the `shard_chain_commitment`.
* Let `start_slot = state.latest_crosslinks[shard].epoch * EPOCH_LENGTH + EPOCH_LENGTH - CROSSLINK_LOOKBACK`. * Let `start_slot = state.latest_crosslinks[shard].epoch * SLOTS_PER_EPOCH + SLOTS_PER_EPOCH - CROSSLINK_LOOKBACK`.
* Let `end_slot = attestation.data.slot - attestation.data.slot % EPOCH_LENGTH - CROSSLINK_LOOKBACK`. * Let `end_slot = attestation.data.slot - attestation.data.slot % SLOTS_PER_EPOCH - CROSSLINK_LOOKBACK`.
* Let `length = end_slot - start_slot`, `headers[0] .... headers[length-1]` be the serialized block headers in the canonical shard chain from the verifer's point of view (note that this implies that `headers` and `bodies` have been checked for validity). * Let `length = end_slot - start_slot`, `headers[0] .... headers[length-1]` be the serialized block headers in the canonical shard chain from the verifer's point of view (note that this implies that `headers` and `bodies` have been checked for validity).
* Let `bodies[0] ... bodies[length-1]` be the bodies of the blocks. * Let `bodies[0] ... bodies[length-1]` be the bodies of the blocks.
* Note: If there is a missing slot, then the header and body are the same as that of the block at the most recent slot that has a block. * Note: If there is a missing slot, then the header and body are the same as that of the block at the most recent slot that has a block.

View File

@ -29,6 +29,7 @@ deserializing objects and data types.
- [`uint264`..`uintN`, `bytes33`..`bytesN`](#uint264uintn-bytes33bytesn) - [`uint264`..`uintN`, `bytes33`..`bytesN`](#uint264uintn-bytes33bytesn)
- [List/Vectors](#listvectors-2) - [List/Vectors](#listvectors-2)
- [Container](#container-2) - [Container](#container-2)
+ [Signed Roots](#signed-roots)
* [Implementations](#implementations) * [Implementations](#implementations)
## About ## About
@ -396,6 +397,14 @@ Recursively tree hash the values in the container in the same order as the field
return merkle_hash([hash_tree_root_internal(getattr(x, field)) for field in value.fields]) return merkle_hash([hash_tree_root_internal(getattr(x, field)) for field in value.fields])
``` ```
### Signed roots
Let `field_name` be a field name in an SSZ container `container`. We define `truncate(container, field_name)` to be the `container` with the fields from `field_name` onwards truncated away. That is, `truncate(container, field_name) = [getattr(container, field)) for field in value.fields[:i]]` where `i = value.fields.index(field_name)`.
When `field_name` maps to a signature (e.g. a BLS12-381 signature of type `Bytes96`) the convention is that the corresponding signed message be `signed_root(container, field_name) = hash_tree_root(truncate(container, field_name))`. For example if `container = {"foo": sub_object_1, "bar": sub_object_2, "signature": bytes96, "baz": sub_object_3}` then `signed_root(container, "signature") = merkle_hash([hash_tree_root(sub_object_1), hash_tree_root(sub_object_2)])`.
Note that this convention means that fields after the signature are _not_ signed over. If there are multiple signatures in `container` then those are expected to be signing over the fields in the order specified. If multiple signatures of the same value are expected the convention is that the signature field be an array of signatures.
## Implementations ## Implementations
| Language | Implementation | Description | | Language | Implementation | Description |

View File

@ -34,7 +34,7 @@ __NOTICE__: This document is a work-in-progress for researchers and implementers
- [Attester slashings](#attester-slashings) - [Attester slashings](#attester-slashings)
- [Attestations](#attestations) - [Attestations](#attestations)
- [Deposits](#deposits) - [Deposits](#deposits)
- [Exits](#exits) - [Voluntary exits](#voluntary-exits)
- [Attestations](#attestations-1) - [Attestations](#attestations-1)
- [Attestation data](#attestation-data) - [Attestation data](#attestation-data)
- [Slot](#slot-1) - [Slot](#slot-1)
@ -118,7 +118,7 @@ Once a validator has been processed and added to the beacon state's `validator_r
### Activation ### Activation
In normal operation, the validator is quickly activated at which point the validator is added to the shuffling and begins validation after an additional `ENTRY_EXIT_DELAY` epochs (25.6 minutes). In normal operation, the validator is quickly activated at which point the validator is added to the shuffling and begins validation after an additional `ACTIVATION_EXIT_DELAY` epochs (25.6 minutes).
The function [`is_active_validator`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#is_active_validator) can be used to check if a validator is active during a given epoch. Usage is as follows: The function [`is_active_validator`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#is_active_validator) can be used to check if a validator is active during a given epoch. Usage is as follows:
@ -232,15 +232,15 @@ Up to `MAX_ATTESTATIONS` aggregate attestations can be included in the `block`.
Up to `MAX_DEPOSITS` [`Deposit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposit) objects can be included in the `block`. These deposits are constructed from the `Deposit` logs from the [Eth1.0 deposit contract](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#ethereum-10-deposit-contract) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposits-1). Up to `MAX_DEPOSITS` [`Deposit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposit) objects can be included in the `block`. These deposits are constructed from the `Deposit` logs from the [Eth1.0 deposit contract](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#ethereum-10-deposit-contract) and must be processed in sequential order. The deposits included in the `block` must satisfy the verification conditions found in [deposits processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#deposits-1).
##### Exits ##### Voluntary exits
Up to `MAX_EXITS` [`Exit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#exit) objects can be included in the `block`. The exits must satisfy the verification conditions found in [exits processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#exits-1). Up to `MAX_VOLUNTARY_EXITS` [`VoluntaryExit`](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#voluntaryexit) objects can be included in the `block`. The exits must satisfy the verification conditions found in [exits processing](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#exits-1).
### Attestations ### Attestations
A validator is expected to create, sign, and broadcast an attestation during each epoch. The slot during which the validator performs this role is any slot at which `get_crosslink_committees_at_slot(state, slot)` contains a committee that contains `validator_index`. A validator is expected to create, sign, and broadcast an attestation during each epoch. The slot during which the validator performs this role is any slot at which `get_crosslink_committees_at_slot(state, slot)` contains a committee that contains `validator_index`.
A validator should create and broadcast the attestation halfway through the `slot` during which the validator is assigned -- that is `SLOT_DURATION * 0.5` seconds after the start of `slot`. A validator should create and broadcast the attestation halfway through the `slot` during which the validator is assigned -- that is `SECONDS_PER_SLOT * 0.5` seconds after the start of `slot`.
#### Attestation data #### Attestation data
@ -347,7 +347,7 @@ Either (2) or (3) occurs if (1) fails. The choice between (2) and (3) is determi
def get_next_epoch_committee_assignment( def get_next_epoch_committee_assignment(
state: BeaconState, state: BeaconState,
validator_index: ValidatorIndex, validator_index: ValidatorIndex,
registry_change: bool) -> Tuple[List[ValidatorIndex], ShardNumber, SlotNumber, bool]: registry_change: bool) -> Tuple[List[ValidatorIndex], Shard, Slot, bool]:
""" """
Return the committee assignment in the next epoch for ``validator_index`` and ``registry_change``. Return the committee assignment in the next epoch for ``validator_index`` and ``registry_change``.
``assignment`` returned is a tuple of the following form: ``assignment`` returned is a tuple of the following form:
@ -360,14 +360,14 @@ def get_next_epoch_committee_assignment(
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)
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 + SLOTS_PER_EPOCH):
crosslink_committees = get_crosslink_committees_at_slot( crosslink_committees = get_crosslink_committees_at_slot(
state, state,
slot, slot,
registry_change=registry_change, registry_change=registry_change,
) )
selected_committees = [ selected_committees = [
committee # Tuple[List[ValidatorIndex], ShardNumber] committee # Tuple[List[ValidatorIndex], Shard]
for committee in crosslink_committees for committee in crosslink_committees
if validator_index in committee[0] if validator_index in committee[0]
] ]