From 8c34aa8c5f7fd7e1951843feae396ac66021e9db Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Wed, 26 Jun 2019 13:20:04 +0100 Subject: [PATCH 1/9] Initial draft --- specs/core/0_beacon-chain.md | 64 +++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 56a6fd06a..6cf6db0cc 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -30,6 +30,7 @@ - [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit) - [`IndexedAttestation`](#indexedattestation) - [`PendingAttestation`](#pendingattestation) + - [`CompactCommitteees`](#CompactCommitteees) - [`Eth1Data`](#eth1data) - [`HistoricalBatch`](#historicalbatch) - [`DepositData`](#depositdata) @@ -68,7 +69,7 @@ - [`get_block_root_at_slot`](#get_block_root_at_slot) - [`get_block_root`](#get_block_root) - [`get_randao_mix`](#get_randao_mix) - - [`get_active_index_root`](#get_active_index_root) + - [`get_compact_committee_root`](#get_compact_committee_root) - [`generate_seed`](#generate_seed) - [`get_beacon_proposer_index`](#get_beacon_proposer_index) - [`verify_merkle_branch`](#verify_merkle_branch) @@ -187,7 +188,7 @@ The following values are (non-configurable) constants used throughout the specif | - | - | | `SHARD_COUNT` | `2**10` (= 1,024) | | `TARGET_COMMITTEE_SIZE` | `2**7` (= 128) | -| `MAX_INDICES_PER_ATTESTATION` | `2**12` (= 4,096) | +| `MAX_VALIDATORS_PER_COMMITTEE` | `2**12` (= 4,096) | | `MIN_PER_EPOCH_CHURN_LIMIT` | `2**2` (= 4) | | `CHURN_LIMIT_QUOTIENT` | `2**16` (= 65,536) | | `SHUFFLE_ROUND_COUNT` | `90` | @@ -344,8 +345,8 @@ class AttestationDataAndCustodyBit(Container): ```python class IndexedAttestation(Container): - custody_bit_0_indices: List[ValidatorIndex, MAX_INDICES_PER_ATTESTATION] # Indices with custody bit equal to 0 - custody_bit_1_indices: List[ValidatorIndex, MAX_INDICES_PER_ATTESTATION] # Indices with custody bit equal to 1 + custody_bit_0_indices: List[ValidatorIndex, MAX_VALIDATORS_PER_COMMITTEE] # Indices with custody bit equal to 0 + custody_bit_1_indices: List[ValidatorIndex, MAX_VALIDATORS_PER_COMMITTEE] # Indices with custody bit equal to 1 data: AttestationData signature: BLSSignature ``` @@ -354,12 +355,22 @@ class IndexedAttestation(Container): ```python class PendingAttestation(Container): - aggregation_bitfield: Bytes[MAX_INDICES_PER_ATTESTATION // 8] + aggregation_bitfield: Bytes[MAX_VALIDATORS_PER_COMMITTEE // 8] data: AttestationData inclusion_delay: Slot proposer_index: ValidatorIndex ``` +#### `CompactCommitteees` + +```python +class CompactCommitteees(Container): + data: Vector[Container( + pubkeys: List[Bytes48, MAX_VALIDATORS_PER_COMMITTEE] + compact_validators: List[uint64, MAX_VALIDATORS_PER_COMMITTEE] + ), SHARD_COUNT] +``` + #### `Eth1Data` ```python @@ -421,9 +432,9 @@ class AttesterSlashing(Container): ```python class Attestation(Container): - aggregation_bitfield: Bytes[MAX_INDICES_PER_ATTESTATION // 8] + aggregation_bitfield: Bytes[MAX_VALIDATORS_PER_COMMITTEE // 8] data: AttestationData - custody_bitfield: Bytes[MAX_INDICES_PER_ATTESTATION // 8] + custody_bitfield: Bytes[MAX_VALIDATORS_PER_COMMITTEE // 8] signature: BLSSignature ``` @@ -511,7 +522,7 @@ class BeaconState(Container): # Shuffling start_shard: Shard randao_mixes: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR] - active_index_roots: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR] # Active registry digests for light clients + compact_committee_roots: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR] # Committee digests for light clients # Slashings slashed_balances: Vector[Gwei, EPOCHS_PER_SLASHED_BALANCES_VECTOR] # Sums of slashed effective balances # Attestations @@ -742,17 +753,23 @@ def get_randao_mix(state: BeaconState, return state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] ``` -### `get_active_index_root` +### `get_compact_committee_root` ```python -def get_active_index_root(state: BeaconState, - epoch: Epoch) -> Hash: +def get_compact_committee_root(state: BeaconState, epoch: Epoch) -> Hash: """ - Return the index root at a recent ``epoch``. - ``epoch`` expected to be between - (current_epoch - EPOCHS_PER_HISTORICAL_VECTOR + ACTIVATION_EXIT_DELAY, current_epoch + ACTIVATION_EXIT_DELAY]. + Return the compact committee root for the current epoch. """ - return state.active_index_roots[epoch % EPOCHS_PER_HISTORICAL_VECTOR] + committee_data = CompactCommitteees().data + for committee_number in range(get_epoch_committee_count(state, epoch)): + shard = (get_epoch_start_shard(state, epoch) + committee_number) % SHARD_COUNT + for index in get_crosslink_committee(state, epoch, shard): + validator = validators[index] + committee_data[shard].pubkeys.append(validator.pubkey) + # `index` (top 7 bytes) + `slashed` (8th bit) + `effective_balance` (bottom 7 bits) + compact_validator = index << 8 + validator.slashed << 7 + validator.effective_balance // GWEI_PER_ETH + committee_data[shard].compact_validators.append(compact_validator) + return hash_tree_root(committee_data) ``` ### `generate_seed` @@ -765,7 +782,7 @@ def generate_seed(state: BeaconState, """ return hash( get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) + - get_active_index_root(state, epoch) + + get_compact_committee_root(state, epoch) + int_to_bytes(epoch, length=32) ) ``` @@ -973,7 +990,7 @@ def validate_indexed_attestation(state: BeaconState, indexed_attestation: Indexe # Verify no index has custody bit equal to 1 [to be removed in phase 1] assert len(bit_1_indices) == 0 # Verify max number of indices - assert len(bit_0_indices) + len(bit_1_indices) <= MAX_INDICES_PER_ATTESTATION + assert len(bit_0_indices) + len(bit_1_indices) <= MAX_VALIDATORS_PER_COMMITTEE # Verify index sets are disjoint assert len(set(bit_0_indices).intersection(bit_1_indices)) == 0 # Verify indices are sorted @@ -1173,12 +1190,9 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - # Populate active_index_roots - genesis_active_index_root = hash_tree_root( - List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, GENESIS_EPOCH)) - ) + # Populate compact_committee_roots for index in range(EPOCHS_PER_HISTORICAL_VECTOR): - state.active_index_roots[index] = genesis_active_index_root + state.compact_committee_roots[index] = get_compact_committee_root(state, GENESIS_EPOCH) return state ``` @@ -1532,11 +1546,7 @@ def process_final_updates(state: BeaconState) -> None: state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT) # Set active index root index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % EPOCHS_PER_HISTORICAL_VECTOR - state.active_index_roots[index_root_position] = hash_tree_root( - List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT]( - get_active_validator_indices(state, Epoch(next_epoch + ACTIVATION_EXIT_DELAY)) - ) - ) + state.compact_committee_roots[index_root_position] = get_compact_committee_root(state, next_epoch + ACTIVATION_EXIT_DELAY) # Set total slashed balances state.slashed_balances[next_epoch % EPOCHS_PER_SLASHED_BALANCES_VECTOR] = ( state.slashed_balances[current_epoch % EPOCHS_PER_SLASHED_BALANCES_VECTOR] From bcfe383e2555ee14261c995044ee3cf503432297 Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Thu, 27 Jun 2019 08:44:44 +0100 Subject: [PATCH 2/9] WIP --- configs/constant_presets/mainnet.yaml | 2 +- configs/constant_presets/minimal.yaml | 2 +- specs/core/0_beacon-chain.md | 37 +++++++++++-------- specs/light_client/sync_protocol.md | 4 +- .../pyspec/eth2spec/test/helpers/genesis.py | 4 +- 5 files changed, 27 insertions(+), 22 deletions(-) diff --git a/configs/constant_presets/mainnet.yaml b/configs/constant_presets/mainnet.yaml index 9f7ca950f..2aa45cde3 100644 --- a/configs/constant_presets/mainnet.yaml +++ b/configs/constant_presets/mainnet.yaml @@ -10,7 +10,7 @@ SHARD_COUNT: 1024 # 2**7 (= 128) TARGET_COMMITTEE_SIZE: 128 # 2**12 (= 4,096) -MAX_INDICES_PER_ATTESTATION: 4096 +MAX_VALIDATORS_PER_COMMITTEE: 4096 # 2**2 (= 4) MIN_PER_EPOCH_CHURN_LIMIT: 4 # 2**16 (= 65,536) diff --git a/configs/constant_presets/minimal.yaml b/configs/constant_presets/minimal.yaml index 3e3f7ccb4..417f11c94 100644 --- a/configs/constant_presets/minimal.yaml +++ b/configs/constant_presets/minimal.yaml @@ -9,7 +9,7 @@ SHARD_COUNT: 8 # [customized] unsecure, but fast TARGET_COMMITTEE_SIZE: 4 # 2**12 (= 4,096) -MAX_INDICES_PER_ATTESTATION: 4096 +MAX_VALIDATORS_PER_COMMITTEE: 4096 # 2**2 (= 4) MIN_PER_EPOCH_CHURN_LIMIT: 4 # 2**16 (= 65,536) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 6cf6db0cc..a7d47e108 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -30,7 +30,7 @@ - [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit) - [`IndexedAttestation`](#indexedattestation) - [`PendingAttestation`](#pendingattestation) - - [`CompactCommitteees`](#CompactCommitteees) + - [`CompactCommittees`](#CompactCommittees) - [`Eth1Data`](#eth1data) - [`HistoricalBatch`](#historicalbatch) - [`DepositData`](#depositdata) @@ -69,7 +69,7 @@ - [`get_block_root_at_slot`](#get_block_root_at_slot) - [`get_block_root`](#get_block_root) - [`get_randao_mix`](#get_randao_mix) - - [`get_compact_committee_root`](#get_compact_committee_root) + - [`get_compact_committees_root`](#get_compact_committees_root) - [`generate_seed`](#generate_seed) - [`get_beacon_proposer_index`](#get_beacon_proposer_index) - [`verify_merkle_branch`](#verify_merkle_branch) @@ -361,14 +361,19 @@ class PendingAttestation(Container): proposer_index: ValidatorIndex ``` -#### `CompactCommitteees` +#### `CompactCommittee` ```python -class CompactCommitteees(Container): - data: Vector[Container( - pubkeys: List[Bytes48, MAX_VALIDATORS_PER_COMMITTEE] - compact_validators: List[uint64, MAX_VALIDATORS_PER_COMMITTEE] - ), SHARD_COUNT] +class CompactCommittee(Container): + pubkeys: List[Bytes48, MAX_VALIDATORS_PER_COMMITTEE] + compact_validators: List[uint64, MAX_VALIDATORS_PER_COMMITTEE] +``` + +#### `CompactCommittees` + +```python +class CompactCommittees(Container): + data: Vector[CompactCommittee, SHARD_COUNT] ``` #### `Eth1Data` @@ -522,7 +527,7 @@ class BeaconState(Container): # Shuffling start_shard: Shard randao_mixes: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR] - compact_committee_roots: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR] # Committee digests for light clients + compact_committees_roots: Vector[Hash, EPOCHS_PER_HISTORICAL_VECTOR] # Committee digests for light clients # Slashings slashed_balances: Vector[Gwei, EPOCHS_PER_SLASHED_BALANCES_VECTOR] # Sums of slashed effective balances # Attestations @@ -753,14 +758,14 @@ def get_randao_mix(state: BeaconState, return state.randao_mixes[epoch % EPOCHS_PER_HISTORICAL_VECTOR] ``` -### `get_compact_committee_root` +### `get_compact_committees_root` ```python -def get_compact_committee_root(state: BeaconState, epoch: Epoch) -> Hash: +def get_compact_committees_root(state: BeaconState, epoch: Epoch) -> Hash: """ Return the compact committee root for the current epoch. """ - committee_data = CompactCommitteees().data + committee_data = CompactCommittees().data for committee_number in range(get_epoch_committee_count(state, epoch)): shard = (get_epoch_start_shard(state, epoch) + committee_number) % SHARD_COUNT for index in get_crosslink_committee(state, epoch, shard): @@ -782,7 +787,7 @@ def generate_seed(state: BeaconState, """ return hash( get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) + - get_compact_committee_root(state, epoch) + + get_compact_committees_root(state, epoch) + int_to_bytes(epoch, length=32) ) ``` @@ -1190,9 +1195,9 @@ def get_genesis_beacon_state(deposits: Sequence[Deposit], genesis_time: int, eth validator.activation_eligibility_epoch = GENESIS_EPOCH validator.activation_epoch = GENESIS_EPOCH - # Populate compact_committee_roots + # Populate compact_committees_roots for index in range(EPOCHS_PER_HISTORICAL_VECTOR): - state.compact_committee_roots[index] = get_compact_committee_root(state, GENESIS_EPOCH) + state.compact_committees_roots[index] = get_compact_committees_root(state, GENESIS_EPOCH) return state ``` @@ -1546,7 +1551,7 @@ def process_final_updates(state: BeaconState) -> None: state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT) # Set active index root index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % EPOCHS_PER_HISTORICAL_VECTOR - state.compact_committee_roots[index_root_position] = get_compact_committee_root(state, next_epoch + ACTIVATION_EXIT_DELAY) + state.compact_committees_roots[index_root_position] = get_compact_committees_root(state, next_epoch + ACTIVATION_EXIT_DELAY) # Set total slashed balances state.slashed_balances[next_epoch % EPOCHS_PER_SLASHED_BALANCES_VECTOR] = ( state.slashed_balances[current_epoch % EPOCHS_PER_SLASHED_BALANCES_VECTOR] diff --git a/specs/light_client/sync_protocol.md b/specs/light_client/sync_protocol.md index 045bf5608..a29ed05c8 100644 --- a/specs/light_client/sync_protocol.md +++ b/specs/light_client/sync_protocol.md @@ -31,7 +31,7 @@ We define an "expansion" of an object as an object where a field in an object th We define two expansions: -* `ExtendedBeaconState`, which is identical to a `BeaconState` except `active_index_roots: List[Bytes32]` is replaced by `active_indices: List[List[ValidatorIndex]]`, where `BeaconState.active_index_roots[i] = hash_tree_root(ExtendedBeaconState.active_indices[i])`. +* `ExtendedBeaconState`, which is identical to a `BeaconState` except `compact_committees_roots: List[Bytes32]` is replaced by `active_indices: List[List[ValidatorIndex]]`, where `BeaconState.compact_committees_roots[i] = hash_tree_root(ExtendedBeaconState.active_indices[i])`. * `ExtendedBeaconBlock`, which is identical to a `BeaconBlock` except `state_root` is replaced with the corresponding `state: ExtendedBeaconState`. ### `get_active_validator_indices` @@ -40,7 +40,7 @@ Note that there is now a new way to compute `get_active_validator_indices`: ```python def get_active_validator_indices(state: ExtendedBeaconState, epoch: Epoch) -> List[ValidatorIndex]: - return state.active_indices[epoch % ACTIVE_INDEX_ROOTS_LENGTH] + return state.active_indices[epoch % compact_committees_rootS_LENGTH] ``` Note that it takes `state` instead of `state.validators` as an argument. This does not affect its use in `get_shuffled_committee`, because `get_shuffled_committee` has access to the full `state` as one of its arguments. diff --git a/test_libs/pyspec/eth2spec/test/helpers/genesis.py b/test_libs/pyspec/eth2spec/test/helpers/genesis.py index ce0be19bb..c793254c8 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/genesis.py +++ b/test_libs/pyspec/eth2spec/test/helpers/genesis.py @@ -41,9 +41,9 @@ def create_genesis_state(spec, num_validators): validator.activation_eligibility_epoch = spec.GENESIS_EPOCH validator.activation_epoch = spec.GENESIS_EPOCH - genesis_active_index_root = hash_tree_root(List[spec.ValidatorIndex, spec.VALIDATOR_REGISTRY_LIMIT]( + genesis_compact_committees_root = hash_tree_root(List[spec.ValidatorIndex, spec.VALIDATOR_REGISTRY_LIMIT]( spec.get_active_validator_indices(state, spec.GENESIS_EPOCH))) for index in range(spec.EPOCHS_PER_HISTORICAL_VECTOR): - state.active_index_roots[index] = genesis_active_index_root + state.compact_committees_roots[index] = genesis_compact_committees_root return state From 853f5fc3f0a8ff671ec9bf946d5cf2a84e1c4f9e Mon Sep 17 00:00:00 2001 From: Justin Drake Date: Thu, 27 Jun 2019 19:05:27 +0100 Subject: [PATCH 3/9] Apply Danny's suggestions --- specs/core/0_beacon-chain.md | 45 ++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index a7d47e108..ba2cf771b 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -30,10 +30,10 @@ - [`AttestationDataAndCustodyBit`](#attestationdataandcustodybit) - [`IndexedAttestation`](#indexedattestation) - [`PendingAttestation`](#pendingattestation) - - [`CompactCommittees`](#CompactCommittees) - [`Eth1Data`](#eth1data) - [`HistoricalBatch`](#historicalbatch) - [`DepositData`](#depositdata) + - [`CompactCommittee`](#compactcommittee) - [`BeaconBlockHeader`](#beaconblockheader) - [Beacon operations](#beacon-operations) - [`ProposerSlashing`](#proposerslashing) @@ -361,21 +361,6 @@ class PendingAttestation(Container): proposer_index: ValidatorIndex ``` -#### `CompactCommittee` - -```python -class CompactCommittee(Container): - pubkeys: List[Bytes48, MAX_VALIDATORS_PER_COMMITTEE] - compact_validators: List[uint64, MAX_VALIDATORS_PER_COMMITTEE] -``` - -#### `CompactCommittees` - -```python -class CompactCommittees(Container): - data: Vector[CompactCommittee, SHARD_COUNT] -``` - #### `Eth1Data` ```python @@ -403,6 +388,14 @@ class DepositData(Container): signature: BLSSignature ``` +#### `CompactCommittee` + +```python +class CompactCommittee(Container): + pubkeys: List[Bytes48, MAX_VALIDATORS_PER_COMMITTEE] + compact_validators: List[uint64, MAX_VALIDATORS_PER_COMMITTEE] +``` + #### `BeaconBlockHeader` ```python @@ -765,16 +758,18 @@ def get_compact_committees_root(state: BeaconState, epoch: Epoch) -> Hash: """ Return the compact committee root for the current epoch. """ - committee_data = CompactCommittees().data + committees = Vector[CompactCommittee, SHARD_COUNT]() + start_shard = get_epoch_start_shard(state, epoch) for committee_number in range(get_epoch_committee_count(state, epoch)): - shard = (get_epoch_start_shard(state, epoch) + committee_number) % SHARD_COUNT + shard = (start_shard + committee_number) % SHARD_COUNT for index in get_crosslink_committee(state, epoch, shard): - validator = validators[index] - committee_data[shard].pubkeys.append(validator.pubkey) - # `index` (top 7 bytes) + `slashed` (8th bit) + `effective_balance` (bottom 7 bits) - compact_validator = index << 8 + validator.slashed << 7 + validator.effective_balance // GWEI_PER_ETH - committee_data[shard].compact_validators.append(compact_validator) - return hash_tree_root(committee_data) + validator = state.validators[index] + committees[shard].pubkeys.append(validator.pubkey) + compact_balance = validator.effective_balance // EFFECTIVE_BALANCE_INCREMENT + # `index` (top 6 bytes) + `slashed` (16th bit) + `compact_balance` (bottom 15 bits) + compact_validator = uint64(index << 16 + validator.slashed << 15 + compact_balance) + committees[shard].compact_validators.append(compact_validator) + return hash_tree_root(committees) ``` ### `generate_seed` @@ -787,7 +782,7 @@ def generate_seed(state: BeaconState, """ return hash( get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) + - get_compact_committees_root(state, epoch) + + state.compact_committees_roots[epoch] + int_to_bytes(epoch, length=32) ) ``` From 990cc55db74628c045ba9919a65c2d9f5d8d0692 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 27 Jun 2019 16:32:10 -0600 Subject: [PATCH 4/9] fix committee typing error --- motes.md | 42 ++++++++++++++++++++++++++++++++++++ notes.txt | 1 + specs/core/0_beacon-chain.md | 4 ++-- 3 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 motes.md create mode 100644 notes.txt diff --git a/motes.md b/motes.md new file mode 100644 index 000000000..e01ba19b7 --- /dev/null +++ b/motes.md @@ -0,0 +1,42 @@ +* `BLS_WITHDRAWAL_PREFIX` + * Why int rather than bytes? +* `MIN_SEED_LOOKAHEAD` + * Is this actually tunable? + * If so, what are the reprecussions? +* `ACTIVATION_EXIT_DELAY` + * Reaquaint with purpose +* AttesterSlashings + * `MAX_ATTESTER_SLASHINGS` is 1. + * Are there scenarios in which validators can create more effective slashable + messages than can be included on chain? For example, Validators split up to + create double attestations for checkpoints but different (junk) crosslink + data to prevent them from being aggregatable to the fullest + * Max is for block size, no? +* Signature domains + * Max 4byte ints +* `Version` not defined in one of the lists of custom types (2!!). ensure in spec +* `PendingAttestation` + * Don't think `proposer_index` is actually necessary here because effective + balance is stable until end of epoch so can do dynamic lookups +* is_genesis_trigger + * only run at ends of blocks to preserve invariant that eth1data.deposit_root + is the deposit root at the _end_ of an eth1 block +* `Attestation` + * why bitfields not together? +* `Transfer` + * replay mechanism... say the slot gets missed and you sign another transfer + * in a fork you could include both transfers +* `get_previous_epoch` + * do a once over on the genesis stuff +* `get_epoch_start_shard` + * checking next hinges upon the fact that the validator set for the next + epoch is 100% known at the current epoch. Ensure this is the case +* `get_block_root_at_slot` .. `generate_seed` can be bade into one line + function signatures +* `get_shuffled_index` + * I think it should be maybe `assert index_count <= VALIDATOR_REGISTRY_LIMIT` + * is the `2**40` special for security of alg? probably. + + +pubkey/privkey g1 vs g2 + diff --git a/notes.txt b/notes.txt new file mode 100644 index 000000000..421ad7750 --- /dev/null +++ b/notes.txt @@ -0,0 +1 @@ +* `BLS_WITHDRAWAL_PREFIX` -- diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index ba2cf771b..842b16b98 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -758,7 +758,7 @@ def get_compact_committees_root(state: BeaconState, epoch: Epoch) -> Hash: """ Return the compact committee root for the current epoch. """ - committees = Vector[CompactCommittee, SHARD_COUNT]() + committees = [CompactCommittee() for _ in range(SHARD_COUNT)] start_shard = get_epoch_start_shard(state, epoch) for committee_number in range(get_epoch_committee_count(state, epoch)): shard = (start_shard + committee_number) % SHARD_COUNT @@ -769,7 +769,7 @@ def get_compact_committees_root(state: BeaconState, epoch: Epoch) -> Hash: # `index` (top 6 bytes) + `slashed` (16th bit) + `compact_balance` (bottom 15 bits) compact_validator = uint64(index << 16 + validator.slashed << 15 + compact_balance) committees[shard].compact_validators.append(compact_validator) - return hash_tree_root(committees) + return hash_tree_root(Vector[CompactCommittee, SHARD_COUNT](committees)) ``` ### `generate_seed` From 5a8f3e495a8be99d6f6ae821c141e1b881d44d92 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 28 Jun 2019 11:10:17 -0600 Subject: [PATCH 5/9] set committees root for next epoch rather tahn ACTIVaTION_EXIT_DELAY in the future --- specs/core/0_beacon-chain.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 842b16b98..8f55addbc 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -698,6 +698,9 @@ def get_shard_delta(state: BeaconState, epoch: Epoch) -> int: ```python def get_epoch_start_shard(state: BeaconState, epoch: Epoch) -> Shard: + """ + Return the start shard of the 0th committee in an epoch. + """ assert epoch <= get_current_epoch(state) + 1 check_epoch = Epoch(get_current_epoch(state) + 1) shard = Shard((state.start_shard + get_shard_delta(state, get_current_epoch(state))) % SHARD_COUNT) @@ -767,7 +770,7 @@ def get_compact_committees_root(state: BeaconState, epoch: Epoch) -> Hash: committees[shard].pubkeys.append(validator.pubkey) compact_balance = validator.effective_balance // EFFECTIVE_BALANCE_INCREMENT # `index` (top 6 bytes) + `slashed` (16th bit) + `compact_balance` (bottom 15 bits) - compact_validator = uint64(index << 16 + validator.slashed << 15 + compact_balance) + compact_validator = uint64((index << 16) + (validator.slashed << 15) + compact_balance) committees[shard].compact_validators.append(compact_validator) return hash_tree_root(Vector[CompactCommittee, SHARD_COUNT](committees)) ``` @@ -782,7 +785,7 @@ def generate_seed(state: BeaconState, """ return hash( get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) + - state.compact_committees_roots[epoch] + + state.compact_committees_roots[epoch % EPOCHS_PER_HISTORICAL_VECTOR] + int_to_bytes(epoch, length=32) ) ``` @@ -1546,7 +1549,7 @@ def process_final_updates(state: BeaconState) -> None: state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT) # Set active index root index_root_position = (next_epoch + ACTIVATION_EXIT_DELAY) % EPOCHS_PER_HISTORICAL_VECTOR - state.compact_committees_roots[index_root_position] = get_compact_committees_root(state, next_epoch + ACTIVATION_EXIT_DELAY) + state.compact_committees_roots[index_root_position] = get_compact_committees_root(state, next_epoch) # Set total slashed balances state.slashed_balances[next_epoch % EPOCHS_PER_SLASHED_BALANCES_VECTOR] = ( state.slashed_balances[current_epoch % EPOCHS_PER_SLASHED_BALANCES_VECTOR] From b40e2284a0f601dd6f6ac80f833d4036c244ecfb Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 28 Jun 2019 11:20:24 -0600 Subject: [PATCH 6/9] use active index root for generate seed mix in --- 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 8f55addbc..80977c8f7 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -785,7 +785,7 @@ def generate_seed(state: BeaconState, """ return hash( get_randao_mix(state, Epoch(epoch + EPOCHS_PER_HISTORICAL_VECTOR - MIN_SEED_LOOKAHEAD)) + - state.compact_committees_roots[epoch % EPOCHS_PER_HISTORICAL_VECTOR] + + hash_tree_root(List[ValidatorIndex, VALIDATOR_REGISTRY_LIMIT](get_active_validator_indices(state, epoch))) + int_to_bytes(epoch, length=32) ) ``` From 9993a2879629b7e27f97086ff3d5d70cc3da6a2f Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 28 Jun 2019 11:26:05 -0600 Subject: [PATCH 7/9] lint --- 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 80977c8f7..490ac0c96 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -764,7 +764,7 @@ def get_compact_committees_root(state: BeaconState, epoch: Epoch) -> Hash: committees = [CompactCommittee() for _ in range(SHARD_COUNT)] start_shard = get_epoch_start_shard(state, epoch) for committee_number in range(get_epoch_committee_count(state, epoch)): - shard = (start_shard + committee_number) % SHARD_COUNT + shard = Shard((start_shard + committee_number) % SHARD_COUNT) for index in get_crosslink_committee(state, epoch, shard): validator = state.validators[index] committees[shard].pubkeys.append(validator.pubkey) @@ -1535,7 +1535,7 @@ def process_slashings(state: BeaconState) -> None: ```python def process_final_updates(state: BeaconState) -> None: current_epoch = get_current_epoch(state) - next_epoch = current_epoch + 1 + next_epoch = Shard(current_epoch + 1) # Reset eth1 data votes if (state.slot + 1) % SLOTS_PER_ETH1_VOTING_PERIOD == 0: state.eth1_data_votes = [] From d5c2ecb6f73a3c2ea673332d45739704b6af9b29 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 28 Jun 2019 15:44:26 -0600 Subject: [PATCH 8/9] remove local notes files --- motes.md | 42 ------------------------------------------ notes.txt | 1 - 2 files changed, 43 deletions(-) delete mode 100644 motes.md delete mode 100644 notes.txt diff --git a/motes.md b/motes.md deleted file mode 100644 index e01ba19b7..000000000 --- a/motes.md +++ /dev/null @@ -1,42 +0,0 @@ -* `BLS_WITHDRAWAL_PREFIX` - * Why int rather than bytes? -* `MIN_SEED_LOOKAHEAD` - * Is this actually tunable? - * If so, what are the reprecussions? -* `ACTIVATION_EXIT_DELAY` - * Reaquaint with purpose -* AttesterSlashings - * `MAX_ATTESTER_SLASHINGS` is 1. - * Are there scenarios in which validators can create more effective slashable - messages than can be included on chain? For example, Validators split up to - create double attestations for checkpoints but different (junk) crosslink - data to prevent them from being aggregatable to the fullest - * Max is for block size, no? -* Signature domains - * Max 4byte ints -* `Version` not defined in one of the lists of custom types (2!!). ensure in spec -* `PendingAttestation` - * Don't think `proposer_index` is actually necessary here because effective - balance is stable until end of epoch so can do dynamic lookups -* is_genesis_trigger - * only run at ends of blocks to preserve invariant that eth1data.deposit_root - is the deposit root at the _end_ of an eth1 block -* `Attestation` - * why bitfields not together? -* `Transfer` - * replay mechanism... say the slot gets missed and you sign another transfer - * in a fork you could include both transfers -* `get_previous_epoch` - * do a once over on the genesis stuff -* `get_epoch_start_shard` - * checking next hinges upon the fact that the validator set for the next - epoch is 100% known at the current epoch. Ensure this is the case -* `get_block_root_at_slot` .. `generate_seed` can be bade into one line - function signatures -* `get_shuffled_index` - * I think it should be maybe `assert index_count <= VALIDATOR_REGISTRY_LIMIT` - * is the `2**40` special for security of alg? probably. - - -pubkey/privkey g1 vs g2 - diff --git a/notes.txt b/notes.txt deleted file mode 100644 index 421ad7750..000000000 --- a/notes.txt +++ /dev/null @@ -1 +0,0 @@ -* `BLS_WITHDRAWAL_PREFIX` -- From bc8df3cba3ccef7ce28b202720d6f698971e5126 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sat, 29 Jun 2019 12:04:56 -0500 Subject: [PATCH 9/9] minor typo Co-Authored-By: Alex Stokes --- specs/light_client/sync_protocol.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/light_client/sync_protocol.md b/specs/light_client/sync_protocol.md index a29ed05c8..cb7b6ce10 100644 --- a/specs/light_client/sync_protocol.md +++ b/specs/light_client/sync_protocol.md @@ -40,7 +40,7 @@ Note that there is now a new way to compute `get_active_validator_indices`: ```python def get_active_validator_indices(state: ExtendedBeaconState, epoch: Epoch) -> List[ValidatorIndex]: - return state.active_indices[epoch % compact_committees_rootS_LENGTH] + return state.active_indices[epoch % EPOCHS_PER_HISTORICAL_VECTOR] ``` Note that it takes `state` instead of `state.validators` as an argument. This does not affect its use in `get_shuffled_committee`, because `get_shuffled_committee` has access to the full `state` as one of its arguments.