From 81c6b561fcab8c316916db079489c11281540d82 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 02:07:12 +0800 Subject: [PATCH 1/8] `CandidatePoWReceiptRootRecord.votes` -> `CandidatePoWReceiptRootRecord.vote_count` --- specs/core/0_beacon-chain.md | 46 ++++-------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f3748a56c..363172dfb 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -59,44 +59,6 @@ - [Helper functions](#helper-functions) - [`hash`](#hash) - [`is_active_validator`](#is_active_validator) - - [`get_active_validator_indices`](#get_active_validator_indices) - - [`shuffle`](#shuffle) - - [`split`](#split) - - [`clamp`](#clamp) - - [`get_new_shuffling`](#get_new_shuffling) - - [`get_shard_committees_at_slot`](#get_shard_committees_at_slot) - - [`get_block_root`](#get_block_root) - - [`get_beacon_proposer_index`](#get_beacon_proposer_index) - - [`merkle_root`](#merkle_root) - - [`get_attestation_participants`](#get_attestation_participants) - - [`bytes1`, `bytes2`, ...](#bytes1-bytes2-) - - [`get_effective_balance`](#get_effective_balance) - - [`get_new_validator_registry_delta_chain_tip`](#get_new_validator_registry_delta_chain_tip) - - [`get_fork_version`](#get_fork_version) - - [`get_domain`](#get_domain) - - [`hash_tree_root`](#hash_tree_root) - - [`verify_casper_votes`](#verify_casper_votes) - - [`integer_squareroot`](#integer_squareroot) - - [`bls_verify`](#bls_verify) - - [`bls_verify_multiple`](#bls_verify_multiple) - - [On startup](#on-startup) - - [Routine for processing deposits](#routine-for-processing-deposits) - - [Routine for updating validator status](#routine-for-updating-validator-status) - - [Per-slot processing](#per-slot-processing) - - [Misc counters](#misc-counters) - - [Block roots](#block-roots) - - [Per-block processing](#per-block-processing) - - [Slot](#slot) - - [Proposer signature](#proposer-signature) - - [RANDAO](#randao) - - [PoW receipt root](#pow-receipt-root) - - [Operations](#operations) - - [Proposer slashings](#proposer-slashings-1) - - [Casper slashings](#casper-slashings-1) - - [Attestations](#attestations-1) - - [Deposits](#deposits-1) - - [Exits](#exits-1) - - [Ejections](#ejections) - [Per-epoch processing](#per-epoch-processing) - [Helpers](#helpers) - [Receipt roots](#receipt-roots) @@ -541,7 +503,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted # Candidate PoW receipt root 'candidate_pow_receipt_root': 'hash32', # Vote count - 'votes': 'uint64', + 'vote_count': 'uint64', } ``` @@ -1343,8 +1305,8 @@ Below are the processing steps that happen at every `block`. ### PoW receipt root -* 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)`. +* If `block.candidate_pow_receipt_root` is `x.candidate_pow_receipt_root` for some `x` in `state.candidate_pow_receipt_roots`, set `x.vote_count += 1`. +* Otherwise, append to `state.candidate_pow_receipt_roots` a new `CandidatePoWReceiptRootRecord(candidate_pow_receipt_root=block.candidate_pow_receipt_root, vote_count=1)`. ### Operations @@ -1528,7 +1490,7 @@ def adjust_for_inclusion_distance(magnitude: int, distance: int) -> int: If `state.slot % POW_RECEIPT_ROOT_VOTING_PERIOD == 0`: -* Set `state.processed_pow_receipt_root = x.receipt_root` if `x.votes * 2 > POW_RECEIPT_ROOT_VOTING_PERIOD` for some `x` in `state.candidate_pow_receipt_root`. +* Set `state.processed_pow_receipt_root = x.receipt_root` if `x.vote_count * 2 > POW_RECEIPT_ROOT_VOTING_PERIOD` for some `x` in `state.candidate_pow_receipt_root`. * Set `state.candidate_pow_receipt_roots = []`. ### Justification From ac3ffb3df62764712a34590525f330bbb952e1df Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 02:08:37 +0800 Subject: [PATCH 2/8] `LATEST_BLOCK_ROOTS_COUNT` -> `LATEST_BLOCK_ROOT_COUNT` --- 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 363172dfb..fe1b9c24e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -122,7 +122,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted | `BEACON_CHAIN_SHARD_NUMBER` | `2**64 - 1` | - | | `BLS_WITHDRAWAL_PREFIX_BYTE` | `0x00` | - | | `MAX_CASPER_VOTES` | `2**10` (= 1,024) | votes | -| `LATEST_BLOCK_ROOTS_COUNT` | `2**13` (= 8,192) | block roots | +| `LATEST_BLOCK_ROOT_COUNT` | `2**13` (= 8,192) | block roots | * For the safety of crosslinks a minimum committee size of 111 is [recommended](https://vitalik.ca/files/Ithaca201807_Sharding.pdf). (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) The shuffling algorithm generally ensures (assuming sufficient validators) committee sizes at least `TARGET_COMMITTEE_SIZE // 2`. @@ -1061,7 +1061,7 @@ def on_startup(initial_validator_deposits: List[Deposit], # Recent state latest_crosslinks=[CrosslinkRecord(slot=INITIAL_SLOT_NUMBER, shard_block_root=ZERO_HASH) for _ in range(SHARD_COUNT)], - latest_block_roots=[ZERO_HASH for _ in range(LATEST_BLOCK_ROOTS_COUNT)], + latest_block_roots=[ZERO_HASH for _ in range(LATEST_BLOCK_ROOT_COUNT)], latest_penalized_exit_balances=[], latest_attestations=[], batched_block_roots=[] @@ -1278,7 +1278,7 @@ Below are the processing steps that happen at every slot. * Let `previous_block_root` be the `tree_hash_root` of the previous beacon block processed in the chain. * Set `state.latest_block_roots = state.latest_block_roots[1:] + [previous_block_root]`. -* If `state.slot % LATEST_BLOCK_ROOTS_COUNT == 0` append `merkle_root(state.latest_block_roots)` to `state.batched_block_roots`. +* If `state.slot % LATEST_BLOCK_ROOT_COUNT == 0` append `merkle_root(state.latest_block_roots)` to `state.batched_block_roots`. ## Per-block processing From ae5221c4f83ef2e2d9b084fad4d6ddd5309c43a4 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 02:11:47 +0800 Subject: [PATCH 3/8] Move BLS verification to later step --- 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 fe1b9c24e..5b845ff4f 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1317,12 +1317,12 @@ Verify that `len(block.body.proposer_slashings) <= MAX_PROPOSER_SLASHINGS`. For each `proposer_slashing` in `block.body.proposer_slashings`: * Let `proposer = state.validator_registry[proposer_slashing.proposer_index]`. -* 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))`. * 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.status != EXITED_WITH_PENALTY`. +* 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 `update_validator_status(state, proposer_slashing.proposer_index, new_status=EXITED_WITH_PENALTY)`. #### Casper slashings @@ -1401,10 +1401,10 @@ Verify that `len(block.body.exits) <= MAX_EXITS`. For each `exit` in `block.body.exits`: * Let `validator = state.validator_registry[exit.validator_index]`. -* Verify that `bls_verify(pubkey=validator.pubkey, message=ZERO_HASH, signature=exit.signature, domain=get_domain(state.fork_data, exit.slot, DOMAIN_EXIT))`. * Verify that `validator.status == ACTIVE`. * Verify that `state.slot >= exit.slot`. * Verify that `state.slot >= validator.latest_status_change_slot + SHARD_PERSISTENT_COMMITTEE_CHANGE_PERIOD`. +* Verify that `bls_verify(pubkey=validator.pubkey, message=ZERO_HASH, signature=exit.signature, domain=get_domain(state.fork_data, exit.slot, DOMAIN_EXIT))`. * Run `update_validator_status(state, validator_index, new_status=ACTIVE_PENDING_EXIT)`. ### Ejections From 4aa6ec4468e6410bff4a21fddaadba4330212f29 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 02:55:28 +0800 Subject: [PATCH 4/8] Update `CasperSlashing` and `verify_casper_votes` 1. Rename `verify_casper_votes` -> `verify_slashable_vote_data` 2. Rename `CasperSlashing.votes_1` -> `CasperSlashing.slashable_vote_data_1` 3. Rename `CasperSlashing.votes_2` -> `CasperSlashing.slashable_vote_data_2` 4. Fix `verify_slashable_vote_data` `(verify_casper_votes)` --- specs/core/0_beacon-chain.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 5b845ff4f..fa15e53c6 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -234,9 +234,9 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted ```python { # First batch of votes - 'votes_1': SlashableVoteData, + 'slashable_vote_data_1': SlashableVoteData, # Second batch of votes - 'votes_2': SlashableVoteData, + 'slashable_vote_data_2': SlashableVoteData, } ``` @@ -965,16 +965,22 @@ def get_domain(fork_data: ForkData, `hash_tree_root` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash). -#### `verify_casper_votes` +#### `verify_slashable_vote_data` ```python -def verify_casper_votes(state: BeaconState, votes: SlashableVoteData) -> bool: - if len(votes.aggregate_signature_poc_0_indices) + len(votes.aggregate_signature_poc_1_indices) > MAX_CASPER_VOTES: +def verify_slashable_vote_data(state: BeaconState, vote_data: SlashableVoteData) -> bool: + if len(vote_data.aggregate_signature_poc_0_indices) + len(vote_data.aggregate_signature_poc_1_indices) > MAX_CASPER_VOTES: return False - pubs = [aggregate_pubkey([state.validators[i].pubkey for i in votes.aggregate_signature_poc_0_indices]), - aggregate_pubkey([state.validators[i].pubkey for i in votes.aggregate_signature_poc_1_indices])] - return bls_verify_multiple(pubkeys=pubs, messages=[hash_tree_root(votes)+bytes1(0), hash_tree_root(votes)+bytes1(1), signature=aggregate_signature) + pubs = [ + aggregate_pubkey([state.validators[i].pubkey for i in vote_data.aggregate_signature_poc_0_indices]), + aggregate_pubkey([state.validators[i].pubkey for i in vote_data.aggregate_signature_poc_1_indices]) + ] + return bls_verify_multiple( + pubkeys=pubs, + messages=[hash_tree_root(vote_data)+bytes1(0), hash_tree_root(vote_data)+bytes1(1)],signature=vote_data.aggregate_signature, + domain=DOMAIN_ATTESTATION, + ) ``` #### `integer_squareroot` @@ -1331,13 +1337,13 @@ Verify that `len(block.body.casper_slashings) <= MAX_CASPER_SLASHINGS`. For each `casper_slashing` in `block.body.casper_slashings`: -* Verify that `verify_casper_votes(state, casper_slashing.votes_1)`. -* Verify that `verify_casper_votes(state, casper_slashing.votes_2)`. -* Verify that `casper_slashing.votes_1.data != casper_slashing.votes_2.data`. +* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_1)`. +* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_2)`. +* Verify that `casper_slashing.slashable_vote_data_1.data != casper_slashing.slashable_vote_data_2.data`. * Let `indices(vote) = vote.aggregate_signature_poc_0_indices + vote.aggregate_signature_poc_1_indices`. -* Let `intersection = [x for x in indices(casper_slashing.votes_1) if x in indices(casper_slashing.votes_2)]`. +* Let `intersection = [x for x in indices(casper_slashing.slashable_vote_data_1) if x in indices(casper_slashing.slashable_vote_data_2)]`. * Verify that `len(intersection) >= 1`. -* Verify that `casper_slashing.votes_1.data.justified_slot + 1 < casper_slashing.votes_2.data.justified_slot + 1 == casper_slashing.votes_2.data.slot < casper_slashing.votes_1.data.slot` or `casper_slashing.votes_1.data.slot == casper_slashing.votes_2.data.slot`. +* Verify that `casper_slashing.slashable_vote_data_1.data.justified_slot + 1 < casper_slashing.slashable_vote_data_2.data.justified_slot + 1 == casper_slashing.slashable_vote_data_2.data.slot < casper_slashing.slashable_vote_data_1.data.slot` or `casper_slashing.slashable_vote_data_1.data.slot == casper_slashing.slashable_vote_data_2.data.slot`. * For each [validator](#dfn-validator) index `i` in `intersection`, if `state.validator_registry[i].status` does not equal `EXITED_WITH_PENALTY`, then run `update_validator_status(state, i, new_status=EXITED_WITH_PENALTY)` #### Attestations From d2fda68ccb18de7b9a060753e9a701edec72623d Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 03:00:53 +0800 Subject: [PATCH 5/8] Fix ToC --- specs/core/0_beacon-chain.md | 42 ++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index fa15e53c6..cd63413c0 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -59,6 +59,44 @@ - [Helper functions](#helper-functions) - [`hash`](#hash) - [`is_active_validator`](#is_active_validator) + - [`get_active_validator_indices`](#get_active_validator_indices) + - [`shuffle`](#shuffle) + - [`split`](#split) + - [`clamp`](#clamp) + - [`get_new_shuffling`](#get_new_shuffling) + - [`get_shard_committees_at_slot`](#get_shard_committees_at_slot) + - [`get_block_root`](#get_block_root) + - [`get_beacon_proposer_index`](#get_beacon_proposer_index) + - [`merkle_root`](#merkle_root) + - [`get_attestation_participants`](#get_attestation_participants) + - [`bytes1`, `bytes2`, ...](#bytes1-bytes2-) + - [`get_effective_balance`](#get_effective_balance) + - [`get_new_validator_registry_delta_chain_tip`](#get_new_validator_registry_delta_chain_tip) + - [`get_fork_version`](#get_fork_version) + - [`get_domain`](#get_domain) + - [`hash_tree_root`](#hash_tree_root) + - [`verify_slashable_vote_data`](#verify_slashable_vote_data) + - [`integer_squareroot`](#integer_squareroot) + - [`bls_verify`](#bls_verify) + - [`bls_verify_multiple`](#bls_verify_multiple) + - [On startup](#on-startup) + - [Routine for processing deposits](#routine-for-processing-deposits) + - [Routine for updating validator status](#routine-for-updating-validator-status) + - [Per-slot processing](#per-slot-processing) + - [Misc counters](#misc-counters) + - [Block roots](#block-roots) + - [Per-block processing](#per-block-processing) + - [Slot](#slot) + - [Proposer signature](#proposer-signature) + - [RANDAO](#randao) + - [PoW receipt root](#pow-receipt-root) + - [Operations](#operations) + - [Proposer slashings](#proposer-slashings-1) + - [Casper slashings](#casper-slashings-1) + - [Attestations](#attestations-1) + - [Deposits](#deposits-1) + - [Exits](#exits-1) + - [Ejections](#ejections) - [Per-epoch processing](#per-epoch-processing) - [Helpers](#helpers) - [Receipt roots](#receipt-roots) @@ -685,7 +723,7 @@ The hash function is denoted by `hash`. In Phase 0 the beacon chain is deployed Note: We aim to migrate to a S[T/N]ARK-friendly hash function in a future Ethereum 2.0 deployment phase. #### `is_active_validator` - ```python +```python def is_active_validator(validator: ValidatorRecord) -> bool: """ Checks if ``validator`` is active. @@ -1417,7 +1455,7 @@ For each `exit` in `block.body.exits`: * Run `process_ejections(state)`. - ```python +```python def process_ejections(state: BeaconState) -> None: """ Iterate through the validator registry From ab7549e52ec91539d5dbc5af05c04827e7756eae Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 03:04:10 +0800 Subject: [PATCH 6/8] Move `verify_slashable_vote_data` to the last verification of Casper slashings --- 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 cd63413c0..e69ed9f92 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1375,13 +1375,13 @@ Verify that `len(block.body.casper_slashings) <= MAX_CASPER_SLASHINGS`. For each `casper_slashing` in `block.body.casper_slashings`: -* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_1)`. -* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_2)`. * Verify that `casper_slashing.slashable_vote_data_1.data != casper_slashing.slashable_vote_data_2.data`. * Let `indices(vote) = vote.aggregate_signature_poc_0_indices + vote.aggregate_signature_poc_1_indices`. * Let `intersection = [x for x in indices(casper_slashing.slashable_vote_data_1) if x in indices(casper_slashing.slashable_vote_data_2)]`. * Verify that `len(intersection) >= 1`. * Verify that `casper_slashing.slashable_vote_data_1.data.justified_slot + 1 < casper_slashing.slashable_vote_data_2.data.justified_slot + 1 == casper_slashing.slashable_vote_data_2.data.slot < casper_slashing.slashable_vote_data_1.data.slot` or `casper_slashing.slashable_vote_data_1.data.slot == casper_slashing.slashable_vote_data_2.data.slot`. +* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_1)`. +* Verify that `verify_slashable_vote_data(state, casper_slashing.slashable_vote_data_2)`. * For each [validator](#dfn-validator) index `i` in `intersection`, if `state.validator_registry[i].status` does not equal `EXITED_WITH_PENALTY`, then run `update_validator_status(state, i, new_status=EXITED_WITH_PENALTY)` #### Attestations From 9eeb863ec6c7c29255634275f01b650b31ea0733 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 03:11:53 +0800 Subject: [PATCH 7/8] Refactor `verify_slashable_vote_data` --- specs/core/0_beacon-chain.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index e69ed9f92..edecfd396 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1014,9 +1014,15 @@ def verify_slashable_vote_data(state: BeaconState, vote_data: SlashableVoteData) aggregate_pubkey([state.validators[i].pubkey for i in vote_data.aggregate_signature_poc_0_indices]), aggregate_pubkey([state.validators[i].pubkey for i in vote_data.aggregate_signature_poc_1_indices]) ] + vote_data_root = hash_tree_root(vote_data) + messages = [ + vote_data_root + bytes1(0), + vote_data_root + bytes1(1) + ] return bls_verify_multiple( pubkeys=pubs, - messages=[hash_tree_root(vote_data)+bytes1(0), hash_tree_root(vote_data)+bytes1(1)],signature=vote_data.aggregate_signature, + messages=messages, + signature=vote_data.aggregate_signature, domain=DOMAIN_ATTESTATION, ) ``` From d5a5e1815cafd1ffdb837a1a3a355db6a3185d73 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 13 Dec 2018 13:55:34 +0800 Subject: [PATCH 8/8] Rename `LATEST_BLOCK_ROOT_COUNT` -> `LATEST_BLOCK_ROOTS_LENGTH` --- 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 edecfd396..77ad7d99e 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -160,7 +160,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted | `BEACON_CHAIN_SHARD_NUMBER` | `2**64 - 1` | - | | `BLS_WITHDRAWAL_PREFIX_BYTE` | `0x00` | - | | `MAX_CASPER_VOTES` | `2**10` (= 1,024) | votes | -| `LATEST_BLOCK_ROOT_COUNT` | `2**13` (= 8,192) | block roots | +| `LATEST_BLOCK_ROOTS_LENGTH` | `2**13` (= 8,192) | block roots | * For the safety of crosslinks a minimum committee size of 111 is [recommended](https://vitalik.ca/files/Ithaca201807_Sharding.pdf). (Unbiasable randomness with a Verifiable Delay Function (VDF) will improve committee robustness and lower the safe minimum committee size.) The shuffling algorithm generally ensures (assuming sufficient validators) committee sizes at least `TARGET_COMMITTEE_SIZE // 2`. @@ -1111,7 +1111,7 @@ def on_startup(initial_validator_deposits: List[Deposit], # Recent state latest_crosslinks=[CrosslinkRecord(slot=INITIAL_SLOT_NUMBER, shard_block_root=ZERO_HASH) for _ in range(SHARD_COUNT)], - latest_block_roots=[ZERO_HASH for _ in range(LATEST_BLOCK_ROOT_COUNT)], + latest_block_roots=[ZERO_HASH for _ in range(LATEST_BLOCK_ROOTS_LENGTH)], latest_penalized_exit_balances=[], latest_attestations=[], batched_block_roots=[] @@ -1328,7 +1328,7 @@ Below are the processing steps that happen at every slot. * Let `previous_block_root` be the `tree_hash_root` of the previous beacon block processed in the chain. * Set `state.latest_block_roots = state.latest_block_roots[1:] + [previous_block_root]`. -* If `state.slot % LATEST_BLOCK_ROOT_COUNT == 0` append `merkle_root(state.latest_block_roots)` to `state.batched_block_roots`. +* If `state.slot % LATEST_BLOCK_ROOTS_LENGTH == 0` append `merkle_root(state.latest_block_roots)` to `state.batched_block_roots`. ## Per-block processing