Various fixes regarding PoW receipt roots

Question: What happens if the block proposer at the `POW_RECEIPT_ROOT_VOTING_PERIOD` boundary puts a bad receipt root? Does this give too much power to that block proposer?
This commit is contained in:
Justin 2018-11-22 23:09:36 +00:00 committed by GitHub
parent f1b78cf01e
commit 50458c1d31
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 26 additions and 26 deletions

View File

@ -44,17 +44,17 @@ The primary source of load on the beacon chain are "attestations". Attestations
| `MIN_VALIDATOR_SET_CHANGE_INTERVAL` | 2**8 (= 256) | slots | ~25 minutes | | `MIN_VALIDATOR_SET_CHANGE_INTERVAL` | 2**8 (= 256) | slots | ~25 minutes |
| `SHARD_PERSISTENT_COMMITTEE_CHANGE_PERIOD` | 2**17 (= 131,072) | slots | ~9 days | | `SHARD_PERSISTENT_COMMITTEE_CHANGE_PERIOD` | 2**17 (= 131,072) | slots | ~9 days |
| `MIN_ATTESTATION_INCLUSION_DELAY` | 2**2 (= 4) | slots | ~24 seconds | | `MIN_ATTESTATION_INCLUSION_DELAY` | 2**2 (= 4) | slots | ~24 seconds |
| `RANDAO_SLOTS_PER_LAYER` | 2**12 (= 4096) | slots | ~7 hours | | `RANDAO_SLOTS_PER_LAYER` | 2**12 (= 4,096) | slots | ~7 hours |
| `SQRT_E_DROP_TIME` | 2**18 (= 262,144) | slots | ~18 days | | `SQRT_E_DROP_TIME` | 2**18 (= 262,144) | slots | ~18 days |
| `WITHDRAWALS_PER_CYCLE` | 2**2 (=4) | validators | 5.2m ETH in ~6 months | | `WITHDRAWALS_PER_CYCLE` | 2**2 (=4) | validators | 5.2m ETH in ~6 months |
| `MIN_WITHDRAWAL_PERIOD` | 2**13 (= 8192) | slots | ~14 hours | | `MIN_WITHDRAWAL_PERIOD` | 2**13 (= 8,192) | slots | ~14 hours |
| `DELETION_PERIOD` | 2**22 (= 4,194,304) | slots | ~290 days | | `DELETION_PERIOD` | 2**22 (= 4,194,304) | slots | ~290 days |
| `COLLECTIVE_PENALTY_CALCULATION_PERIOD` | 2**20 (= 1,048,576) | slots | ~2.4 months | | `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) | | `SLASHING_WHISTLEBLOWER_REWARD_DENOMINATOR` | 2**9 (= 512) |
| `BASE_REWARD_QUOTIENT` | 2**15 (= 32,768) | — | | `BASE_REWARD_QUOTIENT` | 2**15 (= 32,768) | — |
| `MAX_VALIDATOR_CHURN_QUOTIENT` | 2**5 (= 32) | — | | `MAX_VALIDATOR_CHURN_QUOTIENT` | 2**5 (= 32) | — |
| `POW_HASH_VOTING_PERIOD` | 2**10 (=1024) | - | | `POW_CONTRACT_MERKLE_TREE_DEPTH` | 2**5 (= 32) | - |
| `POW_CONTRACT_MERKLE_TREE_DEPTH` | 2**5 (=32) | - |
| `LOGOUT_MESSAGE` | `"LOGOUT"` | — | | `LOGOUT_MESSAGE` | `"LOGOUT"` | — |
| `INITIAL_FORK_VERSION` | 0 | — | | `INITIAL_FORK_VERSION` | 0 | — |
@ -109,7 +109,7 @@ A `BeaconBlock` has the following fields:
'slot': 'uint64', 'slot': 'uint64',
# Proposer RANDAO reveal # Proposer RANDAO reveal
'randao_reveal': 'hash32', 'randao_reveal': 'hash32',
# Recent PoW chain reference (receipt root) # Recent PoW receipt root
'candidate_pow_receipt_root': 'hash32', 'candidate_pow_receipt_root': 'hash32',
# Skip list of previous beacon block hashes # Skip list of previous beacon block hashes
# i'th item is the most recent ancestor whose slot is a multiple of 2**i for i = 0, ..., 31 # i'th item is the most recent ancestor whose slot is a multiple of 2**i for i = 0, ..., 31
@ -236,8 +236,8 @@ The `BeaconState` has the following fields:
'current_exit_seq': 'uint64', 'current_exit_seq': 'uint64',
# Genesis time # Genesis time
'genesis_time': 'uint64', 'genesis_time': 'uint64',
# PoW chain reference # PoW receipt root
'known_pow_receipt_root': 'hash32', 'processed_pow_receipt_root': 'hash32',
'candidate_pow_receipt_root': 'hash32', 'candidate_pow_receipt_root': 'hash32',
'candidate_pow_receipt_root_votes': 'uint64', 'candidate_pow_receipt_root_votes': 'uint64',
# Parameters relevant to hard forks / versioning. # Parameters relevant to hard forks / versioning.
@ -328,7 +328,7 @@ For a block on the beacon chain to be processed by a node, four conditions have
* The parent pointed to by the `ancestor_hashes[0]` has already been processed and accepted * The parent pointed to by the `ancestor_hashes[0]` has already been processed and accepted
* An attestation from the _proposer_ of the block (see later for definition) is included along with the block in the network message object * An attestation from the _proposer_ of the block (see later for definition) is included along with the block in the network message object
* The PoW chain block pointed to by the `pow_chain_reference` has already been processed and accepted * The PoW chain block pointed to by the `processed_pow_receipt_root` has already been processed and accepted
* The node's local clock time is greater than or equal to the minimum timestamp as computed by `GENESIS_TIME + block.slot * SLOT_DURATION` * The node's local clock time is greater than or equal to the minimum timestamp as computed by `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.
@ -551,8 +551,8 @@ def int_sqrt(n: int) -> int:
The beacon chain is initialized when a condition is met inside a contract on the existing PoW chain. This contract's code in Vyper is as follows: The beacon chain is initialized when a condition is met inside a contract on the existing PoW chain. This contract's code in Vyper is as follows:
```python ```python
HashChainValue: event({prev_tip: bytes32, data: bytes[2064], total_deposit_count: int128}) HashChainValue: event({previous_receipt_root: bytes32, data: bytes[2064], total_deposit_count: int128})
ChainStart: event({hash_chain_tip: bytes32, time: bytes[8]}) ChainStart: event({receipt_root: bytes32, time: bytes[8]})
receipt_tree: bytes32[int128] receipt_tree: bytes32[int128]
total_deposit_count: int128 total_deposit_count: int128
@ -597,7 +597,7 @@ If the user wishes to deposit more than `DEPOSIT_SIZE` ETH, they would need to m
* `initial_validator_entries` equal to the list of data records published as HashChainValue logs so far, in the order in which they were published (oldest to newest). * `initial_validator_entries` equal to the list of data records published as HashChainValue logs so far, in the order in which they were published (oldest to newest).
* `genesis_time` equal to the `time` value published in the log * `genesis_time` equal to the `time` value published in the log
* `pow_hash_chain_tip` equal to the `hash_chain_tip` value published in the log * `pow_receipt_root` equal to the `receipt_root` value published in the log
### On startup ### On startup
@ -619,7 +619,7 @@ A valid block with slot `0` (the "genesis block") has the following values. Othe
`STARTUP_STATE_ROOT` is the root of the initial state, computed by running the following code: `STARTUP_STATE_ROOT` is the root of the initial state, computed by running the following code:
```python ```python
def on_startup(initial_validator_entries: List[Any], genesis_time: uint64, pow_hash_chain_tip: Hash32) -> BeaconState: def on_startup(initial_validator_entries: List[Any], genesis_time: uint64, pow_receipt_root: Hash32) -> BeaconState:
# Induct validators # Induct validators
validators = [] validators = []
for pubkey, proof_of_possession, withdrawal_shard, withdrawal_address, \ for pubkey, proof_of_possession, withdrawal_shard, withdrawal_address, \
@ -655,14 +655,13 @@ def on_startup(initial_validator_entries: List[Any], genesis_time: uint64, pow_h
persistent_committees=split(shuffle(validators, bytes([0] * 32)), SHARD_COUNT), persistent_committees=split(shuffle(validators, bytes([0] * 32)), SHARD_COUNT),
persistent_committee_reassignments=[], persistent_committee_reassignments=[],
deposits_penalized_in_period=[], deposits_penalized_in_period=[],
next_shuffling_seed=b'\x00'*32, next_shuffling_seed=bytes([0] * 32),
validator_set_delta_hash_chain=bytes([0] * 32), # stub validator_set_delta_hash_chain=bytes([0] * 32), # stub
current_exit_seq=0, current_exit_seq=0,
genesis_time=genesis_time, genesis_time=genesis_time,
known_pow_hash_chain_tip=pow_hash_chain_tip, processed_pow_receipt_root=pow_receipt_root,
processed_pow_hash_chain_tip=pow_hash_chain_tip, candidate_pow_receipt_root=bytes([0] * 32),
candidate_pow_hash_chain_tip=bytes([0] * 32), candidate_pow_receipt_root_votes=0,
candidate_pow_hash_chain_tip_votes=0,
pre_fork_version=INITIAL_FORK_VERSION, pre_fork_version=INITIAL_FORK_VERSION,
post_fork_version=INITIAL_FORK_VERSION, post_fork_version=INITIAL_FORK_VERSION,
fork_slot_number=0, fork_slot_number=0,
@ -790,7 +789,7 @@ def on_startup(initial_validator_entries: List[Any]) -> BeaconState:
persistent_committees=split(shuffle(validators, bytes([0] * 32)), SHARD_COUNT), persistent_committees=split(shuffle(validators, bytes([0] * 32)), SHARD_COUNT),
persistent_committee_reassignments=[], persistent_committee_reassignments=[],
deposits_penalized_in_period=[], deposits_penalized_in_period=[],
next_shuffling_seed=b'\x00'*32, next_shuffling_seed=bytes([0] * 32),
validator_set_delta_hash_chain=bytes([0] * 32), # stub validator_set_delta_hash_chain=bytes([0] * 32), # stub
pre_fork_version=INITIAL_FORK_VERSION, pre_fork_version=INITIAL_FORK_VERSION,
post_fork_version=INITIAL_FORK_VERSION, post_fork_version=INITIAL_FORK_VERSION,
@ -860,11 +859,13 @@ Verify that `BLSVerify(pubkey=get_beacon_proposer(state, block.slot).pubkey, dat
### Verify and process RANDAO reveal ### Verify and process RANDAO reveal
* Let `repeat_hash(x, n) = x if n == 0 else repeat_hash(hash(x), n-1)`. * Let `repeat_hash(x, n) = x if n == 0 else repeat_hash(hash(x), n-1)`.
* Let `V = get_beacon_proposer(state, block.slot). * Let `V = get_beacon_proposer(state, block.slot)`.
* Verify that `repeat_hash(block.randao_reveal, (block.slot - V.randao_last_change) // RANDAO_SLOTS_PER_LAYER + 1) == V.randao_commitment` * Verify that `repeat_hash(block.randao_reveal, (block.slot - V.randao_last_change) // RANDAO_SLOTS_PER_LAYER + 1) == V.randao_commitment`
* Set `state.randao_mix = xor(state.randao_mix, block.randao_reveal)`, `V.randao_commitment = block.randao_reveal`, `V.randao_last_change = block.slot` * Set `state.randao_mix = xor(state.randao_mix, block.randao_reveal)`, `V.randao_commitment = block.randao_reveal`, `V.randao_last_change = block.slot`
Finally, if `block.candidate_pow_hash_chain_tip = state.candidate_pow_hash_chain_tip`, set `state.candidate_hash_chain_tip_votes += 1`. ### Process PoW receipt root
If `block.candidate_pow_receipt_root = state.candidate_pow_receipt_root` set `state.candidate_pow_receipt_root_votes += 1`.
### Process penalties, logouts and other special objects ### Process penalties, logouts and other special objects
@ -938,7 +939,7 @@ For each `proposal_signature`, verify that `BLSVerify(pubkey=validators[proposer
Note that `deposit_data` in serialized form should be the `DepositParams` followed by 8 bytes for the `msg_value` and 8 bytes for the `timestamp`, or exactly the `deposit_data` in the PoW contract of which the hash was placed into the Merkle tree. Note that `deposit_data` in serialized form should be the `DepositParams` followed by 8 bytes for the `msg_value` and 8 bytes for the `timestamp`, or exactly the `deposit_data` in the PoW contract of which the hash was placed into the Merkle tree.
Use the following procedure to verify the `merkle_branch`, setting `leaf=serialized_deposit_data`, `depth=POW_CONTRACT_MERKLE_TREE_DEPTH` and `root=state.known_pow_receipt_root`: Use the following procedure to verify the `merkle_branch`, setting `leaf=serialized_deposit_data`, `depth=POW_CONTRACT_MERKLE_TREE_DEPTH` and `root=state.processed_pow_receipt_root`:
```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:
@ -1012,11 +1013,11 @@ For every shard number `shard` for which a crosslink committee exists in the cyc
#### PoW chain related rules #### PoW chain related rules
If `last_state_recalculation_slot % POW_HASH_VOTING_PERIOD == 0`, then: If `last_state_recalculation_slot % POW_RECEIPT_ROOT_VOTING_PERIOD == 0`, then:
* If `state.candidate_hash_chain_tip_votes * 3 >= POW_HASH_VOTING_PERIOD * 2`, set `state.hash_chain_tip = state.candidate_hash_chain_tip` * If `state.candidate_pow_receipt_root_votes * 3 >= POW_RECEIPT_ROOT_VOTING_PERIOD * 2` set `state.processed_pow_receipt_root = state.candidate_pow_receipt_root`.
* Set `state.candidate_hash_chain_tip = block.candidate_pow_hash_chain_tip` * Set `state.candidate_pow_receipt_root = block.candidate_pow_receipt_root`.
* Set `state.candidate_hash_chain_tip_votes = 0` * Set `state.candidate_pow_receipt_root_votes = 0`.
### Validator set change ### Validator set change
@ -1151,7 +1152,6 @@ Note: This spec is ~65% complete.
**Missing** **Missing**
* [ ] Specify the rules around acceptable values for `pow_chain_reference` ([issue 58](https://github.com/ethereum/eth2.0-specs/issues/58))
* [ ] Specify the shard chain blocks, blobs, proposers, etc. * [ ] Specify the shard chain blocks, blobs, proposers, etc.
* [ ] Specify the deposit contract on the PoW chain in Vyper * [ ] Specify the deposit contract on the PoW chain in Vyper
* [ ] Specify the beacon chain genesis rules ([issue 58](https://github.com/ethereum/eth2.0-specs/issues/58)) * [ ] Specify the beacon chain genesis rules ([issue 58](https://github.com/ethereum/eth2.0-specs/issues/58))