proofread and add ToC

This commit is contained in:
Hsiao-Wei Wang 2018-11-28 15:23:37 +08:00
parent 2c34a97341
commit 67123a79cb
No known key found for this signature in database
GPG Key ID: 95B070122902DEA4
1 changed files with 71 additions and 28 deletions

View File

@ -1,10 +1,52 @@
# Ethereum 2.0 Phase 0 -- The Beacon Chain
###### tags: `spec`, `eth2.0`, `casper`, `sharding`, `beacon`
**tags: `spec`, `eth2.0`, `casper`, `sharding`, `beacon`**
**NOTICE**: This document is a work-in-progress for researchers and implementers. It reflects recent spec changes and takes precedence over the [Python proof-of-concept implementation](https://github.com/ethereum/beacon_chain).
### Introduction
## Table of contents
* [Ethereum 2.0 Phase 0 -- The Beacon Chain](#ethereum-20-phase-0----the-beacon-chain)
* [Table of contents](#table-of-contents)
* [Introduction](#introduction)
* [Terminology](#terminology)
* [Constants](#constants)
* [PoW chain registration contract](#pow-chain-registration-contract)
* [Data structures](#data-structures)
* [Beacon chain blocks](#beacon-chain-blocks)
* [Beacon chain state](#beacon-chain-state)
* [Beacon chain processing](#beacon-chain-processing)
* [Beacon chain fork choice rule](#beacon-chain-fork-choice-rule)
* [Beacon chain state transition function](#beacon-chain-state-transition-function)
* [Helper functions](#helper-functions)
* [PoW chain contract](#pow-chain-contract)
* [On startup](#on-startup)
* [Routine for adding a validator](#routine-for-adding-a-validator)
* [Routine for removing a validator](#routine-for-removing-a-validator)
* [Per-block processing](#per-block-processing)
* [Verify attestations](#verify-attestations)
* [Verify proposer signature](#verify-proposer-signature)
* [Verify and process RANDAO reveal](#verify-and-process-randao-reveal)
* [Process PoW receipt root](#process-pow-receipt-root)
* [Process penalties, logouts and other special objects](#process-penalties-logouts-and-other-special-objects)
* [LOGOUT](#logout)
* [CASPER_SLASHING](#casper_slashing)
* [PROPOSER_SLASHING](#proposer_slashing)
* [DEPOSIT_PROOF](#deposit_proof)
* [Cycle boundary processing](#cycle-boundary-processing)
* [Precomputation](#precomputation)
* [Adjust justified slots and crosslink status](#adjust-justified-slots-and-crosslink-status)
* [Balance recalculations related to FFG rewards](#balance-recalculations-related-to-ffg-rewards)
* [Balance recalculations related to crosslink rewards](#balance-recalculations-related-to-crosslink-rewards)
* [PoW chain related rules](#pow-chain-related-rules)
* [Validator set change](#validator-set-change)
* [If a validator set change does NOT happen](#if-a-validator-set-change-does-not-happen)
* [Proposer reshuffling](#proposer-reshuffling)
* [Finally...](#finally)
* [Appendix](#appendix)
* [Appendix A - Hash function](#appendix-a---hash-function)
* [Copyright](#copyright)
## Introduction
This document represents the specification for Phase 0 of Ethereum 2.0 -- The Beacon Chain.
@ -12,7 +54,8 @@ At the core of Ethereum 2.0 is a system chain called the "beacon chain". The bea
The primary source of load on the beacon chain are "attestations". Attestations simultaneously attest to a shard block and a corresponding beacon chain block. A sufficient number of attestations for the same shard block create a "crosslink", confirming the shard segment up to that shard block into the beacon chain. Crosslinks also serve as infrastructure for asynchronous cross-shard communication.
### Terminology
## Terminology
* **Validator** - a participant in the Casper/sharding consensus system. You can become one by depositing 32 ETH into the Casper mechanism.
* **Active validator set** - those validators who are currently participating, and which the Casper mechanism looks to produce and attest to blocks, crosslinks and other consensus objects.
@ -28,7 +71,7 @@ The primary source of load on the beacon chain are "attestations". Attestations
* **Withdrawal period** - number of slots between a validator exit and the validator balance being withdrawable
* **Genesis time** - the Unix time of the genesis beacon chain block at slot 0
### Constants
## Constants
| Constant | Value | Unit | Approximation |
| --- | --- | :---: | - |
@ -52,13 +95,13 @@ The primary source of load on the beacon chain are "attestations". Attestations
| `COLLECTIVE_PENALTY_CALCULATION_PERIOD` | 2**20 (= 1,048,576) | slots | ~2.4 months |
| `POW_RECEIPT_ROOT_VOTING_PERIOD` | 2**10 (= 1,024) | slots | ~1.7 hours |
| `SLASHING_WHISTLEBLOWER_REWARD_DENOMINATOR` | 2**9 (= 512) |
| `BASE_REWARD_QUOTIENT` | 2**11 (= 2,048) | |
| `INCLUDER_REWARD_SHARE_QUOTIENT` | 2**3 (= 8) | |
| `MAX_VALIDATOR_CHURN_QUOTIENT` | 2**5 (= 32) | |
| `BASE_REWARD_QUOTIENT` | 2**11 (= 2,048) | - |
| `INCLUDER_REWARD_SHARE_QUOTIENT` | 2**3 (= 8) | - |
| `MAX_VALIDATOR_CHURN_QUOTIENT` | 2**5 (= 32) | - |
| `POW_CONTRACT_MERKLE_TREE_DEPTH` | 2**5 (= 32) | - |
| `MAX_ATTESTATION_COUNT` | 2**7 (= 128) | - |
| `LOGOUT_MESSAGE` | `"LOGOUT"` | — |
| `INITIAL_FORK_VERSION` | 0 | |
| `INITIAL_FORK_VERSION` | 0 | - |
**Notes**
@ -103,7 +146,7 @@ The primary source of load on the beacon chain are "attestations". Attestations
| `DOMAIN_PROPOSAL` | `2` |
| `DOMAIN_LOGOUT` | `3` |
### PoW chain registration contract
## PoW chain registration contract
The initial deployment phases of Ethereum 2.0 are implemented without consensus changes to the PoW chain. A registration contract is added to the PoW chain to deposit ETH. This contract has a `registration` function which takes as arguments `pubkey`, `withdrawal_credentials`, `randao_commitment` as defined in a `ValidatorRecord` below. A BLS `proof_of_possession` of types `bytes` is given as a final argument.
@ -333,7 +376,7 @@ A `ProcessedAttestation` object has the following fields:
{
# Signed data
'data': AttestationSignedData,
# Attester participation bitfield (2 bits per attester)
# Attester participation bitfield
'attester_bitfield': 'bytes',
# Proof of custody bitfield
'poc_bitfield': 'bytes',
@ -371,7 +414,7 @@ The beacon chain fork choice rule is a hybrid that combines justification and fi
* Let `finalized_head` be the finalized block with the highest slot number. (A block `B` is finalized if there is a descendant of `B` in `store` the processing of which sets `B` as finalized.)
* Let `justified_head` be the descendant of `finalized_head` with the highest slot number that has been justified for at least `CYCLE_LENGTH` slots. (A block `B` is justified if there is a descendant of `B` in `store` the processing of which sets `B` as justified.) If no such descendant exists set `justified_head` to `finalized_head`.
* Let `get_ancestor(store, block, slot)` be the ancestor of `block` with slot number `slot`. The `get_ancestor` function can be defined recursively as `def get_ancestor(store, block, slot): return block if block.slot == slot else get_ancestor(store, store.get_parent(block), slot)`.
* Let `get_latest_attestation(store, validator)` be the attestation with the highest slot number in `store` from `validator`. If several such attestations exist use the one the validator `v` observed first.
* Let `get_latest_attestation(store, validator)` be the attestation with the highest slot number in `store` from `validator`. If several such attestations exist, use the one the validator `v` observed first.
* Let `get_latest_attestation_target(store, validator)` be the target block in the attestation `get_latest_attestation(store, validator)`.
* The head is `lmd_ghost(store, justified_head)` where the function `lmd_ghost` is defined below. Note that the implementation below is suboptimal; there are implementations that compute the head in time logarithmic in slot count.
@ -409,7 +452,7 @@ Below are various helper functions.
The following is a function that gets active validator indices from the validator list:
```python
def get_active_validator_indices(validators)
def get_active_validator_indices(validators: [ValidatorRecords]) -> List[int]:
return [i for i, v in enumerate(validators) if v.status == ACTIVE]
```
@ -501,18 +544,18 @@ Now, our combined helper method:
def get_new_shuffling(seed: Hash32,
validators: List[ValidatorRecord],
crosslinking_start_shard: int) -> List[List[ShardAndCommittee]]:
active_validators = get_active_validator_indices(validators)
active_validator_indices = get_active_validator_indices(validators)
committees_per_slot = clamp(
1,
SHARD_COUNT // CYCLE_LENGTH,
len(active_validators) // CYCLE_LENGTH // TARGET_COMMITTEE_SIZE,
len(active_validator_indices) // CYCLE_LENGTH // TARGET_COMMITTEE_SIZE,
)
output = []
# Shuffle with seed
shuffled_active_validator_indices = shuffle(active_validators, seed)
shuffled_active_validator_indices = shuffle(active_validator_indices, seed)
# Split the shuffled list into cycle_length pieces
validators_per_slot = split(shuffled_active_validator_indices, CYCLE_LENGTH)
@ -1107,7 +1150,7 @@ Repeat the steps in this section while `block.slot - last_state_recalculation_sl
_Note: `last_state_recalculation_slot` will always be a multiple of `CYCLE_LENGTH`. In the "happy case", this process will trigger, and loop once, every time `block.slot` passes a new exact multiple of `CYCLE_LENGTH`, but if a chain skips more than an entire cycle then the loop may run multiple times, incrementing `last_state_recalculation_slot` by `CYCLE_LENGTH` with each iteration._
#### Precomputation
### Precomputation
All validators:
@ -1147,7 +1190,7 @@ def adjust_for_inclusion_distance(magnitude: int, dist: int) -> int:
For any validator `v`, `base_reward(v) = balance_at_stake(v) // reward_quotient`
#### Adjust justified slots and crosslink status
### Adjust justified slots and crosslink status
* Set `state.justified_slot_bitfield = (state.justified_slot_bitfield * 2) % 2**64`.
* If `3 * prev_cycle_boundary_attesting_balance >= 2 * total_balance` then set `state.justified_slot_bitfield &= 2` (ie. flip the second lowest bit to 1) and `new_justification_source = s - CYCLE_LENGTH`.
@ -1161,7 +1204,7 @@ For every `ShardAndCommittee` object `obj`:
* If `3 * total_attesting_balance(obj) >= 2 * total_balance(obj)`, set `crosslinks[shard] = CrosslinkRecord(slot=last_state_recalculation_slot + CYCLE_LENGTH, hash=winning_hash(obj))`.
#### Balance recalculations related to FFG rewards
### Balance recalculations related to FFG rewards
Note: When applying penalties in the following balance recalculations implementers should make sure the `uint64` does not underflow.
@ -1180,21 +1223,21 @@ Case 2: `time_since_finality > 4 * CYCLE_LENGTH`:
For each `v` in `prev_cycle_boundary_attesters`, we determine the proposer `proposer_index = get_beacon_proposer_index(state, inclusion_slot(v))` and set `state.validators[proposer_index].balance += base_reward(v) // INCLUDER_REWARD_SHARE_QUOTIENT`.
#### Balance recalculations related to crosslink rewards
### Balance recalculations related to crosslink rewards
For every `ShardAndCommittee` object `obj` in `shard_and_committee_for_slots[:CYCLE_LENGTH]` (ie. the objects corresponding to the cycle before the current one), for each `v` in `[state.validators[index] for index in obj.committee]`, adjust balances as follows:
* If `v in attesting_validators(obj)`, `v.balance += adjust_for_inclusion_distance(base_reward(v) * total_attesting_balance(obj) // total_balance(obj)), inclusion_distance(v))`.
* If `v not in attesting_validators(obj)`, `v.balance -= base_reward(v)`.
#### PoW chain related rules
### PoW chain related rules
If `last_state_recalculation_slot % POW_RECEIPT_ROOT_VOTING_PERIOD == 0`, then:
* If for any `x` in `state.candidate_pow_receipt_root`, `x.votes * 2 >= POW_RECEIPT_ROOT_VOTING_PERIOD` set `state.processed_pow_receipt_root = x.receipt_root`.
* Set `state.candidate_pow_receipt_roots = []`.
#### Validator set change
### Validator set change
A validator set change can happen if all of the following criteria are satisfied:
@ -1212,9 +1255,9 @@ def get_changed_validators(validators: List[ValidatorRecord],
Return changed validator set and `deposits_penalized_in_period`, `validator_set_delta_hash_chain`.
"""
# The active validator set
active_validators = get_active_validator_indices(validators)
active_validator_indices = get_active_validator_indices(validators)
# The total balance of active validators
total_balance = sum([balance_at_stake(v) for i, v in enumerate(validators) if i in active_validators])
total_balance = sum([balance_at_stake(v) for i, v in enumerate(validators) if i in active_validator_indices])
# The maximum total wei that can deposit+withdraw
max_allowable_change = max(
2 * DEPOSIT_SIZE * GWEI_PER_ETH,
@ -1296,14 +1339,14 @@ And perform the following updates to the `state`:
* Set `state.shard_and_committee_for_slots[CYCLE_LENGTH:] = get_new_shuffling(state.next_shuffling_seed, validators, next_start_shard)`
* Set `state.next_shuffling_seed = state.randao_mix`
#### If a validator set change does NOT happen
### If a validator set change does NOT happen
* Set `state.shard_and_committee_for_slots[:CYCLE_LENGTH] = state.shard_and_committee_for_slots[CYCLE_LENGTH:]`
* Let `time_since_finality = block.slot - state.validator_set_change_slot`
* Let `start_shard = state.shard_and_committee_for_slots[0][0].shard`
* If `time_since_finality * CYCLE_LENGTH <= MIN_VALIDATOR_SET_CHANGE_INTERVAL` or `time_since_finality` is an exact power of 2, set `state.shard_and_committee_for_slots[CYCLE_LENGTH:] = get_new_shuffling(state.next_shuffling_seed, validators, start_shard)` and set `state.next_shuffling_seed = state.randao_mix`. Note that `start_shard` is not changed from last cycle.
#### Proposer reshuffling
### Proposer reshuffling
Run the following code to update the shard proposer set:
@ -1332,7 +1375,7 @@ while len(state.persistent_committee_reassignments) > 0 and state.persistent_com
state.persistent_committees[rec.shard].append(rec.validator_index)
```
#### Finally...
### Finally...
* Remove all attestation records older than slot `s`
* For any validator with index `v` with balance less than `MIN_ONLINE_DEPOSIT_SIZE` and status `ACTIVE`, run `exit_validator(v, state, block, penalize=False, current_slot=block.slot)`
@ -1344,5 +1387,5 @@ while len(state.persistent_committee_reassignments) > 0 and state.persistent_com
We aim to have a STARK-friendly hash function `hash(x)` for the production launch of the beacon chain. While the standardisation process for a STARK-friendly hash function takes place—led by STARKware, who will produce a detailed report with recommendations—we use `BLAKE2b-512` as a placeholder. Specifically, we set `hash(x) := BLAKE2b-512(x)[0:32]` where the `BLAKE2b-512` algorithm is defined in [RFC 7693](https://tools.ietf.org/html/rfc7693) and the input `x` is of type `bytes`.
## Copyright
# Copyright
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).