From 61cf6209d841b97c4e20acab8a4e0ef519a3e746 Mon Sep 17 00:00:00 2001 From: Mikhail Kalinin Date: Mon, 14 Jan 2019 15:17:53 +0600 Subject: [PATCH 1/9] Fix one of proposer slashing verifications --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 570048219..a9b161abd 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1471,7 +1471,7 @@ For each `proposer_slashing` in `block.body.proposer_slashings`: * Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`. * Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`. * Verify that `proposer_slashing.proposal_data_1.block_root != proposer_slashing.proposal_data_2.block_root`. -* Verify that `validator.penalized_slot > state.slot`. +* Verify that `proposer.penalized_slot < state.slot`. * Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_1), signature=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`. * Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_2), signature=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`. * Run `penalize_validator(state, proposer_slashing.proposer_index)`. From bd506e12227850888df167926b52f8fd2db31915 Mon Sep 17 00:00:00 2001 From: terence tsao Date: Mon, 14 Jan 2019 16:06:33 -0800 Subject: [PATCH 2/9] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 40 ++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index b75641c5a..011cbd377 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -69,7 +69,7 @@ - [`get_shuffling`](#get_shuffling) - [`get_previous_epoch_committee_count_per_slot`](#get_previous_epoch_committee_count_per_slot) - [`get_current_epoch_committee_count_per_slot`](#get_current_epoch_committee_count_per_slot) - - [`get_shard_committees_at_slot`](#get_shard_committees_at_slot) + - [`get_crosslink_committees_at_slot`](#get_crosslink_committees_at_slot) - [`get_block_root`](#get_block_root) - [`get_randao_mix`](#get_randao_mix) - [`get_beacon_proposer_index`](#get_beacon_proposer_index) @@ -927,10 +927,10 @@ def get_current_epoch_committee_count_per_slot(state: BeaconState) -> int: return get_committee_count_per_slot(len(current_active_validators)) ``` -#### `get_shard_committees_at_slot` +#### `get_crosslink_committees_at_slot` ```python -def get_shard_committees_at_slot(state: BeaconState, +def get_crosslink_committees_at_slot(state: BeaconState, slot: int) -> List[Tuple[List[int], int]]: """ Returns the list of ``(committee, shard)`` tuples for the ``slot``. @@ -980,7 +980,7 @@ def get_block_root(state: BeaconState, return state.latest_block_roots[slot % LATEST_BLOCK_ROOTS_LENGTH] ``` -`get_block_root(_, s)` should always return `hash_tree_root` of the block in the beacon chain at slot `s`, and `get_shard_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes. +`get_block_root(_, s)` should always return `hash_tree_root` of the block in the beacon chain at slot `s`, and `get_crosslink_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes. #### `get_randao_mix` @@ -1003,7 +1003,7 @@ def get_beacon_proposer_index(state: BeaconState, """ Returns the beacon proposer index for the ``slot``. """ - first_committee, _ = get_shard_committees_at_slot(state, slot)[0] + first_committee, _ = get_crosslink_committees_at_slot(state, slot)[0] return first_committee[slot % len(first_committee)] ``` @@ -1031,15 +1031,15 @@ def get_attestation_participants(state: BeaconState, """ # Find the committee in the list with the desired shard - shard_committees = get_shard_committees_at_slot(state, attestation_data.slot) + crosslink_committees = get_crosslink_committees_at_slot(state, attestation_data.slot) - assert attestation.shard in [shard for _, shard in shard_committees] - shard_committee = [committee for committee, shard in shard_committees if shard == attestation_data.shard][0] + assert attestation.shard in [shard for _, shard in crosslink_committees] + crosslink_committee = [committee for committee, shard in crosslink_committees if shard == attestation_data.shard][0] assert len(participation_bitfield) == (len(committee) + 7) // 8 # Find the participating attesters in the committee participants = [] - for i, validator_index in enumerate(shard_committee): + for i, validator_index in enumerate(crosslink_committee): participation_bit = (participation_bitfield[i//8] >> (7 - (i % 8))) % 2 if participation_bit == 1: participants.append(validator_index) @@ -1616,14 +1616,14 @@ All [validators](#dfn-validator): **Note**: `previous_epoch_boundary_attesting_balance` balance might be marginally different than `current_epoch_boundary_attesting_balance` during the previous epoch transition. Due to the tight bound on validator churn each epoch and small per-epoch rewards/penalties, the potential balance difference is very low and only marginally affects consensus safety. -For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `shard_committee_at_slot = get_shard_committees_at_slot(slot)`. For every `(shard_committee, shard)` in `shard_committee_at_slot`, compute: +For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `crosslink_committee_at_slot = get_crosslink_committees_at_slot(slot)`. For every `(crosslink_committee, shard)` in `crosslink_committee_at_slot`, compute: * Let `shard_block_root` be `state.latest_crosslinks[shard].shard_block_root` -* Let `attesting_validator_indices(shard_committee, shard_block_root)` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.participation_bitfield) for a in current_epoch_attestations + previous_epoch_attestations if a.shard == shard and a.shard_block_root == shard_block_root]`. -* Let `winning_root(shard_committee)` be equal to the value of `shard_block_root` such that `sum([get_effective_balance(state, i) for i in attesting_validator_indices(shard_committee, shard_block_root)])` is maximized (ties broken by favoring lower `shard_block_root` values). -* Let `attesting_validators(shard_committee)` be equal to `attesting_validator_indices(shard_committee, winning_root(shard_committee))` for convenience. -* Let `total_attesting_balance(shard_committee) = sum([get_effective_balance(state, i) for i in attesting_validators(shard_committee)])`. -* Let `total_balance(shard_committee) = sum([get_effective_balance(state, i) for i in shard_committee])`. +* Let `attesting_validator_indices(crosslink_committee, shard_block_root)` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.participation_bitfield) for a in current_epoch_attestations + previous_epoch_attestations if a.shard == shard and a.shard_block_root == shard_block_root]`. +* Let `winning_root(crosslink_committee)` be equal to the value of `shard_block_root` such that `sum([get_effective_balance(state, i) for i in attesting_validator_indices(crosslink_committee, shard_block_root)])` is maximized (ties broken by favoring lower `shard_block_root` values). +* Let `attesting_validators(crosslink_committee)` be equal to `attesting_validator_indices(crosslink_committee, winning_root(crosslink_committee))` for convenience. +* Let `total_attesting_balance(crosslink_committee) = sum([get_effective_balance(state, i) for i in attesting_validators(crosslink_committee)])`. +* Let `total_balance(crosslink_committee) = sum([get_effective_balance(state, i) for i in crosslink_committee])`. Define the following helpers to process attestation inclusion rewards and inclusion distance reward/penalty. For every attestation `a` in `previous_epoch_attestations`: @@ -1652,9 +1652,9 @@ Set `state.finalized_slot = state.previous_justified_slot` if any of the followi ### Crosslinks -For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `shard_committee_at_slot = get_shard_committees_at_slot(slot)`. For every `(shard_committee, shard)` in `shard_committee_at_slot`, compute: +For every `slot in range(state.slot - 2 * EPOCH_LENGTH, state.slot)`, let `crosslink_committee_at_slot = get_crosslink_committees_at_slot(slot)`. For every `(crosslink_committee, shard)` in `crosslink_committee_at_slot`, compute: -* Set `state.latest_crosslinks[shard] = CrosslinkRecord(slot=state.slot, shard_block_root=winning_root(shard_committee))` if `3 * total_attesting_balance(shard_committee) >= 2 * total_balance(shard_committee)`. +* Set `state.latest_crosslinks[shard] = CrosslinkRecord(slot=state.slot, shard_block_root=winning_root(crosslink_committee))` if `3 * total_attesting_balance(crosslink_committee) >= 2 * total_balance(crosslink_committee)`. ### Rewards and penalties @@ -1698,10 +1698,10 @@ For each `index` in `previous_epoch_attester_indices`, we determine the proposer #### Crosslinks -For every `i in range(state.slot - 2 * EPOCH_LENGTH, state.slot - EPOCH_LENGTH)`, let `shard_committee_at_slot, start_shard = get_shard_committees_at_slot(i)`. For every `j in range(len(shard_committee_at_slot))`, let `shard_committee = shard_committee_at_slot[j]`, `shard = (start_shard + j) % SHARD_COUNT`, and compute: +For every `i in range(state.slot - 2 * EPOCH_LENGTH, state.slot - EPOCH_LENGTH)`, let `crosslink_committee_at_slot, start_shard = get_crosslink_committees_at_slot(i)`. For every `j in range(len(crosslink_committee_at_slot))`, let `crosslink_committee = crosslink_committee_at_slot[j]`, `shard = (start_shard + j) % SHARD_COUNT`, and compute: -* If `index in attesting_validators(shard_committee)`, `state.validator_balances[index] += base_reward(state, index) * total_attesting_balance(shard_committee) // total_balance(shard_committee))`. -* If `index not in attesting_validators(shard_committee)`, `state.validator_balances[index] -= base_reward(state, index)`. +* If `index in attesting_validators(crosslink_committee)`, `state.validator_balances[index] += base_reward(state, index) * total_attesting_balance(crosslink_committee) // total_balance(crosslink_committee))`. +* If `index not in attesting_validators(crosslink_committee)`, `state.validator_balances[index] -= base_reward(state, index)`. ### Ejections From 134ef6d2521b02372a73697ad913be0a1463b8d7 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Mon, 14 Jan 2019 20:44:30 -0800 Subject: [PATCH 3/9] Update specs/core/0_beacon-chain.md Co-Authored-By: terenc3t --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 011cbd377..368e6af0a 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -931,7 +931,7 @@ def get_current_epoch_committee_count_per_slot(state: BeaconState) -> int: ```python def get_crosslink_committees_at_slot(state: BeaconState, - slot: int) -> List[Tuple[List[int], int]]: + slot: int) -> List[Tuple[List[int], int]]: """ Returns the list of ``(committee, shard)`` tuples for the ``slot``. """ From aa990eb10e90d306562bf01a75482da0c064e68b Mon Sep 17 00:00:00 2001 From: terence tsao Date: Mon, 14 Jan 2019 21:07:36 -0800 Subject: [PATCH 4/9] update `shard committees` in get_shuffling --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 368e6af0a..8cf53770e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -881,7 +881,7 @@ def get_shuffling(seed: Hash32, validators: List[ValidatorRecord], slot: int) -> List[List[int]] """ - Shuffles ``validators`` into shard committees seeded by ``seed`` and ``slot``. + Shuffles ``validators`` into crosslink committees seeded by ``seed`` and ``slot``. Returns a list of ``EPOCH_LENGTH * committees_per_slot`` committees where each committee is itself a list of validator indices. """ From 8173854227782c1cfdc81815b46b93638697cf53 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Tue, 15 Jan 2019 12:02:17 +0600 Subject: [PATCH 5/9] Update specs/core/0_beacon-chain.md Co-Authored-By: mkalinin --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a9b161abd..2eda26acf 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1471,7 +1471,7 @@ For each `proposer_slashing` in `block.body.proposer_slashings`: * Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`. * Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`. * Verify that `proposer_slashing.proposal_data_1.block_root != proposer_slashing.proposal_data_2.block_root`. -* Verify that `proposer.penalized_slot < state.slot`. +* Verify that `proposer.penalized_slot > state.slot`. * Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_1), signature=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`. * Verify that `bls_verify(pubkey=proposer.pubkey, message=hash_tree_root(proposer_slashing.proposal_data_2), signature=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`. * Run `penalize_validator(state, proposer_slashing.proposer_index)`. From 5058e38b238f6e77170084af3527805c12b4493d Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Tue, 15 Jan 2019 20:26:53 -0800 Subject: [PATCH 6/9] fix ValidatorRegistryDeltaBlock field naming/reference inconsistency --- specs/core/0_beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 010dd06fd..60b426694 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1371,7 +1371,7 @@ def activate_validator(state: BeaconState, index: int, genesis: bool) -> None: validator.activation_slot = GENESIS_SLOT if genesis else (state.slot + ENTRY_EXIT_DELAY) state.validator_registry_delta_chain_tip = hash_tree_root( ValidatorRegistryDeltaBlock( - current_validator_registry_delta_chain_tip=state.validator_registry_delta_chain_tip, + latest_registry_delta_root=state.validator_registry_delta_chain_tip, validator_index=index, pubkey=validator.pubkey, slot=validator.activation_slot, @@ -1400,7 +1400,7 @@ def exit_validator(state: BeaconState, index: int) -> None: validator.exit_count = state.validator_registry_exit_count state.validator_registry_delta_chain_tip = hash_tree_root( ValidatorRegistryDeltaBlock( - current_validator_registry_delta_chain_tip=state.validator_registry_delta_chain_tip, + latest_registry_delta_root=state.validator_registry_delta_chain_tip, validator_index=index, pubkey=validator.pubkey, slot=validator.exit_slot, From 2c25ed9062f7a5f7fc160c55b05affe77f343111 Mon Sep 17 00:00:00 2001 From: Gregory Markou Date: Wed, 16 Jan 2019 14:05:53 -0500 Subject: [PATCH 7/9] fix typo with get_attestation_participants --- specs/core/0_beacon-chain.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 989513bd6..ebf430eb8 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1010,7 +1010,7 @@ def get_beacon_proposer_index(state: BeaconState, #### `merkle_root` ```python -def merkle_root(values): +def merkle_root(values: [hash32]) -> hash32: """ Merkleize ``values`` (where ``len(values)`` is a power of two) and return the Merkle root. """ @@ -1032,8 +1032,8 @@ def get_attestation_participants(state: BeaconState, # Find the committee in the list with the desired shard crosslink_committees = get_crosslink_committees_at_slot(state, attestation_data.slot) - - assert attestation.shard in [shard for _, shard in crosslink_committees] + + assert attestation_data.shard in [shard for _, shard in crosslink_committees] crosslink_committee = [committee for committee, shard in crosslink_committees if shard == attestation_data.shard][0] assert len(participation_bitfield) == (len(committee) + 7) // 8 From 3b1ccae58cb7ad5e3cc9a86981356ab0393132e6 Mon Sep 17 00:00:00 2001 From: Dean Eigenmann Date: Wed, 16 Jan 2019 20:35:01 +0100 Subject: [PATCH 8/9] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 989513bd6..33de997b8 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1092,8 +1092,8 @@ def verify_slashable_vote_data(state: BeaconState, vote_data: SlashableVoteData) return bls_verify_multiple( pubkeys=[ - aggregate_pubkey([state.validators[i].pubkey for i in vote_data.custody_bit_0_indices]), - aggregate_pubkey([state.validators[i].pubkey for i in vote_data.custody_bit_1_indices]), + bls_aggregate_pubkey([state.validators[i].pubkey for i in vote_data.custody_bit_0_indices]), + bls_aggregate_pubkey([state.validators[i].pubkey for i in vote_data.custody_bit_1_indices]), ], messages=[ hash_tree_root(AttestationDataAndCustodyBit(vote_data.data, False)), From e5ea67f4acf960b00550b4b7cebbfd591330827c Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 16 Jan 2019 14:39:00 -0500 Subject: [PATCH 9/9] Update specs/core/0_beacon-chain.md Co-Authored-By: GregTheGreek --- specs/core/0_beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index ebf430eb8..078a92add 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1010,7 +1010,7 @@ def get_beacon_proposer_index(state: BeaconState, #### `merkle_root` ```python -def merkle_root(values: [hash32]) -> hash32: +def merkle_root(values: List[Hash32]) -> Hash32: """ Merkleize ``values`` (where ``len(values)`` is a power of two) and return the Merkle root. """