From 9ce7a8e5919dbafba7d7b9436759dd931647b114 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 27 Sep 2019 09:41:12 +0900 Subject: [PATCH 1/3] working through lint and format on shard chains --- specs/core/1_beacon-chain-misc.md | 29 ++++++++++++++++++++--------- specs/core/1_shard-data-chains.md | 10 +++++++--- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/specs/core/1_beacon-chain-misc.md b/specs/core/1_beacon-chain-misc.md index 5bb0f6da0..0b5ed5234 100644 --- a/specs/core/1_beacon-chain-misc.md +++ b/specs/core/1_beacon-chain-misc.md @@ -34,6 +34,7 @@ | `MAX_SHARD_RECEIPT_PROOFS` | `2**0` (= 1) | - | - | | `PERIOD_COMMITTEE_ROOT_LENGTH` | `2**8` (= 256) | periods | ~9 months | | `MINOR_REWARD_QUOTIENT` | `2**8` (=256) | - | - | +| `REWARD_COEFFICIENT_BASE` | **TBD** | - | - | ## Containers @@ -45,6 +46,16 @@ class CompactCommittee(Container): compact_validators: List[uint64, MAX_VALIDATORS_PER_COMMITTEE] ``` +#### `ShardReceiptDelta` + +```python +class ShardReceiptDelta(Container): + index: ValidatorIndex + reward_coefficient: uint64 + block_fee: Gwei +``` + + #### `ShardReceiptProof` ```python @@ -112,16 +123,17 @@ def verify_merkle_proof(leaf: Hash, proof: Sequence[Hash], index: GeneralizedInd ```python def compute_historical_state_generalized_index(earlier: ShardSlot, later: ShardSlot) -> GeneralizedIndex: """ - Computes the generalized index of the state root of slot `frm` based on the state root of slot `to`. - Relies on the `history_acc` in the `ShardState`, where `history_acc[i]` maintains the most recent 2**i'th - slot state. Works by tracing a `log(later-earlier)` step path from `later` to `earlier` through intermediate - blocks at the next available multiples of descending powers of two. + Computes the generalized index of the state root of slot `earlier` based on the state root of slot `later`. + Relies on the `history_accumulator` in the `ShardState`, where `history_accumulator[i]` maintains the most + recent 2**i'th slot state. Works by tracing a `log(later-earlier)` step path from `later` to `earlier` + through intermediate blocks at the next available multiples of descending powers of two. """ o = GeneralizedIndex(1) - for i in range(HISTORY_ACCUMULATOR_VECTOR - 1, -1, -1): + for i in range(HISTORY_ACCUMULATOR_DEPTH - 1, -1, -1): if (later - 1) & 2**i > (earlier - 1) & 2**i: later = later - ((later - 1) % 2**i) - 1 - o = concat_generalized_indices(o, GeneralizedIndex(get_generalized_index(ShardState, ['history_acc', i]))) + gindex = GeneralizedIndex(get_generalized_index(ShardState, ['history_accumulator', i])) + o = concat_generalized_indices(o, gindex) return o ``` @@ -133,7 +145,7 @@ def get_generalized_index_of_crosslink_header(index: int) -> GeneralizedIndex: Gets the generalized index for the root of the index'th header in a crosslink. """ MAX_CROSSLINK_SIZE = ( - SHARD_BLOCK_SIZE_LIMIT * SHARD_SLOTS_PER_BEACON_SLOT * SLOTS_PER_EPOCH * MAX_EPOCHS_PER_CROSSLINK + MAX_SHARD_BLOCK_SIZE * SHARD_SLOTS_PER_EPOCH * MAX_EPOCHS_PER_CROSSLINK ) assert MAX_CROSSLINK_SIZE == get_previous_power_of_two(MAX_CROSSLINK_SIZE) return GeneralizedIndex(MAX_CROSSLINK_SIZE // SHARD_HEADER_SIZE + index) @@ -146,10 +158,9 @@ def process_shard_receipt_proof(state: BeaconState, receipt_proof: ShardReceiptP """ Processes a ShardReceipt object. """ - SHARD_SLOTS_PER_EPOCH = SHARD_SLOTS_PER_BEACON_SLOT * SLOTS_PER_EPOCH receipt_slot = ( state.next_shard_receipt_period[receipt_proof.shard] * - SHARD_SLOTS_PER_BEACON_SLOT * SLOTS_PER_EPOCH * EPOCHS_PER_SHARD_PERIOD + SHARD_SLOTS_PER_EPOCH * EPOCHS_PER_SHARD_PERIOD ) first_slot_in_last_crosslink = state.current_crosslinks[receipt_proof.shard].start_epoch * SHARD_SLOTS_PER_EPOCH gindex = concat_generalized_indices( diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index 4596d250b..4e26c7c72 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -356,6 +356,8 @@ def process_shard_block_header(beacon_state: BeaconState, shard_state: ShardStat assert block.block_size_sum == shard_state.block_size_sum # Verify proposer signature proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) + assert proposer_index is not None + domain = get_domain(beacon_state, DOMAIN_SHARD_PROPOSER, compute_epoch_of_shard_slot(block.slot)) assert bls_verify(beacon_state.validators[proposer_index].pubkey, signing_root(block), block.signature, domain) ``` @@ -381,8 +383,9 @@ def process_shard_attestations(beacon_state: BeaconState, shard_state: ShardStat assert bls_verify(bls_aggregate_pubkeys(pubkeys), message, block.attestations, domain) # Proposer micro-reward proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) + assert proposer_index is not None reward = attestation_count * get_base_reward(beacon_state, proposer_index) // PROPOSER_REWARD_QUOTIENT - process_delta(beacon_state, shard_state, proposer_index, reward) + process_delta(beacon_state, shard_state, proposer_index, Gwei(reward)) ``` #### Block body @@ -394,8 +397,9 @@ def process_shard_block_body(beacon_state: BeaconState, shard_state: ShardState, # Apply proposer block body fee block_body_fee = shard_state.block_body_price * len(block.body) // MAX_SHARD_BLOCK_SIZE proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) - process_delta(beacon_state, shard_state, proposer_index, block_body_fee, positive=False) # Burn - process_delta(beacon_state, shard_state, proposer_index, block_body_fee // PROPOSER_REWARD_QUOTIENT) # Reward + assert proposer_index is not None + process_delta(beacon_state, shard_state, proposer_index, Gwei(block_body_fee), positive=False) # Burn + process_delta(beacon_state, shard_state, proposer_index, Gwei(block_body_fee // PROPOSER_REWARD_QUOTIENT)) # Reward # Calculate new block body price block_size = SHARD_HEADER_SIZE + len(block.body) QUOTIENT = MAX_SHARD_BLOCK_SIZE * BLOCK_BODY_PRICE_QUOTIENT From 86ed3937dc6f5e52ae7b869e4696a132ec054171 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 27 Sep 2019 10:34:19 +0900 Subject: [PATCH 2/3] fix a couple of minor shard chain bugs --- specs/core/1_beacon-chain-misc.md | 22 ++++++++++++---------- specs/core/1_shard-data-chains.md | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/specs/core/1_beacon-chain-misc.md b/specs/core/1_beacon-chain-misc.md index 0b5ed5234..6dd6e19c3 100644 --- a/specs/core/1_beacon-chain-misc.md +++ b/specs/core/1_beacon-chain-misc.md @@ -226,16 +226,18 @@ def update_period_committee(state: BeaconState) -> None: """ Updates period committee roots at boundary blocks. """ - if (get_current_epoch(state) + 1) % EPOCHS_PER_SHARD_PERIOD == 0: - period = (get_current_epoch(state) + 1) // EPOCHS_PER_SHARD_PERIOD - committees = Vector[CompactCommittee, SHARD_COUNT]([ - committee_to_compact_committee( - state, - get_period_committee(state, Epoch(get_current_epoch(state) + 1), Shard(shard)), - ) - for shard in range(SHARD_COUNT) - ]) - state.period_committee_roots[period % PERIOD_COMMITTEE_ROOT_LENGTH] = hash_tree_root(committees) + if (get_current_epoch(state) + 1) % EPOCHS_PER_SHARD_PERIOD != 0: + return + + period = (get_current_epoch(state) + 1) // EPOCHS_PER_SHARD_PERIOD + committees = Vector[CompactCommittee, SHARD_COUNT]([ + committee_to_compact_committee( + state, + get_period_committee(state, Shard(shard), Epoch(get_current_epoch(state) + 1)), + ) + for shard in range(SHARD_COUNT) + ]) + state.period_committee_roots[period % PERIOD_COMMITTEE_ROOT_LENGTH] = hash_tree_root(committees) ``` ### Shard receipt processing diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index ebb1b6b68..96b2de41a 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -224,7 +224,7 @@ def process_delta(beacon_state: BeaconState, index: ValidatorIndex, delta: Gwei, positive: bool=True) -> None: - epoch = compute_epoch_of_shard_slot(beacon_state.slot) + epoch = compute_epoch_of_shard_slot(shard_state.slot) older_committee = get_period_committee(beacon_state, shard_state.shard, compute_shard_period_start_epoch(epoch, 2)) newer_committee = get_period_committee(beacon_state, shard_state.shard, compute_shard_period_start_epoch(epoch, 1)) if index in older_committee: From b259d3518b28622b2627a4b23932d790ff8d652c Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 30 Sep 2019 11:34:28 +0900 Subject: [PATCH 3/3] move assert to get_beacon_proposer_index --- scripts/build_spec.py | 2 +- specs/core/1_shard-data-chains.md | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/scripts/build_spec.py b/scripts/build_spec.py index ffdbda505..f35332e64 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -37,7 +37,7 @@ from eth2spec.utils.bls import ( from eth2spec.utils.hash_function import hash ''' PHASE1_IMPORTS = '''from typing import ( - Any, Dict, Optional, Set, Sequence, MutableSequence, NewType, Tuple, Union, + Any, Dict, Set, Sequence, MutableSequence, NewType, Tuple, Union, ) from math import ( log2, diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index 96b2de41a..9293a50da 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -202,12 +202,11 @@ def get_shard_committee(beacon_state: BeaconState, shard: Shard, epoch: Epoch) - #### `get_shard_proposer_index` ```python -def get_shard_proposer_index(beacon_state: BeaconState, shard: Shard, slot: ShardSlot) -> Optional[ValidatorIndex]: +def get_shard_proposer_index(beacon_state: BeaconState, shard: Shard, slot: ShardSlot) -> ValidatorIndex: epoch = get_current_epoch(beacon_state) shard_committee = get_shard_committee(beacon_state, shard, epoch) active_indices = [i for i in shard_committee if is_active_validator(beacon_state.validators[i], epoch)] - if not any(active_indices): - return None + assert any(active_indices) epoch_seed = get_seed(beacon_state, epoch, DOMAIN_SHARD_PROPOSER) seed = hash(epoch_seed + int_to_bytes(slot, length=8) + int_to_bytes(shard, length=8)) @@ -356,7 +355,6 @@ def process_shard_block_header(beacon_state: BeaconState, shard_state: ShardStat assert block.block_size_sum == shard_state.block_size_sum # Verify proposer is not slashed proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) - assert proposer_index is not None proposer = beacon_state.validators[proposer_index] assert not proposer.slashed # Verify proposer signature @@ -385,7 +383,6 @@ def process_shard_attestations(beacon_state: BeaconState, shard_state: ShardStat assert bls_verify(bls_aggregate_pubkeys(pubkeys), message, block.attestations, domain) # Proposer micro-reward proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) - assert proposer_index is not None reward = attestation_count * get_base_reward(beacon_state, proposer_index) // PROPOSER_REWARD_QUOTIENT process_delta(beacon_state, shard_state, proposer_index, Gwei(reward)) ``` @@ -399,7 +396,6 @@ def process_shard_block_body(beacon_state: BeaconState, shard_state: ShardState, # Apply proposer block body fee block_body_fee = shard_state.block_body_price * len(block.body) // MAX_SHARD_BLOCK_SIZE proposer_index = get_shard_proposer_index(beacon_state, shard_state.shard, block.slot) - assert proposer_index is not None process_delta(beacon_state, shard_state, proposer_index, Gwei(block_body_fee), positive=False) # Burn process_delta(beacon_state, shard_state, proposer_index, Gwei(block_body_fee // PROPOSER_REWARD_QUOTIENT)) # Reward # Calculate new block body price