From db65429cc8c85c599c80ff4e7a719c4892008e62 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Wed, 5 Dec 2018 19:24:37 -0600 Subject: [PATCH] rework to do virtual block transitions --- specs/core/0_beacon-chain.md | 51 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 66d0d2f52..4d17e2eb3 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -637,7 +637,7 @@ Processing the beacon chain is similar to processing the Ethereum 1.0 chain. Cli For a beacon chain block, `block`, to be processed by a node, the following conditions must be met: -* The parent block (possibly a skip block) with hash `block.ancestor_hashes[0]` has been processed and accepted. +* The parent block with hash `block.ancestor_hashes[0]` has been processed and accepted. * The Ethereum 1.0 block pointed to by the `state.processed_pow_receipt_root` has been processed and accepted. * The node's local clock time is greater than or equal to `state.genesis_time + block.slot * SLOT_DURATION`. @@ -1192,7 +1192,7 @@ def exit_validator(index: int, Below are the processing steps that happen at every slot. -First we define the following helpers. +First we define the following helper. ```python def get_updated_ancestor_hashes(parent: BeaconBlock, @@ -1202,39 +1202,23 @@ def get_updated_ancestor_hashes(parent: BeaconBlock, if parent.slot % 2**i == 0: new_ancestor_hashes[i] = parent_hash return new_ancestor_hashes - - -def get_skip_block(slot: int, - parent: BeaconBlock, - parent_hash: Hash32) -> BeaconBlock: - return BeaconBlock( - slot=state.slot, - randao_reveal=ZERO_HASH, - candidate_pow_receipt_root=ZERO_HASH, - ancestor_hashes=get_updated_ancestor_hashes(parent, parent_hash), - state_root=ZERO_HASH, # filled in with post-state-transition root - attestations=[], - specials=[], - proposer_signature=[0, 0] - ) ``` -* Let `parent_hash` be the hash of the beacon block at the immediate previous slot. +* Let `parent_hash` be the hash of the latest beacon block that was processed in the chain. * Let `parent` be the `BeaconBlock` with the hash `parent_hash`. +* Set `state.latest_block_hashes = state.latest_block_hashes + [parent_hash]`. (The output of `get_block_hash` should not change, except that it will no longer throw for `state.slot - 1`). If there is a block from the proposer for `state.slot`, we process that incoming block: +* Let `skip_block = False` * Let `block` be that associated incoming block. +* Verify that `block.ancestor_hashes` equals `get_updated_ancestor_hashes(parent, parent_hash)`. -If there is not a block from the proposer for `state.slot`, a "skip block" is inserted into the beacon chain: -* Let `block` be a skip block defined by `get_skip_block(state.slot, parent, parent_hash)`. - -Verify that `block.ancestor_hashes` equals `get_updated_ancestor_hashes(parent, parent_hash)`. - -Set `state.latest_block_hashes = state.latest_block_hashes + [parent_hash]`. (The output of `get_block_hash` should not change, except that it will no longer throw for `state.slot - 1`). +If there is not a block from the proposer for `state.slot`, the slot is processed without a block: +* Let `skip_block = True` ### Proposer signature -If `block` is not a skip block: +If not `skip_block`: * Let `block_hash_without_sig` be the hash of `block` where `proposer_signature` is set to `[0, 0]`. * Let `proposal_hash = hash(ProposalSignedData(state.slot, BEACON_CHAIN_SHARD_NUMBER, block_hash_without_sig))`. @@ -1242,6 +1226,8 @@ If `block` is not a skip block: ### Attestations +*If `skip_block`, do not process attestations. Move to next section.* + * Verify that `len(block.attestations) <= MAX_ATTESTATIONS_PER_BLOCK`. For each `attestation` in `block.attestations`: @@ -1260,11 +1246,11 @@ For each `attestation` in `block.attestations`: ### RANDAO -If `block` is a skip block: +If `skip_block`: * Let `state.validator_registry[get_beacon_proposer_index(state, state.slot)].randao_skips += 1`. -If `block` is not a skip block: +If not `skip_block`: * Let `repeat_hash(x, n) = x if n == 0 else repeat_hash(hash(x), n-1)`. * Let `proposer = state.validator_registry[get_beacon_proposer_index(state, state.slot)]`. @@ -1275,13 +1261,16 @@ If `block` is not a skip block: ### PoW receipt root -If `block` is not a skip block: +*If `skip_block`, do not process PoW receipt root. Move to next section.* + * If `block.candidate_pow_receipt_root` is `x.candidate_pow_receipt_root` for some `x` in `state.candidate_pow_receipt_roots`, set `x.votes += 1`. * Otherwise, append to `state.candidate_pow_receipt_roots` a new `CandidatePoWReceiptRootRecord(candidate_pow_receipt_root=block.candidate_pow_receipt_root, votes=1)`. ### Special objects +*If `skip_block`, do not process special objects. Move to next section.* + * Verify that the quantity of each type of object in `block.specials` is less than or equal to its maximum (see table at the top). * Verify that objects are sorted in order of `kind`. That is, `block.specials[i+1].kind >= block.specials[i].kind` for `0 <= i < len(block.specials-1)`. @@ -1615,11 +1604,9 @@ while len(state.persistent_committee_reassignments) > 0 and state.persistent_com ## State root processing -If `block` is not a skip block: -* Verify `block.state_root == hash(state)` +*If `skip_block`, do not process state root. Move to next section.* -If `block` is a skip block: -* Set `block.state_root = hash(state)` +Verify `block.state_root == hash(state)` # Appendix ## Appendix A - Hash function