Vote for block hash along with deposit root (#448)

This commit is contained in:
vbuterin 2019-01-17 05:43:47 -06:00 committed by Justin
parent 7439939e29
commit 7686702c29

View File

@ -45,10 +45,11 @@
- [`BeaconState`](#beaconstate) - [`BeaconState`](#beaconstate)
- [`Validator`](#validator) - [`Validator`](#validator)
- [`Crosslink`](#crosslink) - [`Crosslink`](#crosslink)
- [`DepositRootVote`](#depositrootvote)
- [`PendingAttestation`](#pendingattestation) - [`PendingAttestation`](#pendingattestation)
- [`Fork`](#fork) - [`Fork`](#fork)
- [`ValidatorRegistryDeltaBlock`](#validatorregistrydeltablock) - [`ValidatorRegistryDeltaBlock`](#validatorregistrydeltablock)
- [`Eth1Data`](#eth1data)
- [`Eth1DataVote`](#eth1datavote)
- [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract) - [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract)
- [Deposit arguments](#deposit-arguments) - [Deposit arguments](#deposit-arguments)
- [Withdrawal credentials](#withdrawal-credentials) - [Withdrawal credentials](#withdrawal-credentials)
@ -96,7 +97,7 @@
- [Slot](#slot) - [Slot](#slot)
- [Proposer signature](#proposer-signature) - [Proposer signature](#proposer-signature)
- [RANDAO](#randao) - [RANDAO](#randao)
- [Deposit root](#deposit-root) - [Eth1 data](#eth1-data)
- [Operations](#operations) - [Operations](#operations)
- [Proposer slashings](#proposer-slashings-1) - [Proposer slashings](#proposer-slashings-1)
- [Casper slashings](#casper-slashings-1) - [Casper slashings](#casper-slashings-1)
@ -106,7 +107,7 @@
- [Custody](#custody) - [Custody](#custody)
- [Per-epoch processing](#per-epoch-processing) - [Per-epoch processing](#per-epoch-processing)
- [Helpers](#helpers) - [Helpers](#helpers)
- [Deposit roots](#deposit-roots) - [Eth1 data](#eth1-data-1)
- [Justification](#justification) - [Justification](#justification)
- [Crosslinks](#crosslinks) - [Crosslinks](#crosslinks)
- [Rewards and penalties](#rewards-and-penalties) - [Rewards and penalties](#rewards-and-penalties)
@ -202,7 +203,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted
| `EPOCH_LENGTH` | `2**6` (= 64) | slots | 6.4 minutes | | `EPOCH_LENGTH` | `2**6` (= 64) | slots | 6.4 minutes |
| `SEED_LOOKAHEAD` | `2**6` (= 64) | slots | 6.4 minutes | | `SEED_LOOKAHEAD` | `2**6` (= 64) | slots | 6.4 minutes |
| `ENTRY_EXIT_DELAY` | `2**8` (= 256) | slots | 25.6 minutes | | `ENTRY_EXIT_DELAY` | `2**8` (= 256) | slots | 25.6 minutes |
| `DEPOSIT_ROOT_VOTING_PERIOD` | `2**10` (= 1,024) | slots | ~1.7 hours | | `ETH1_DATA_VOTING_PERIOD` | `2**10` (= 1,024) | slots | ~1.7 hours |
| `MIN_VALIDATOR_WITHDRAWAL_TIME` | `2**14` (= 16,384) | slots | ~27 hours | | `MIN_VALIDATOR_WITHDRAWAL_TIME` | `2**14` (= 16,384) | slots | ~27 hours |
### Reward and penalty quotients ### Reward and penalty quotients
@ -423,7 +424,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted
'parent_root': 'hash32', 'parent_root': 'hash32',
'state_root': 'hash32', 'state_root': 'hash32',
'randao_reveal': 'hash32', 'randao_reveal': 'hash32',
'deposit_root': 'hash32', 'eth1_data': Eth1Data,
'signature': ['uint384'], 'signature': ['uint384'],
## Body ## ## Body ##
@ -505,9 +506,9 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted
'latest_attestations': [PendingAttestation], 'latest_attestations': [PendingAttestation],
'batched_block_roots': ['hash32'], 'batched_block_roots': ['hash32'],
# Ethereum 1.0 deposit root # Ethereum 1.0 chain data
'latest_deposit_root': 'hash32', 'latest_eth1_data': Eth1Data,
'deposit_root_votes': [DepositRootVote], 'eth1_data_votes': [Eth1DataVote],
} }
``` ```
@ -555,17 +556,6 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted
} }
``` ```
#### `DepositRootVote`
```python
{
# Deposit root
'deposit_root': 'hash32',
# Vote count
'vote_count': 'uint64',
}
```
#### `PendingAttestation` #### `PendingAttestation`
```python ```python
@ -598,11 +588,33 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted
```python ```python
{ {
latest_registry_delta_root: 'hash32', 'latest_registry_delta_root': 'hash32',
validator_index: 'uint24', 'validator_index': 'uint24',
pubkey: 'uint384', 'pubkey': 'uint384',
slot: 'uint64', 'slot': 'uint64',
flag: 'uint64', 'flag': 'uint64',
}
```
#### `Eth1Data`
```python
{
# Root of the deposit tree
'deposit_root': 'hash32',
# Block hash
'block_hash': 'hash32',
}
```
#### `Eth1DataVote`
```python
{
# Data being voted for
'eth1_data': Eth1Data,
# Vote count
'vote_count': 'uint64',
} }
``` ```
@ -632,7 +644,7 @@ Every Ethereum 1.0 deposit, of size between `MIN_DEPOSIT_AMOUNT` and `MAX_DEPOSI
When sufficiently many full deposits have been made the deposit contract emits the `ChainStart` log. The beacon chain state may then be initialized by calling the `get_initial_beacon_state` function (defined below) where: When sufficiently many full deposits have been made the deposit contract emits the `ChainStart` log. The beacon chain state may then be initialized by calling the `get_initial_beacon_state` function (defined below) where:
* `genesis_time` equals `time` in the `ChainStart` log * `genesis_time` equals `time` in the `ChainStart` log
* `latest_deposit_root` equals `deposit_root` in the `ChainStart` log * `latest_eth1_data.deposit_root` equals `deposit_root` in the `ChainStart` log, and `latest_eth1_data.block_hash` equals the hash of the block that included the log
* `initial_validator_deposits` is a list of `Deposit` objects built according to the `Deposit` logs up to the deposit that triggered the `ChainStart` log, processed in the order in which they were emitted (oldest to newest) * `initial_validator_deposits` is a list of `Deposit` objects built according to the `Deposit` logs up to the deposit that triggered the `ChainStart` log, processed in the order in which they were emitted (oldest to newest)
### Vyper code ### Vyper code
@ -713,7 +725,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.
* The node has processed its `state` up to slot, `block.slot - 1`. * The node has processed its `state` up to slot, `block.slot - 1`.
* An Ethereum 1.0 block pointed to by the `state.latest_deposit_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.
* The node's local clock time is greater than or equal to `state.genesis_time + block.slot * SLOT_DURATION`. * The node's local clock time is greater than or equal to `state.genesis_time + block.slot * SLOT_DURATION`.
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.
@ -1183,7 +1195,10 @@ A valid block with slot `GENESIS_SLOT` (a "genesis block") has the following val
parent_root=ZERO_HASH, parent_root=ZERO_HASH,
state_root=STARTUP_STATE_ROOT, state_root=STARTUP_STATE_ROOT,
randao_reveal=ZERO_HASH, randao_reveal=ZERO_HASH,
deposit_root=ZERO_HASH, eth1_data=Eth1Data(
deposit_root=ZERO_HASH,
block_hash=ZERO_HASH
),
signature=EMPTY_SIGNATURE, signature=EMPTY_SIGNATURE,
body=BeaconBlockBody( body=BeaconBlockBody(
proposer_slashings=[], proposer_slashings=[],
@ -1203,7 +1218,7 @@ A valid block with slot `GENESIS_SLOT` (a "genesis block") has the following val
```python ```python
def get_initial_beacon_state(initial_validator_deposits: List[Deposit], def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
genesis_time: int, genesis_time: int,
latest_deposit_root: Hash32) -> BeaconState: latest_eth1_data: Eth1Data) -> BeaconState:
state = BeaconState( state = BeaconState(
# Misc # Misc
slot=GENESIS_SLOT, slot=GENESIS_SLOT,
@ -1247,9 +1262,9 @@ def get_initial_beacon_state(initial_validator_deposits: List[Deposit],
latest_attestations=[], latest_attestations=[],
batched_block_roots=[], batched_block_roots=[],
# Deposit root # Ethereum 1.0 chain data
latest_deposit_root=latest_deposit_root, latest_eth1_data=latest_eth1_data,
deposit_root_votes=[], eth1_data_votes=[],
) )
# Process initial deposits # Process initial deposits
@ -1466,10 +1481,10 @@ Below are the processing steps that happen at every `block`.
* Set `proposer.randao_commitment = block.randao_reveal`. * Set `proposer.randao_commitment = block.randao_reveal`.
* Set `proposer.randao_layers = 0`. * Set `proposer.randao_layers = 0`.
### Deposit root ### Eth1 data
* If `block.deposit_root` is `deposit_root_vote.deposit_root` for some `deposit_root_vote` in `state.deposit_root_votes`, set `deposit_root_vote.vote_count += 1`. * If `block.eth1_data` equals `eth1_data_vote.eth1_data` for some `eth1_data_vote` in `state.eth1_data_votes`, set `eth1_data_vote.vote_count += 1`.
* Otherwise, append to `state.deposit_root_votes` a new `DepositRootVote(deposit_root=block.deposit_root, vote_count=1)`. * Otherwise, append to `state.eth1_data_votes` a new `Eth1DataVote(eth1_data=block.eth1_data, vote_count=1)`.
### Operations ### Operations
@ -1533,7 +1548,7 @@ Verify that `len(block.body.deposits) <= MAX_DEPOSITS`.
For each `deposit` in `block.body.deposits`: For each `deposit` in `block.body.deposits`:
* Let `serialized_deposit_data` be the serialized form of `deposit.deposit_data`. It should be 8 bytes for `deposit_data.amount` followed by 8 bytes for `deposit_data.timestamp` and then the `DepositInput` bytes. That is, it should match `deposit_data` in the [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract) of which the hash was placed into the Merkle tree. * Let `serialized_deposit_data` be the serialized form of `deposit.deposit_data`. It should be 8 bytes for `deposit_data.amount` followed by 8 bytes for `deposit_data.timestamp` and then the `DepositInput` bytes. That is, it should match `deposit_data` in the [Ethereum 1.0 deposit contract](#ethereum-10-deposit-contract) of which the hash was placed into the Merkle tree.
* Verify that `verify_merkle_branch(hash(serialized_deposit_data), deposit.branch, DEPOSIT_CONTRACT_TREE_DEPTH, deposit.index, state.latest_deposit_root)` is `True`. * Verify that `verify_merkle_branch(hash(serialized_deposit_data), deposit.branch, DEPOSIT_CONTRACT_TREE_DEPTH, deposit.index, state.latest_eth1_data.deposit_root)` is `True`.
```python ```python
def verify_merkle_branch(leaf: Hash32, branch: [Hash32], depth: int, index: int, root: Hash32) -> bool: def verify_merkle_branch(leaf: Hash32, branch: [Hash32], depth: int, index: int, root: Hash32) -> bool:
@ -1629,12 +1644,12 @@ Define the following helpers to process attestation inclusion rewards and inclus
* Let `inclusion_slot(state, index) = a.slot_included` for the attestation `a` where `index` is in `get_attestation_participants(state, a.data, a.aggregation_bitfield)`. * Let `inclusion_slot(state, index) = a.slot_included` for the attestation `a` where `index` is in `get_attestation_participants(state, a.data, a.aggregation_bitfield)`.
* Let `inclusion_distance(state, index) = a.slot_included - a.data.slot` where `a` is the above attestation. * Let `inclusion_distance(state, index) = a.slot_included - a.data.slot` where `a` is the above attestation.
### Deposit roots ### Eth1 data
If `state.slot % DEPOSIT_ROOT_VOTING_PERIOD == 0`: If `state.slot % ETH1_DATA_VOTING_PERIOD == 0`:
* Set `state.latest_deposit_root = deposit_root_vote.deposit_root` if `deposit_root_vote.vote_count * 2 > DEPOSIT_ROOT_VOTING_PERIOD` for some `deposit_root_vote` in `state.deposit_root_votes`. * Set `state.latest_eth1_data = eth1_data_vote.data` if `eth1_data_vote.vote_count * 2 > ETH1_DATA_VOTING_PERIOD` for some `eth1_data_vote` in `state.eth1_data_votes`.
* Set `state.deposit_root_votes = []`. * Set `state.eth1_data_votes = []`.
### Justification ### Justification