From 6208e74d3f9ff9b975fd625aaf89c31ea88d0838 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 13 Oct 2019 21:52:58 +0900 Subject: [PATCH] get crosslink committees by slot --- configs/minimal.yaml | 2 +- specs/core/0_beacon-chain.md | 31 +++++++++++-------- specs/validator/0_beacon-chain-validator.md | 2 +- .../eth2spec/test/helpers/attestations.py | 3 -- .../pyspec/eth2spec/test/helpers/state.py | 4 +-- .../test_process_attestation.py | 27 ++++++++++++++-- ..._process_justification_and_finalization.py | 2 +- 7 files changed, 48 insertions(+), 23 deletions(-) diff --git a/configs/minimal.yaml b/configs/minimal.yaml index a6040b3a3..1cf35ca90 100644 --- a/configs/minimal.yaml +++ b/configs/minimal.yaml @@ -5,7 +5,7 @@ # --------------------------------------------------------------- # [customized] Just 2 committees for slot for testing purposes -MAX_COMMITTEES_PER_SLOT: 2 +MAX_COMMITTEES_PER_SLOT: 4 # [customized] unsecure, but fast TARGET_COMMITTEE_SIZE: 4 # 2**12 (= 4,096) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 7b6b876de..72cc4edb8 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -858,19 +858,18 @@ def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Hash: return hash(domain_type + int_to_bytes(epoch, length=8) + mix) ``` - -#### `get_committee_count` +#### `get_committees_per_slot` ```python -def get_committee_count(state: BeaconState, epoch: Epoch) -> uint64: +def get_committees_per_slot(state: BeaconState, slot: Slot) -> uint64: """ - Return the number of committees at ``epoch``. + Return the number of committees at ``slot``. """ - committees_per_slot = max(1, min( + epoch = compute_epoch_of_slot(slot) + return max(1, min( MAX_COMMITTEES_PER_SLOT, len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE, )) - return committees_per_slot * SLOTS_PER_EPOCH ``` #### `get_crosslink_committee` @@ -878,20 +877,19 @@ def get_committee_count(state: BeaconState, epoch: Epoch) -> uint64: ```python def get_crosslink_committee(state: BeaconState, slot: Slot, index: uint64) -> Sequence[ValidatorIndex]: """ - Return the crosslink committee at ``epoch`` for ``index``. + Return the crosslink committee at ``slot`` for ``index``. """ epoch = compute_epoch_of_slot(slot) - committees_per_slot = get_committee_count(state, epoch) // SLOTS_PER_EPOCH + committees_per_slot = get_committees_per_slot(state, slot) slot_start_index = get_slot_start_index(state, slot) slot_offset = (index + MAX_COMMITTEES_PER_SLOT - slot_start_index) % MAX_COMMITTEES_PER_SLOT epoch_offset = slot_offset + (slot % SLOTS_PER_EPOCH) * committees_per_slot - print(epoch_offset) return compute_committee( indices=get_active_validator_indices(state, epoch), seed=get_seed(state, epoch, DOMAIN_BEACON_ATTESTER), index=epoch_offset, - count=get_committee_count(state, epoch), + count=committees_per_slot * SLOTS_PER_EPOCH, ) ``` @@ -903,8 +901,9 @@ def get_slot_start_index(state: BeaconState, slot: Slot) -> uint64: Return the start index of the 0th committee at ``slot``. """ epoch = compute_epoch_of_slot(slot) - committees_per_slot = get_committee_count(state, epoch) // SLOTS_PER_EPOCH - slot_start_index = ((slot % SLOTS_PER_EPOCH) * committees_per_slot + get_start_index(state, epoch)) % MAX_COMMITTEES_PER_SLOT + committees_per_slot = get_committees_per_slot(state, slot) + start_index = get_start_index(state, epoch) + slot_start_index = ((slot % SLOTS_PER_EPOCH) * committees_per_slot + start_index) % MAX_COMMITTEES_PER_SLOT return slot_start_index ``` @@ -932,7 +931,7 @@ def get_index_delta(state: BeaconState, epoch: Epoch) -> uint64: """ Return the amount to increase ``state.start_index`` at ``epoch``. """ - return get_committee_count(state, epoch) + return get_committees_per_slot(state, compute_start_slot_of_epoch(epoch)) * SLOTS_PER_EPOCH ``` #### `get_beacon_proposer_index` @@ -1547,6 +1546,12 @@ def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSla def process_attestation(state: BeaconState, attestation: Attestation) -> None: data = attestation.data assert data.index < MAX_COMMITTEES_PER_SLOT + slot_start_index = get_slot_start_index(state, data.slot) + if data.index < slot_start_index: + test_index = data.index + MAX_COMMITTEES_PER_SLOT + else: + test_index = data.index + assert slot_start_index <= test_index < slot_start_index + get_committees_per_slot(state, data.slot) assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state)) assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= data.slot + SLOTS_PER_EPOCH diff --git a/specs/validator/0_beacon-chain-validator.md b/specs/validator/0_beacon-chain-validator.md index 774837ced..b0e64d6c9 100644 --- a/specs/validator/0_beacon-chain-validator.md +++ b/specs/validator/0_beacon-chain-validator.md @@ -150,7 +150,7 @@ def get_committee_assignment(state: BeaconState, start_slot = compute_start_slot_of_epoch(epoch) for slot in range(start_slot, start_slot + SLOTS_PER_EPOCH): slot_start_index = get_slot_start_index(state, Slot(slot)) - for i in range(get_committee_count(state, epoch) // SLOTS_PER_EPOCH): + for i in range(get_committees_per_slot(state, Slot(slot))): index = (slot_start_index + i) % MAX_COMMITTEES_PER_SLOT committee = get_crosslink_committee(state, Slot(slot), index) if validator_index in committee: diff --git a/test_libs/pyspec/eth2spec/test/helpers/attestations.py b/test_libs/pyspec/eth2spec/test/helpers/attestations.py index 49d6b6ad7..879d878ac 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/attestations.py +++ b/test_libs/pyspec/eth2spec/test/helpers/attestations.py @@ -43,9 +43,6 @@ def get_valid_attestation(spec, state, slot=None, index=None, signed=False): slot = state.slot if index is None: index = spec.get_slot_start_index(state, slot) - print(slot) - print(index) - print(spec.get_committee_count(state, spec.compute_epoch_of_slot(slot))) attestation_data = build_attestation_data(spec, state, slot, index) diff --git a/test_libs/pyspec/eth2spec/test/helpers/state.py b/test_libs/pyspec/eth2spec/test/helpers/state.py index 6ae845f69..ffa59fafd 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/state.py +++ b/test_libs/pyspec/eth2spec/test/helpers/state.py @@ -51,8 +51,8 @@ def next_epoch_with_attestations(spec, for _ in range(spec.SLOTS_PER_EPOCH): block = build_empty_block_for_next_slot(spec, post_state) if fill_cur_epoch and post_state.slot >= spec.MIN_ATTESTATION_INCLUSION_DELAY: - committees_per_slot = spec.get_committee_count(state, spec.get_current_epoch(state)) // spec.SLOTS_PER_EPOCH slot_to_attest = post_state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1 + committees_per_slot = spec.get_committees_per_slot(state, slot_to_attest) if slot_to_attest >= spec.compute_start_slot_of_epoch(spec.get_current_epoch(post_state)): slot_start_index = spec.get_slot_start_index(state, slot_to_attest) for i in range(committees_per_slot): @@ -61,8 +61,8 @@ def next_epoch_with_attestations(spec, block.body.attestations.append(cur_attestation) if fill_prev_epoch: - committees_per_slot = spec.get_committee_count(state, spec.get_previous_epoch(state)) // spec.SLOTS_PER_EPOCH slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1 + committees_per_slot = spec.get_committees_per_slot(state, slot_to_attest) slot_start_index = spec.get_slot_start_index(state, slot_to_attest) for i in range(committees_per_slot): index = (slot_start_index + i) % spec.MAX_COMMITTEES_PER_SLOT diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index 87024a21d..229eb85b3 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -124,8 +124,31 @@ def test_old_source_epoch(spec, state): @with_all_phases @spec_state_test -def test_wrong_index(spec, state): - pass +@always_bls +def test_wrong_index_for_committee_signature(spec, state): + attestation = get_valid_attestation(spec, state) + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY + + attestation.data.index += 1 + + yield from run_attestation_processing(spec, state, attestation, False) + + +@with_all_phases +@spec_state_test +@never_bls +def test_wrong_index_for_slot(spec, state): + committees_per_slot = spec.get_committees_per_slot(state, state.slot) + assert committees_per_slot < spec.MAX_COMMITTEES_PER_SLOT + slot_start_index = spec.get_slot_start_index(state, state.slot) + index = slot_start_index + committees_per_slot + + attestation = get_valid_attestation(spec, state) + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY + + attestation.data.index = index + + yield from run_attestation_processing(spec, state, attestation, False) @with_all_phases diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py index abd8f2c17..25d8c083f 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py @@ -26,8 +26,8 @@ def add_mock_attestations(spec, state, epoch, source, target, sufficient_support remaining_balance = total_balance * 2 // 3 start_slot = spec.compute_start_slot_of_epoch(epoch) - committees_per_slot = spec.get_committee_count(state, epoch) // spec.SLOTS_PER_EPOCH for slot in range(start_slot, start_slot + spec.SLOTS_PER_EPOCH): + committees_per_slot = spec.get_committees_per_slot(state, slot) slot_start_index = spec.get_slot_start_index(state, slot) for i in range(committees_per_slot): index = (slot_start_index + i) % spec.MAX_COMMITTEES_PER_SLOT