From 3ee0761d17206d5cd3f97ef72dea14beeb106eb7 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 16 Jun 2020 00:16:39 +0800 Subject: [PATCH 01/23] Add `shard: Shard` field to `AttestationData` --- specs/phase1/beacon-chain.md | 18 ++++++------------ specs/phase1/fork-choice.md | 3 ++- specs/phase1/shard-transition.md | 3 +-- .../test/fork_choice/test_on_attestation.py | 2 +- .../test/fork_choice/test_on_shard_head.py | 2 +- .../eth2spec/test/helpers/attestations.py | 10 ++++++---- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 87de9d34e..582e2e669 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -55,7 +55,6 @@ - [`get_indexed_attestation`](#get_indexed_attestation) - [`get_committee_count_delta`](#get_committee_count_delta) - [`get_start_shard`](#get_start_shard) - - [`get_shard`](#get_shard) - [`get_latest_slot_for_shard`](#get_latest_slot_for_shard) - [`get_offset_slots`](#get_offset_slots) - [Predicates](#predicates) @@ -165,6 +164,8 @@ class AttestationData(Container): # FFG vote source: Checkpoint target: Checkpoint + # Shard vote + shard: Shard # Current-slot shard block root shard_head_root: Root # Shard transition root @@ -624,16 +625,6 @@ def get_start_shard(state: BeaconState, slot: Slot) -> Shard: ) ``` -#### `get_shard` - -```python -def get_shard(state: BeaconState, attestation: Attestation) -> Shard: - """ - Return the shard that the given ``attestation`` is attesting. - """ - return compute_shard_from_committee_index(state, attestation.data.index, attestation.data.slot) -``` - #### `get_latest_slot_for_shard` ```python @@ -833,12 +824,15 @@ def validate_attestation(state: BeaconState, attestation: Attestation) -> None: else: assert attestation.data.source == state.previous_justified_checkpoint + assert attestation.data.shard == compute_shard_from_committee_index( + state, attestation.data.index, attestation.data.slot) + # Type 1: on-time attestations, the custody bits should be non-empty. if attestation.custody_bits_blocks != []: # Ensure on-time attestation assert is_on_time_attestation(state, attestation) # Correct data root count - shard = get_shard(state, attestation) + shard = attestation.data.shard assert len(attestation.custody_bits_blocks) == len(get_offset_slots(state, shard)) # Correct parent block root assert data.beacon_block_root == get_block_root_at_slot(state, compute_previous_slot(state.slot)) diff --git a/specs/phase1/fork-choice.md b/specs/phase1/fork-choice.md index 3f9fbdbfb..b07f33496 100644 --- a/specs/phase1/fork-choice.md +++ b/specs/phase1/fork-choice.md @@ -47,7 +47,8 @@ class LatestMessage(object): def update_latest_messages(store: Store, attesting_indices: Sequence[ValidatorIndex], attestation: Attestation) -> None: target = attestation.data.target beacon_block_root = attestation.data.beacon_block_root - shard = get_shard(store.block_states[beacon_block_root], attestation) + # TODO: separate shard chain vote + shard = attestation.data.shard for i in attesting_indices: if i not in store.latest_messages or target.epoch > store.latest_messages[i].epoch: store.latest_messages[i] = LatestMessage( diff --git a/specs/phase1/shard-transition.md b/specs/phase1/shard-transition.md index c62b059ee..186b4cad0 100644 --- a/specs/phase1/shard-transition.md +++ b/specs/phase1/shard-transition.md @@ -148,8 +148,7 @@ def is_valid_fraud_proof(beacon_state: BeaconState, # 2. Check if the shard state transition result is wrong between # `transition.shard_states[offset_index - 1]` to `transition.shard_states[offset_index]`. if offset_index == 0: - shard = get_shard(beacon_state, attestation) - shard_states = beacon_parent_block.body.shard_transitions[shard].shard_states + shard_states = beacon_parent_block.body.shard_transitions[attestation.data.shard].shard_states shard_state = shard_states[len(shard_states) - 1] else: shard_state = transition.shard_states[offset_index - 1] # Not doing the actual state updates here. diff --git a/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py b/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py index a5334c5c7..1c177a919 100644 --- a/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py +++ b/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py @@ -31,7 +31,7 @@ def run_on_attestation(spec, state, store, attestation, valid=True): latest_message = spec.LatestMessage( epoch=attestation.data.target.epoch, root=attestation.data.beacon_block_root, - shard=spec.get_shard(state, attestation), + shard=attestation.data.shard, shard_root=attestation.data.shard_head_root, ) diff --git a/tests/core/pyspec/eth2spec/test/fork_choice/test_on_shard_head.py b/tests/core/pyspec/eth2spec/test/fork_choice/test_on_shard_head.py index 24eeaedbe..c84f073b2 100644 --- a/tests/core/pyspec/eth2spec/test/fork_choice/test_on_shard_head.py +++ b/tests/core/pyspec/eth2spec/test/fork_choice/test_on_shard_head.py @@ -82,7 +82,7 @@ def apply_shard_and_beacon(spec, state, store, shard_store, shard_blocks_buffer) shard_transition=shard_transition, signed=False, ) - assert spec.get_shard(state, attestation) == shard + assert attestation.data.shard == shard beacon_block.body.attestations = [attestation] beacon_block.body.shard_transitions = shard_transitions diff --git a/tests/core/pyspec/eth2spec/test/helpers/attestations.py b/tests/core/pyspec/eth2spec/test/helpers/attestations.py index 1e0560405..25d55f3a9 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/attestations.py +++ b/tests/core/pyspec/eth2spec/test/helpers/attestations.py @@ -45,7 +45,7 @@ def run_attestation_processing(spec, state, attestation, valid=True): yield 'post', state -def build_attestation_data(spec, state, slot, index, shard_transition=None, on_time=True): +def build_attestation_data(spec, state, slot, index, shard=None, shard_transition=None, on_time=True): assert state.slot >= slot if slot == state.slot: @@ -77,13 +77,15 @@ def build_attestation_data(spec, state, slot, index, shard_transition=None, on_t ) if spec.fork == PHASE1: + if shard is None: + shard = spec.compute_shard_from_committee_index(state, attestation_data.index, attestation_data.slot) + attestation_data.shard = shard + if shard_transition is not None: lastest_shard_data_root_index = len(shard_transition.shard_data_roots) - 1 attestation_data.shard_head_root = shard_transition.shard_data_roots[lastest_shard_data_root_index] attestation_data.shard_transition_root = shard_transition.hash_tree_root() else: - # No shard transition -> no shard block - shard = spec.get_shard(state, spec.Attestation(data=attestation_data)) if on_time: shard_transition = spec.get_shard_transition(state, shard, shard_blocks=[]) lastest_shard_data_root_index = len(shard_transition.shard_data_roots) - 1 @@ -96,7 +98,7 @@ def build_attestation_data(spec, state, slot, index, shard_transition=None, on_t def convert_to_valid_on_time_attestation(spec, state, attestation, signed=False): - shard = spec.get_shard(state, attestation) + shard = spec.compute_shard_from_committee_index(state, attestation.data.index, attestation.data.slot) offset_slots = spec.compute_offset_slots( spec.get_latest_slot_for_shard(state, shard), attestation.data.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY, From ace46c38a729e26db2be4212f2120801c3adc720 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Tue, 16 Jun 2020 15:33:25 -0600 Subject: [PATCH 02/23] revert local config settings from .gitignore --- .gitignore | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.gitignore b/.gitignore index ecbeb9a3c..bcd96f885 100644 --- a/.gitignore +++ b/.gitignore @@ -28,13 +28,3 @@ tests/core/pyspec/test-reports tests/core/pyspec/eth2spec/test_results.xml *.egg-info - -# flake8 config -tox.ini - -# VS code files -.vscode -*.code-workspace - -# npm (for doctoc) -package-lock.json \ No newline at end of file From c8ae7d99f9e4875581ab3f31d88f63ab63a11ab6 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 17 Jun 2020 09:05:44 +0800 Subject: [PATCH 03/23] Fix after auto-merge --- specs/phase1/beacon-chain.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 0b7db5516..ad543a941 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -760,6 +760,9 @@ def validate_attestation(state: BeaconState, attestation: Attestation) -> None: else: assert attestation.data.source == state.previous_justified_checkpoint + assert attestation.data.shard == compute_shard_from_committee_index( + state, attestation.data.index, attestation.data.slot) + # Type 1: on-time attestations if is_on_time_attestation(state, attestation): # Correct parent block root From 23cbbb1d081c07c915e8db56de796e1cb042bb98 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 17 Jun 2020 09:47:39 +0800 Subject: [PATCH 04/23] Fix shard number assertion and refactor it --- specs/phase1/beacon-chain.md | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index ad543a941..f63654182 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -760,13 +760,14 @@ def validate_attestation(state: BeaconState, attestation: Attestation) -> None: else: assert attestation.data.source == state.previous_justified_checkpoint - assert attestation.data.shard == compute_shard_from_committee_index( - state, attestation.data.index, attestation.data.slot) - # Type 1: on-time attestations if is_on_time_attestation(state, attestation): # Correct parent block root assert data.beacon_block_root == get_block_root_at_slot(state, compute_previous_slot(state.slot)) + # Correct shard number + assert attestation.data.shard == compute_shard_from_committee_index( + state, attestation.data.index, attestation.data.slot + ) # Type 2: no shard transition else: # Ensure delayed attestation @@ -868,7 +869,6 @@ def process_crosslink_for_shard(state: BeaconState, on_time_attestation_slot = compute_previous_slot(state.slot) committee = get_beacon_committee(state, on_time_attestation_slot, committee_index) online_indices = get_online_validator_indices(state) - shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot) # Loop over all shard transition roots shard_transition_roots = set([a.data.shard_transition_root for a in attestations]) @@ -894,7 +894,7 @@ def process_crosslink_for_shard(state: BeaconState, assert shard_transition_root == hash_tree_root(shard_transition) # Apply transition - apply_shard_transition(state, shard, shard_transition) + apply_shard_transition(state, attestation.data.shard, shard_transition) # Apply proposer reward and cost beacon_proposer_index = get_beacon_proposer_index(state) estimated_attester_reward = sum([get_base_reward(state, attester) for attester in transition_participants]) @@ -902,11 +902,11 @@ def process_crosslink_for_shard(state: BeaconState, increase_balance(state, beacon_proposer_index, proposer_reward) states_slots_lengths = zip( shard_transition.shard_states, - get_offset_slots(state, shard), + get_offset_slots(state, attestation.data.shard), shard_transition.shard_block_lengths ) for shard_state, slot, length in states_slots_lengths: - proposer_index = get_shard_proposer_index(state, slot, shard) + proposer_index = get_shard_proposer_index(state, slot, attestation.data.shard) decrease_balance(state, proposer_index, shard_state.gasprice * length) # Return winning transition root @@ -931,13 +931,16 @@ def process_crosslinks(state: BeaconState, attestation for attestation in attestations if is_on_time_attestation(state, attestation) and attestation.data.index == committee_index ] - shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot) - winning_root = process_crosslink_for_shard(state, committee_index, shard_transitions[shard], shard_attestations) - if winning_root != Root(): - # Mark relevant pending attestations as creating a successful crosslink - for pending_attestation in state.current_epoch_attestations: - if is_winning_attestation(state, pending_attestation, committee_index, winning_root): - pending_attestation.crosslink_success = True + if len(shard_attestations) > 0: + shard = shard_attestations[0].data.shard + winning_root = process_crosslink_for_shard( + state, committee_index, shard_transitions[shard], shard_attestations + ) + if winning_root != Root(): + # Mark relevant pending attestations as creating a successful crosslink + for pending_attestation in state.current_epoch_attestations: + if is_winning_attestation(state, pending_attestation, committee_index, winning_root): + pending_attestation.crosslink_success = True ``` ###### `verify_empty_shard_transition` From 9b60a9b799496f1a2fc941bf1250b7009483ed1d Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 17 Jun 2020 20:04:40 +0200 Subject: [PATCH 05/23] Avoid state usage in p2p validation, compute committee count per slot for epoch as a whole --- setup.py | 6 +++--- specs/phase0/beacon-chain.md | 13 ++++++------- specs/phase0/p2p-interface.md | 12 ++++++++---- specs/phase0/validator.md | 19 +++++++++++++------ specs/phase1/beacon-chain.md | 7 ++++--- specs/phase1/validator.md | 2 +- .../test/fork_choice/test_get_head.py | 2 +- .../eth2spec/test/helpers/attestations.py | 6 +++--- .../eth2spec/test/helpers/shard_block.py | 2 +- .../test_process_attestation.py | 2 +- ..._process_justification_and_finalization.py | 2 +- .../phase_1/unittests/test_get_start_shard.py | 15 ++++++++++----- .../test/validator/test_validator_unittest.py | 11 +++++------ 13 files changed, 57 insertions(+), 42 deletions(-) diff --git a/setup.py b/setup.py index 6bee87080..cc3b00da9 100644 --- a/setup.py +++ b/setup.py @@ -189,10 +189,10 @@ get_base_reward = cache_this( lambda state, index: (state.validators.hash_tree_root(), state.slot, index), _get_base_reward, lru_size=2048) -_get_committee_count_at_slot = get_committee_count_at_slot -get_committee_count_at_slot = cache_this( +_get_committee_count_per_slot = get_committee_count_per_slot +get_committee_count_per_slot = cache_this( lambda state, epoch: (state.validators.hash_tree_root(), epoch), - _get_committee_count_at_slot, lru_size=SLOTS_PER_EPOCH * 3) + _get_committee_count_per_slot, lru_size=SLOTS_PER_EPOCH * 3) _get_active_validator_indices = get_active_validator_indices get_active_validator_indices = cache_this( diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index 7914dc458..6533dcb7f 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -89,7 +89,7 @@ - [`get_active_validator_indices`](#get_active_validator_indices) - [`get_validator_churn_limit`](#get_validator_churn_limit) - [`get_seed`](#get_seed) - - [`get_committee_count_at_slot`](#get_committee_count_at_slot) + - [`get_committee_count_per_slot`](#get_committee_count_per_slot) - [`get_beacon_committee`](#get_beacon_committee) - [`get_beacon_proposer_index`](#get_beacon_proposer_index) - [`get_total_balance`](#get_total_balance) @@ -948,14 +948,13 @@ def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Bytes return hash(domain_type + int_to_bytes(epoch, length=8) + mix) ``` -#### `get_committee_count_at_slot` +#### `get_committee_count_per_slot` ```python -def get_committee_count_at_slot(state: BeaconState, slot: Slot) -> uint64: +def get_committee_count_per_slot(state: BeaconState, epoch: Epoch) -> uint64: """ - Return the number of committees at ``slot``. + Return the number of committees in each ``slot`` for the given epoch. """ - epoch = compute_epoch_at_slot(slot) return max(1, min( MAX_COMMITTEES_PER_SLOT, len(get_active_validator_indices(state, epoch)) // SLOTS_PER_EPOCH // TARGET_COMMITTEE_SIZE, @@ -970,7 +969,7 @@ def get_beacon_committee(state: BeaconState, slot: Slot, index: CommitteeIndex) Return the beacon committee at ``slot`` for ``index``. """ epoch = compute_epoch_at_slot(slot) - committees_per_slot = get_committee_count_at_slot(state, slot) + committees_per_slot = get_committee_count_per_slot(state, epoch) return compute_committee( indices=get_active_validator_indices(state, epoch), seed=get_seed(state, epoch, DOMAIN_BEACON_ATTESTER), @@ -1720,7 +1719,7 @@ def process_attester_slashing(state: BeaconState, attester_slashing: AttesterSla ```python def process_attestation(state: BeaconState, attestation: Attestation) -> None: data = attestation.data - assert data.index < get_committee_count_at_slot(state, data.slot) + assert data.index < get_committee_count_per_slot(state, data.target.epoch) assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state)) assert data.target.epoch == compute_epoch_at_slot(data.slot) assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= data.slot + SLOTS_PER_EPOCH diff --git a/specs/phase0/p2p-interface.md b/specs/phase0/p2p-interface.md index 6c4cdd2a6..211508f00 100644 --- a/specs/phase0/p2p-interface.md +++ b/specs/phase0/p2p-interface.md @@ -275,18 +275,22 @@ Additional global topics are used to propagate lower frequency validator message Attestation subnets are used to propagate unaggregated attestations to subsections of the network. Their `Name`s are: - `beacon_attestation_{subnet_id}` - These topics are used to propagate unaggregated attestations to the subnet `subnet_id` (typically beacon and persistent committees) to be aggregated before being gossiped to `beacon_aggregate_and_proof`. The following validations MUST pass before forwarding the `attestation` on the subnet. - - _[REJECT]_ The attestation is for the correct subnet (i.e. `compute_subnet_for_attestation(state, attestation.data.slot, attestation.data.index) == subnet_id`). + - _[REJECT]_ The attestation is for the correct subnet -- i.e. `compute_subnet_for_attestation(committees_per_slot, attestation.data.slot, attestation.data.index) == subnet_id`, where `committees_per_slot = get_committee_count_per_slot(state, attestation.data.target.epoch)`, which may be computed along with the committee information for the signature check. - _[IGNORE]_ `attestation.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (within a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= attestation.data.slot` (a client MAY queue future attestations for processing at the appropriate slot). - - _[REJECT]_ The attestation is unaggregated -- that is, it has exactly one participating validator (`len(get_attesting_indices(state, attestation.data, attestation.aggregation_bits)) == 1`). + - _[REJECT]_ The attestation is unaggregated -- that is, it has exactly one participating validator (`len([bit in bit attestation.aggregation_bits if bit]) == 1`, i.e. exactly 1 bit is set). - _[IGNORE]_ There has been no other valid attestation seen on an attestation subnet that has an identical `attestation.data.target.epoch` and participating validator index. - _[REJECT]_ The block being voted for (`attestation.data.beacon_block_root`) passes validation. - _[REJECT]_ The signature of `attestation` is valid. #### Attestations and Aggregation -Attestation broadcasting is grouped into subnets defined by a topic. The number of subnets is defined via `ATTESTATION_SUBNET_COUNT`. The correct subnet for an attestation can be calculated with `compute_subnet_for_attestation`. `beacon_attestation_{subnet_id}` topics, are rotated through throughout the epoch in a similar fashion to rotating through shards in committees in Phase 1. +Attestation broadcasting is grouped into subnets defined by a topic. The number of subnets is defined via `ATTESTATION_SUBNET_COUNT`. +The correct subnet for an attestation can be calculated with `compute_subnet_for_attestation`. +`beacon_attestation_{subnet_id}` topics, are rotated through throughout the epoch in a similar fashion to rotating through shards in committees in Phase 1. +The subnets are rotated through with `committees_per_slot = get_committee_count_per_slot(state, attestation.data.target.epoch)` subnets per slot. + +Unaggregated attestations are sent to the subnet topic, `beacon_attestation_{compute_subnet_for_attestation(committees_per_slot, attestation.data.slot, attestation.data.index)}` as `Attestation`s. -Unaggregated attestations are sent to the subnet topic, `beacon_attestation_{compute_subnet_for_attestation(state, attestation.data.slot, attestation.data.index)}` as `Attestation`s. Aggregated attestations are sent to the `beacon_aggregate_and_proof` topic as `AggregateAndProof`s. diff --git a/specs/phase0/validator.md b/specs/phase0/validator.md index 35c52f346..e325f75f6 100644 --- a/specs/phase0/validator.md +++ b/specs/phase0/validator.md @@ -172,8 +172,9 @@ def get_committee_assignment(state: BeaconState, assert epoch <= next_epoch start_slot = compute_start_slot_at_epoch(epoch) + committee_count_per_slot = get_committee_count_per_slot(state, epoch) for slot in range(start_slot, start_slot + SLOTS_PER_EPOCH): - for index in range(get_committee_count_at_slot(state, Slot(slot))): + for index in range(committee_count_per_slot): committee = get_beacon_committee(state, Slot(slot), CommitteeIndex(index)) if validator_index in committee: return committee, CommitteeIndex(index), Slot(slot) @@ -199,8 +200,10 @@ The beacon chain shufflings are designed to provide a minimum of 1 epoch lookahe Specifically a validator should: * Call `get_committee_assignment(state, next_epoch, validator_index)` when checking for next epoch assignments. -* Find peers of the pubsub topic `beacon_attestation_{compute_subnet_for_attestation(state, slot, committee_index)}`. - * If an _insufficient_ number of current peers are subscribed to the topic, the validator must discover new peers on this topic. Via the discovery protocol, find peers with an ENR containing the `attnets` entry such that `ENR["attnets"][compute_subnet_for_attestation(state, slot, committee_index)] == True`. Then validate that the peers are still persisted on the desired topic by requesting `GetMetaData` and checking the resulting `attnets` field. +* Calculate the committees per slot for the next epoch: `committees_per_slot = get_committee_count_per_slot(state, next_epoch)` +* Calculate the subnet index: `subnet_id = compute_subnet_for_attestation(committees_per_slot, slot, committee_index)` +* Find peers of the pubsub topic `beacon_attestation_{subnet_id}`. + * If an _insufficient_ number of current peers are subscribed to the topic, the validator must discover new peers on this topic. Via the discovery protocol, find peers with an ENR containing the `attnets` entry such that `ENR["attnets"][subnet_id] == True`. Then validate that the peers are still persisted on the desired topic by requesting `GetMetaData` and checking the resulting `attnets` field. * If the validator is assigned to be an aggregator for the slot (see `is_aggregator()`), then subscribe to the topic. *Note*: If the validator is _not_ assigned to be an aggregator, the validator only needs sufficient number of peers on the topic to be able to publish messages. The validator does not need to _subscribe_ and listen to all messages on the topic. @@ -425,16 +428,20 @@ def get_attestation_signature(state: BeaconState, attestation_data: AttestationD #### Broadcast attestation -Finally, the validator broadcasts `attestation` to the associated attestation subnet -- the `beacon_attestation_{compute_subnet_for_attestation(state, attestation.data.slot, attestation.data.committee_index)}` pubsub topic. +Finally, the validator broadcasts `attestation` to the associated attestation subnet, the `beacon_attestation_{subnet_id}` pubsub topic. + +The `subnet_id` for the `attestation` is calculated with: +- Let `committees_per_slot = get_committee_count_per_slot(state, attestation.data.target.epoch)`. +- Let `subnet_id = compute_subnet_for_attestation(committees_per_slot, attestation.data.slot, attestation.data.committee_index)`. ```python -def compute_subnet_for_attestation(state: BeaconState, slot: Slot, committee_index: CommitteeIndex) -> uint64: +def compute_subnet_for_attestation(committees_per_slot: uint64, slot: Slot, committee_index: CommitteeIndex) -> uint64: """ Compute the correct subnet for an attestation for Phase 0. Note, this mimics expected Phase 1 behavior where attestations will be mapped to their shard subnet. """ slots_since_epoch_start = slot % SLOTS_PER_EPOCH - committees_since_epoch_start = get_committee_count_at_slot(state, slot) * slots_since_epoch_start + committees_since_epoch_start = committees_per_slot * slots_since_epoch_start return (committees_since_epoch_start + committee_index) % ATTESTATION_SUBNET_COUNT ``` diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 4e4778abe..472182a45 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -592,7 +592,8 @@ def get_committee_count_delta(state: BeaconState, start_slot: Slot, stop_slot: S """ Return the sum of committee counts in range ``[start_slot, stop_slot)``. """ - return sum(get_committee_count_at_slot(state, Slot(slot)) for slot in range(start_slot, stop_slot)) + return sum(get_committee_count_per_slot(state, compute_epoch_at_slot(Slot(slot))) + for slot in range(start_slot, stop_slot)) ``` #### `get_start_shard` @@ -757,7 +758,7 @@ def process_operations(state: BeaconState, body: BeaconBlockBody) -> None: ```python def validate_attestation(state: BeaconState, attestation: Attestation) -> None: data = attestation.data - assert data.index < get_committee_count_at_slot(state, data.slot) + assert data.index < get_committee_count_per_slot(state, data.target.epoch) assert data.index < get_active_shard_count(state) assert data.target.epoch in (get_previous_epoch(state), get_current_epoch(state)) assert data.target.epoch == compute_epoch_at_slot(data.slot) @@ -935,7 +936,7 @@ def process_crosslinks(state: BeaconState, shard_transitions: Sequence[ShardTransition], attestations: Sequence[Attestation]) -> None: on_time_attestation_slot = compute_previous_slot(state.slot) - committee_count = get_committee_count_at_slot(state, on_time_attestation_slot) + committee_count = get_committee_count_per_slot(state, compute_epoch_at_slot(on_time_attestation_slot)) for committee_index in map(CommitteeIndex, range(committee_count)): # All attestations in the block for this committee/shard and current slot shard_attestations = [ diff --git a/specs/phase1/validator.md b/specs/phase1/validator.md index 558a1b3bf..66445abb8 100644 --- a/specs/phase1/validator.md +++ b/specs/phase1/validator.md @@ -148,7 +148,7 @@ def get_shard_winning_roots(state: BeaconState, shards = [] winning_roots = [] online_indices = get_online_validator_indices(state) - committee_count = get_committee_count_at_slot(state, state.slot) + committee_count = get_committee_count_per_slot(state, get_current_epoch(state)) for committee_index in map(CommitteeIndex, range(committee_count)): shard = compute_shard_from_committee_index(state, committee_index, state.slot) # All attestations in the block for this committee/shard and are "on time" diff --git a/tests/core/pyspec/eth2spec/test/fork_choice/test_get_head.py b/tests/core/pyspec/eth2spec/test/fork_choice/test_get_head.py index f9a739804..859fc797f 100644 --- a/tests/core/pyspec/eth2spec/test/fork_choice/test_get_head.py +++ b/tests/core/pyspec/eth2spec/test/fork_choice/test_get_head.py @@ -154,7 +154,7 @@ def test_filtered_block_tree(spec, state): attestations = [] for i in range(spec.SLOTS_PER_EPOCH): slot = rogue_block.slot + i - for index in range(spec.get_committee_count_at_slot(non_viable_state, slot)): + for index in range(spec.get_committee_count_per_slot(non_viable_state, spec.compute_epoch_at_slot(slot))): attestation = get_valid_attestation(spec, non_viable_state, slot, index, signed=True) attestations.append(attestation) diff --git a/tests/core/pyspec/eth2spec/test/helpers/attestations.py b/tests/core/pyspec/eth2spec/test/helpers/attestations.py index 23eba34da..5016ac5df 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/attestations.py +++ b/tests/core/pyspec/eth2spec/test/helpers/attestations.py @@ -257,7 +257,7 @@ def next_epoch_with_attestations(spec, block = build_empty_block_for_next_slot(spec, post_state) if fill_cur_epoch and post_state.slot >= spec.MIN_ATTESTATION_INCLUSION_DELAY: slot_to_attest = post_state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1 - committees_per_slot = spec.get_committee_count_at_slot(state, slot_to_attest) + committees_per_slot = spec.get_committee_count_per_slot(state, spec.compute_epoch_at_slot(slot_to_attest)) if slot_to_attest >= spec.compute_start_slot_at_epoch(spec.get_current_epoch(post_state)): for index in range(committees_per_slot): if spec.fork == PHASE1: @@ -275,7 +275,7 @@ def next_epoch_with_attestations(spec, if fill_prev_epoch: slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1 - committees_per_slot = spec.get_committee_count_at_slot(state, slot_to_attest) + committees_per_slot = spec.get_committee_count_per_slot(state, spec.compute_epoch_at_slot(slot_to_attest)) for index in range(committees_per_slot): prev_attestation = get_valid_attestation( spec, post_state, slot_to_attest, index=index, signed=True, on_time=False) @@ -304,7 +304,7 @@ def prepare_state_with_attestations(spec, state, participation_fn=None): for _ in range(spec.SLOTS_PER_EPOCH + spec.MIN_ATTESTATION_INCLUSION_DELAY): # create an attestation for each index in each slot in epoch if state.slot < next_epoch_start_slot: - for committee_index in range(spec.get_committee_count_at_slot(state, state.slot)): + for committee_index in range(spec.get_committee_count_per_slot(state, spec.get_current_epoch(state))): def temp_participants_filter(comm): if participation_fn is None: return comm diff --git a/tests/core/pyspec/eth2spec/test/helpers/shard_block.py b/tests/core/pyspec/eth2spec/test/helpers/shard_block.py index ddf66f6c2..6957f2283 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/shard_block.py +++ b/tests/core/pyspec/eth2spec/test/helpers/shard_block.py @@ -75,7 +75,7 @@ def get_shard_transitions(spec, parent_beacon_state, shard_blocks): def get_committee_index_of_shard(spec, state, slot, shard): # Optional[CommitteeIndex] active_shard_count = spec.get_active_shard_count(state) - committee_count = spec.get_committee_count_at_slot(state, slot) + committee_count = spec.get_committee_count_per_slot(state, spec.compute_epoch_at_slot(slot)) start_shard = spec.get_start_shard(state, slot) for committee_index in range(committee_count): if (start_shard + committee_index) % active_shard_count == shard: diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index 5de8913d6..28fd9ac9e 100644 --- a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -139,7 +139,7 @@ def test_wrong_index_for_committee_signature(spec, state): @spec_state_test @never_bls def test_wrong_index_for_slot(spec, state): - while spec.get_committee_count_at_slot(state, state.slot) >= spec.MAX_COMMITTEES_PER_SLOT: + while spec.get_committee_count_per_slot(state, spec.get_current_epoch(state)) >= spec.MAX_COMMITTEES_PER_SLOT: state.validators = state.validators[:len(state.validators) // 2] state.balances = state.balances[:len(state.balances) // 2] diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py b/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py index 09af2126d..73091a1c7 100644 --- a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py +++ b/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py @@ -27,8 +27,8 @@ def add_mock_attestations(spec, state, epoch, source, target, sufficient_support remaining_balance = int(total_balance * 2 // 3) # can become negative start_slot = spec.compute_start_slot_at_epoch(epoch) + committees_per_slot = spec.get_committee_count_per_slot(state, epoch) for slot in range(start_slot, start_slot + spec.SLOTS_PER_EPOCH): - committees_per_slot = spec.get_committee_count_at_slot(state, slot) for index in range(committees_per_slot): # Check if we already have had sufficient balance. (and undone if we don't want it). # If so, do not create more attestations. (we do not have empty pending attestations normally anyway) diff --git a/tests/core/pyspec/eth2spec/test/phase_1/unittests/test_get_start_shard.py b/tests/core/pyspec/eth2spec/test/phase_1/unittests/test_get_start_shard.py index 27afd4a4e..c443545b9 100644 --- a/tests/core/pyspec/eth2spec/test/phase_1/unittests/test_get_start_shard.py +++ b/tests/core/pyspec/eth2spec/test/phase_1/unittests/test_get_start_shard.py @@ -10,11 +10,16 @@ from eth2spec.test.helpers.state import next_epoch @spec_state_test def test_get_committee_count_delta(spec, state): assert spec.get_committee_count_delta(state, 0, 0) == 0 - assert spec.get_committee_count_at_slot(state, 0) != 0 - assert spec.get_committee_count_delta(state, 0, 1) == spec.get_committee_count_at_slot(state, 0) - assert spec.get_committee_count_delta(state, 1, 2) == spec.get_committee_count_at_slot(state, 1) - assert spec.get_committee_count_delta(state, 0, 2) == ( - spec.get_committee_count_at_slot(state, 0) + spec.get_committee_count_at_slot(state, 1) + assert spec.get_committee_count_per_slot(state, 0) != 0 + assert spec.get_committee_count_delta(state, 0, 1) == spec.get_committee_count_per_slot(state, 0) + assert spec.get_committee_count_delta(state, 1, 2) == spec.get_committee_count_per_slot(state, 0) + assert spec.get_committee_count_delta(state, 0, 2) == spec.get_committee_count_per_slot(state, 0) * 2 + assert spec.get_committee_count_delta(state, 0, spec.SLOTS_PER_EPOCH) == ( + spec.get_committee_count_per_slot(state, 0) * spec.SLOTS_PER_EPOCH + ) + assert spec.get_committee_count_delta(state, 0, 2 * spec.SLOTS_PER_EPOCH) == ( + spec.get_committee_count_per_slot(state, 0) * spec.SLOTS_PER_EPOCH + + spec.get_committee_count_per_slot(state, 1) * spec.SLOTS_PER_EPOCH ) diff --git a/tests/core/pyspec/eth2spec/test/validator/test_validator_unittest.py b/tests/core/pyspec/eth2spec/test/validator/test_validator_unittest.py index e749b1e3d..84c4b9fe5 100644 --- a/tests/core/pyspec/eth2spec/test/validator/test_validator_unittest.py +++ b/tests/core/pyspec/eth2spec/test/validator/test_validator_unittest.py @@ -26,7 +26,7 @@ def run_get_committee_assignment(spec, state, epoch, validator_index, valid=True committee, committee_index, slot = assignment assert spec.compute_epoch_at_slot(slot) == epoch assert committee == spec.get_beacon_committee(state, slot, committee_index) - assert committee_index < spec.get_committee_count_at_slot(state, slot) + assert committee_index < spec.get_committee_count_per_slot(state, epoch) assert validator_index in committee assert valid except AssertionError: @@ -359,13 +359,12 @@ def test_get_attestation_signature_phase0(spec, state): def test_compute_subnet_for_attestation(spec, state): for committee_idx in range(spec.MAX_COMMITTEES_PER_SLOT): for slot in range(state.slot, state.slot + spec.SLOTS_PER_EPOCH): - actual_subnet_id = spec.compute_subnet_for_attestation(state, slot, committee_idx) + committees_per_slot = spec.get_committee_count_per_slot(state, spec.compute_epoch_at_slot(slot)) + actual_subnet_id = spec.compute_subnet_for_attestation(committees_per_slot, slot, committee_idx) slots_since_epoch_start = slot % spec.SLOTS_PER_EPOCH - committees_since_epoch_start = spec.get_committee_count_at_slot( - state, slot) * slots_since_epoch_start - expected_subnet_id = (committees_since_epoch_start + - committee_idx) % spec.ATTESTATION_SUBNET_COUNT + committees_since_epoch_start = committees_per_slot * slots_since_epoch_start + expected_subnet_id = (committees_since_epoch_start + committee_idx) % spec.ATTESTATION_SUBNET_COUNT assert actual_subnet_id == expected_subnet_id From ce0371a66b408c86af5305527a9bd2bd253899e0 Mon Sep 17 00:00:00 2001 From: protolambda Date: Wed, 17 Jun 2020 20:23:26 +0200 Subject: [PATCH 06/23] fix comment: committees per slot for given *epoch* --- specs/phase0/beacon-chain.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index 6533dcb7f..cd52762d5 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -953,7 +953,7 @@ def get_seed(state: BeaconState, epoch: Epoch, domain_type: DomainType) -> Bytes ```python def get_committee_count_per_slot(state: BeaconState, epoch: Epoch) -> uint64: """ - Return the number of committees in each ``slot`` for the given epoch. + Return the number of committees in each slot for the given ``epoch``. """ return max(1, min( MAX_COMMITTEES_PER_SLOT, From 3eabcddb4caa540abaf7c8721cb76b1f64918dde Mon Sep 17 00:00:00 2001 From: terence tsao Date: Wed, 17 Jun 2020 13:24:00 -0700 Subject: [PATCH 07/23] Update validator.md --- specs/phase1/validator.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/specs/phase1/validator.md b/specs/phase1/validator.md index 558a1b3bf..530bda004 100644 --- a/specs/phase1/validator.md +++ b/specs/phase1/validator.md @@ -1,4 +1,4 @@ -# Ethereum 2.0 Phase 0 -- Honest Validator +# Ethereum 2.0 Phase 1 -- Honest Validator **Notice**: This document is a work-in-progress for researchers and implementers. This is an accompanying document to [Ethereum 2.0 Phase 1](./), which describes the expected actions of a "validator" participating in the Ethereum 2.0 Phase 1 protocol. @@ -99,7 +99,7 @@ Specifically _after_ finding stable peers of attestation subnets (see Phase 0) a ## Beacon chain responsibilities -A validator has two primary responsibilities to the beacon chain: [proposing blocks](#block-proposal) and [creating attestations](#attestations-1). Proposals happen infrequently, whereas attestations should be created once per epoch. +A validator has two primary responsibilities to the beacon chain: [proposing blocks](#block-proposal) and [creating attestations](#attesting). Proposals happen infrequently, whereas attestations should be created once per epoch. These responsibilities are largely unchanged from Phase 0, but utilize the updated `SignedBeaconBlock`, `BeaconBlock`, `BeaconBlockBody`, `Attestation`, and `AttestationData` definitions found in Phase 1. Below notes only the additional and modified behavior with respect to Phase 0. @@ -109,7 +109,7 @@ Phase 1 adds light client committees and associated responsibilities, discussed #### Preparing for a `BeaconBlock` -`slot`, `proposer_index`, `parent_root` fields are unchanged. +`slot`, `proposer_index`, `parent_root`, `state_root` fields are unchanged. #### Constructing the `BeaconBlockBody` @@ -133,7 +133,7 @@ Up to `MAX_EARLY_DERIVED_SECRET_REVEALS`, [`EarlyDerivedSecretReveal`](./custody ##### Shard transitions -Exactly `MAX_SHARDS` [`ShardTransition`](./beacon-chain#shardtransition) objects are included in the block. Default each to an empty `ShardTransition()`. Then for each committee assigned to the slot with an associated `committee_index` and `shard`, set `shard_transitions[shard] = full_transitions[winning_root]` if the committee had enough weight to form a crosslink this slot. +Exactly `MAX_SHARDS` [`ShardTransition`](./beacon-chain.md#shardtransition) objects are included in the block. Default each to an empty `ShardTransition()`. Then for each committee assigned to the slot with an associated `committee_index` and `shard`, set `shard_transitions[shard] = full_transitions[winning_root]` if the committee had enough weight to form a crosslink this slot. Specifically: * Call `shards, winning_roots = get_shard_winning_roots(state, block.slot, block.body.attestations)` @@ -216,7 +216,7 @@ A validator is expected to create, sign, and broadcast an attestation during eac Assignments and the core of this duty are unchanged from Phase 0. There are a few additional fields related to the assigned shard chain. -The `Attestation` and `AttestationData` defined in the [Phase 1 Beacon Chain spec]() utilizes `shard_transition_root: Root` rather than a full `ShardTransition`. For the purposes of the validator and p2p layer, a modified `FullAttestationData` and containing `FullAttestation` are used to send the accompanying `ShardTransition` in its entirety. Note that due to the properties of SSZ `hash_tree_root`, the root and signatures of `AttestationData` and `FullAttestationData` are equivalent. +The `Attestation` and `AttestationData` defined in the [Phase 1 Beacon Chain spec](./beacon-chain.md) utilizes `shard_transition_root: Root` rather than a full `ShardTransition`. For the purposes of the validator and p2p layer, a modified `FullAttestationData` and containing `FullAttestation` are used to send the accompanying `ShardTransition` in its entirety. Note that due to the properties of SSZ `hash_tree_root`, the root and signatures of `AttestationData` and `FullAttestationData` are equivalent. #### `FullAttestationData` From 17c86177d9b1b0ed4963dff5c4cb2e2dc44a6ee0 Mon Sep 17 00:00:00 2001 From: ericsson Date: Thu, 18 Jun 2020 01:43:41 +0300 Subject: [PATCH 08/23] Change types of BeaconBlockBody chunk_challenges and chunk_challenge_responses to List[CustodyChunkChallenge, ...] --- specs/phase1/beacon-chain.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 4e4778abe..a84d432a1 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -252,8 +252,8 @@ class BeaconBlockBody(Container): deposits: List[Deposit, MAX_DEPOSITS] voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] # Custody game - chunk_challenges: List[CustodyChunkResponse, MAX_CUSTODY_CHUNK_CHALLENGES] - chunk_challenge_responses: List[CustodyChunkResponse, MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES] + chunk_challenges: List[CustodyChunkChallenge, MAX_CUSTODY_CHUNK_CHALLENGES] + chunk_challenge_responses: List[CustodyChunkChallenge, MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES] custody_key_reveals: List[CustodyKeyReveal, MAX_CUSTODY_KEY_REVEALS] early_derived_secret_reveals: List[EarlyDerivedSecretReveal, MAX_EARLY_DERIVED_SECRET_REVEALS] custody_slashings: List[SignedCustodySlashing, MAX_CUSTODY_SLASHINGS] From cc84b49d133233e5879c4503b4df2eda58fa642f Mon Sep 17 00:00:00 2001 From: terence tsao Date: Wed, 17 Jun 2020 16:20:46 -0700 Subject: [PATCH 09/23] on_time_attestation_slot instead of current_slot --- specs/phase1/validator.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specs/phase1/validator.md b/specs/phase1/validator.md index 558a1b3bf..65cd23cd8 100644 --- a/specs/phase1/validator.md +++ b/specs/phase1/validator.md @@ -148,15 +148,16 @@ def get_shard_winning_roots(state: BeaconState, shards = [] winning_roots = [] online_indices = get_online_validator_indices(state) - committee_count = get_committee_count_at_slot(state, state.slot) + on_time_attestation_slot = compute_previous_slot(state.slot) + committee_count = get_committee_count_at_slot(state, on_time_attestation_slot) for committee_index in map(CommitteeIndex, range(committee_count)): - shard = compute_shard_from_committee_index(state, committee_index, state.slot) + shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot) # All attestations in the block for this committee/shard and are "on time" shard_attestations = [ attestation for attestation in attestations if is_on_time_attestation(state, attestation) and attestation.data.index == committee_index ] - committee = get_beacon_committee(state, state.slot, committee_index) + committee = get_beacon_committee(state, on_time_attestation_slot, committee_index) # Loop over all shard transition roots, looking for a winning root shard_transition_roots = set([a.data.shard_transition_root for a in shard_attestations]) From 9dc43957e2228df37e3b9260de65a09f4c9bd53c Mon Sep 17 00:00:00 2001 From: ericsson Date: Thu, 18 Jun 2020 03:39:51 +0300 Subject: [PATCH 10/23] a fix according to @protolambda comments --- specs/phase1/beacon-chain.md | 2 +- specs/phase1/custody-game.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index a84d432a1..cd938e0c5 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -253,7 +253,7 @@ class BeaconBlockBody(Container): voluntary_exits: List[SignedVoluntaryExit, MAX_VOLUNTARY_EXITS] # Custody game chunk_challenges: List[CustodyChunkChallenge, MAX_CUSTODY_CHUNK_CHALLENGES] - chunk_challenge_responses: List[CustodyChunkChallenge, MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES] + chunk_challenge_responses: List[CustodyChunkResponse, MAX_CUSTODY_CHUNK_CHALLENGE_RESPONSES] custody_key_reveals: List[CustodyKeyReveal, MAX_CUSTODY_KEY_REVEALS] early_derived_secret_reveals: List[EarlyDerivedSecretReveal, MAX_EARLY_DERIVED_SECRET_REVEALS] custody_slashings: List[SignedCustodySlashing, MAX_CUSTODY_SLASHINGS] diff --git a/specs/phase1/custody-game.md b/specs/phase1/custody-game.md index 124167a35..6b767193a 100644 --- a/specs/phase1/custody-game.md +++ b/specs/phase1/custody-game.md @@ -302,7 +302,7 @@ def process_custody_game_operations(state: BeaconState, body: BeaconBlockBody) - fn(state, operation) for_ops(body.chunk_challenges, process_chunk_challenge) - for_ops(body.chunk_challenge_responses, process_chunk_challenge) + for_ops(body.chunk_challenge_responses, process_chunk_challenge_response) for_ops(body.custody_key_reveals, process_custody_key_reveal) for_ops(body.early_derived_secret_reveals, process_early_derived_secret_reveal) for_ops(body.custody_slashings, process_custody_slashing) From 974ef47c03dc137659b24185d20713ac1dc589ba Mon Sep 17 00:00:00 2001 From: Joanne Fuller Date: Thu, 18 Jun 2020 14:47:10 +1000 Subject: [PATCH 11/23] Clarification of types. --- ssz/simple-serialize.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ssz/simple-serialize.md b/ssz/simple-serialize.md index b8a6bc9a2..700a428e8 100644 --- a/ssz/simple-serialize.md +++ b/ssz/simple-serialize.md @@ -66,6 +66,8 @@ * **union**: union type containing one of the given subtypes * notation `Union[type_0, type_1, ...]`, e.g. `union[null, uint64]` +*Note*: Both `Vector[boolean, N]` and `Bitvector[N]` are valid, yet distinct due to their different serialization requirements. Similarly, both `List[boolean, N]` and `Bitlist[N]` are valid, yet distinct. Generally `Bitvector[N]`/`Bitlist[N]` are preferred because of their serialization efficiencies. + ### Variable-size and fixed-size We recursively define "variable-size" types to be lists, unions, `Bitlist` and all types that contain a variable-size type. All other types are said to be "fixed-size". @@ -88,9 +90,9 @@ Assuming a helper function `default(type)` which returns the default value for ` | `boolean` | `False` | | `Container` | `[default(type) for type in container]` | | `Vector[type, N]` | `[default(type)] * N` | -| `Bitvector[boolean, N]` | `[False] * N` | +| `Bitvector[N]` | `[False] * N` | | `List[type, N]` | `[]` | -| `Bitlist[boolean, N]` | `[]` | +| `Bitlist[N]` | `[]` | | `Union[type_0, type_1, ...]` | `default(type_0)` | #### `is_zero` From 51e7969147f992e72be8a25e5fe61b64059feb89 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 14:28:56 +0800 Subject: [PATCH 12/23] Set linter configs in `linter.ini` --- Makefile | 9 ++++----- linter.ini | 13 +++++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 linter.ini diff --git a/Makefile b/Makefile index da87f7912..d89092483 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,8 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/phase0/*.md) $(wildcard $(SPEC_DIR)/phas COV_HTML_OUT=.htmlcov COV_INDEX_FILE=$(PY_SPEC_DIR)/$(COV_HTML_OUT)/index.html +LINTER_CONFIG_FILE = $(CURDIR)/linter.ini + .PHONY: clean partial_clean all test citest lint generate_tests pyspec install_test open_cov \ install_deposit_contract_tester test_deposit_contract install_deposit_contract_compiler \ compile_deposit_contract test_compile_deposit_contract check_toc @@ -101,9 +103,8 @@ codespell: lint: pyspec . venv/bin/activate; cd $(PY_SPEC_DIR); \ - flake8 --ignore=E252,W504,W503 --max-line-length=120 ./eth2spec \ - && cd ./eth2spec && mypy --follow-imports=silent --warn-unused-ignores --ignore-missing-imports --check-untyped-defs --disallow-incomplete-defs --disallow-untyped-defs -p phase0 \ - && mypy --follow-imports=silent --warn-unused-ignores --ignore-missing-imports --check-untyped-defs --disallow-incomplete-defs --disallow-untyped-defs -p phase1; + flake8 --config $(LINTER_CONFIG_FILE) ./eth2spec \ + && mypy --config-file $(LINTER_CONFIG_FILE) -p eth2spec.phase0 -p eth2spec.phase1 install_deposit_contract_tester: cd $(DEPOSIT_CONTRACT_TESTER_DIR); python3 -m venv venv; . venv/bin/activate; pip3 install -r requirements.txt @@ -123,8 +124,6 @@ test_compile_deposit_contract: cd $(DEPOSIT_CONTRACT_COMPILER_DIR); . venv/bin/activate; \ python3.7 -m pytest . -CURRENT_DIR = ${CURDIR} - # Runs a generator, identified by param 1 define run_generator # Started! diff --git a/linter.ini b/linter.ini new file mode 100644 index 000000000..6575642f1 --- /dev/null +++ b/linter.ini @@ -0,0 +1,13 @@ +[flake8] +ignore = E252,W504,W503 +max-line-length = 120 + +[mypy] +disallow_incomplete_defs = True +disallow_untyped_defs = True + +warn_unused_ignores = True +warn_unused_configs = True +warn_redundant_casts = True + +ignore_missing_imports = True From 27eb2e25793e764afa21e683c413e26196d03be5 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 14:54:27 +0800 Subject: [PATCH 13/23] Move testing files from */phase_0 to */phase0, */phase_1 to */phase1 --- tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/__init__.py | 0 .../test/{phase_0 => phase0}/block_processing/__init__.py | 0 .../block_processing/test_process_attestation.py | 0 .../block_processing/test_process_attester_slashing.py | 0 .../block_processing/test_process_block_header.py | 0 .../{phase_0 => phase0}/block_processing/test_process_deposit.py | 0 .../block_processing/test_process_proposer_slashing.py | 0 .../block_processing/test_process_voluntary_exit.py | 0 .../test/{phase_0 => phase0}/epoch_processing/__init__.py | 0 .../epoch_processing/run_epoch_process_base.py | 0 .../epoch_processing/test_process_final_updates.py | 0 .../test_process_justification_and_finalization.py | 0 .../epoch_processing/test_process_registry_updates.py | 0 .../epoch_processing/test_process_rewards_and_penalties.py | 0 .../epoch_processing/test_process_slashings.py | 0 .../pyspec/eth2spec/test/{phase_0 => phase0}/rewards/__init__.py | 0 .../eth2spec/test/{phase_0 => phase0}/rewards/test_basic.py | 0 .../pyspec/eth2spec/test/{phase_0 => phase0}/rewards/test_leak.py | 0 .../eth2spec/test/{phase_0 => phase0}/rewards/test_random.py | 0 .../pyspec/eth2spec/test/{phase_0 => phase0}/sanity/__init__.py | 0 .../eth2spec/test/{phase_0 => phase0}/sanity/test_blocks.py | 0 .../pyspec/eth2spec/test/{phase_0 => phase0}/sanity/test_slots.py | 0 tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/__init__.py | 0 .../test/{phase_1 => phase1}/block_processing/__init__.py | 0 .../block_processing/test_process_attestation.py | 0 .../block_processing/test_process_chunk_challenge.py | 0 .../block_processing/test_process_custody_key_reveal.py | 0 .../block_processing/test_process_custody_slashing.py | 0 .../block_processing/test_process_early_derived_secret_reveal.py | 0 .../block_processing/test_process_shard_transition.py | 0 .../epoch_processing/test_process_challenge_deadlines.py | 0 .../epoch_processing/test_process_custody_final_updates.py | 0 .../epoch_processing/test_process_reveal_deadlines.py | 0 .../pyspec/eth2spec/test/{phase_1 => phase1}/sanity/__init__.py | 0 .../eth2spec/test/{phase_1 => phase1}/sanity/test_blocks.py | 0 .../eth2spec/test/{phase_1 => phase1}/unittests/__init__.py | 0 .../test/{phase_1 => phase1}/unittests/test_get_start_shard.py | 0 37 files changed, 0 insertions(+), 0 deletions(-) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/test_process_attestation.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/test_process_attester_slashing.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/test_process_block_header.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/test_process_deposit.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/test_process_proposer_slashing.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/block_processing/test_process_voluntary_exit.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/run_epoch_process_base.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/test_process_final_updates.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/test_process_justification_and_finalization.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/test_process_registry_updates.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/test_process_rewards_and_penalties.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/epoch_processing/test_process_slashings.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/rewards/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/rewards/test_basic.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/rewards/test_leak.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/rewards/test_random.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/sanity/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/sanity/test_blocks.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_0 => phase0}/sanity/test_slots.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/test_process_attestation.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/test_process_chunk_challenge.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/test_process_custody_key_reveal.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/test_process_custody_slashing.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/test_process_early_derived_secret_reveal.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/block_processing/test_process_shard_transition.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/epoch_processing/test_process_challenge_deadlines.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/epoch_processing/test_process_custody_final_updates.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/epoch_processing/test_process_reveal_deadlines.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/sanity/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/sanity/test_blocks.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/unittests/__init__.py (100%) rename tests/core/pyspec/eth2spec/test/{phase_1 => phase1}/unittests/test_get_start_shard.py (100%) diff --git a/tests/core/pyspec/eth2spec/test/phase_0/__init__.py b/tests/core/pyspec/eth2spec/test/phase0/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/__init__.py rename to tests/core/pyspec/eth2spec/test/phase0/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/__init__.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/__init__.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attestation.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attestation.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attester_slashing.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attester_slashing.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_attester_slashing.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_attester_slashing.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_block_header.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_block_header.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_block_header.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_block_header.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_deposit.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_deposit.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_proposer_slashing.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_proposer_slashing.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_proposer_slashing.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_proposer_slashing.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py b/tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_voluntary_exit.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/block_processing/test_process_voluntary_exit.py rename to tests/core/pyspec/eth2spec/test/phase0/block_processing/test_process_voluntary_exit.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/__init__.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/__init__.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/run_epoch_process_base.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/run_epoch_process_base.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_final_updates.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_final_updates.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_justification_and_finalization.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_justification_and_finalization.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_justification_and_finalization.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_registry_updates.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_registry_updates.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_rewards_and_penalties.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_rewards_and_penalties.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_slashings.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_slashings.py rename to tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/rewards/__init__.py b/tests/core/pyspec/eth2spec/test/phase0/rewards/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/rewards/__init__.py rename to tests/core/pyspec/eth2spec/test/phase0/rewards/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/rewards/test_basic.py b/tests/core/pyspec/eth2spec/test/phase0/rewards/test_basic.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/rewards/test_basic.py rename to tests/core/pyspec/eth2spec/test/phase0/rewards/test_basic.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/rewards/test_leak.py b/tests/core/pyspec/eth2spec/test/phase0/rewards/test_leak.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/rewards/test_leak.py rename to tests/core/pyspec/eth2spec/test/phase0/rewards/test_leak.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/rewards/test_random.py b/tests/core/pyspec/eth2spec/test/phase0/rewards/test_random.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/rewards/test_random.py rename to tests/core/pyspec/eth2spec/test/phase0/rewards/test_random.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/sanity/__init__.py b/tests/core/pyspec/eth2spec/test/phase0/sanity/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/sanity/__init__.py rename to tests/core/pyspec/eth2spec/test/phase0/sanity/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/sanity/test_blocks.py rename to tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py diff --git a/tests/core/pyspec/eth2spec/test/phase_0/sanity/test_slots.py b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_slots.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_0/sanity/test_slots.py rename to tests/core/pyspec/eth2spec/test/phase0/sanity/test_slots.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/__init__.py b/tests/core/pyspec/eth2spec/test/phase1/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/__init__.py rename to tests/core/pyspec/eth2spec/test/phase1/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/__init__.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/__init__.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_attestation.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_attestation.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_attestation.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_chunk_challenge.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_chunk_challenge.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_chunk_challenge.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_chunk_challenge.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_custody_key_reveal.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_key_reveal.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_custody_key_reveal.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_key_reveal.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_custody_slashing.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_slashing.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_custody_slashing.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_slashing.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_early_derived_secret_reveal.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_early_derived_secret_reveal.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_early_derived_secret_reveal.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_early_derived_secret_reveal.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_shard_transition.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_shard_transition.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/block_processing/test_process_shard_transition.py rename to tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_shard_transition.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/epoch_processing/test_process_challenge_deadlines.py b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_challenge_deadlines.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/epoch_processing/test_process_challenge_deadlines.py rename to tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_challenge_deadlines.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/epoch_processing/test_process_custody_final_updates.py b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_custody_final_updates.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/epoch_processing/test_process_custody_final_updates.py rename to tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_custody_final_updates.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/epoch_processing/test_process_reveal_deadlines.py b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_reveal_deadlines.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/epoch_processing/test_process_reveal_deadlines.py rename to tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_reveal_deadlines.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/sanity/__init__.py b/tests/core/pyspec/eth2spec/test/phase1/sanity/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/sanity/__init__.py rename to tests/core/pyspec/eth2spec/test/phase1/sanity/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/phase1/sanity/test_blocks.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/sanity/test_blocks.py rename to tests/core/pyspec/eth2spec/test/phase1/sanity/test_blocks.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/unittests/__init__.py b/tests/core/pyspec/eth2spec/test/phase1/unittests/__init__.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/unittests/__init__.py rename to tests/core/pyspec/eth2spec/test/phase1/unittests/__init__.py diff --git a/tests/core/pyspec/eth2spec/test/phase_1/unittests/test_get_start_shard.py b/tests/core/pyspec/eth2spec/test/phase1/unittests/test_get_start_shard.py similarity index 100% rename from tests/core/pyspec/eth2spec/test/phase_1/unittests/test_get_start_shard.py rename to tests/core/pyspec/eth2spec/test/phase1/unittests/test_get_start_shard.py From ec25f7863244c5c7173e69851fc0f10cc079918f Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 14:55:50 +0800 Subject: [PATCH 14/23] Update path --- .../test_process_final_updates.py | 2 +- ..._process_justification_and_finalization.py | 2 +- .../test_process_registry_updates.py | 2 +- .../test_process_rewards_and_penalties.py | 7 +++--- .../test_process_slashings.py | 2 +- .../test/phase0/sanity/test_blocks.py | 14 +++++------ .../test_process_attestation.py | 5 ++-- .../test_process_chunk_challenge.py | 23 ++++++++++--------- .../test_process_custody_slashing.py | 13 ++++++----- .../test_process_challenge_deadlines.py | 9 ++++---- .../test_process_custody_final_updates.py | 19 ++++++++------- .../test_process_reveal_deadlines.py | 9 ++++---- .../pyspec/eth2spec/test/test_finality.py | 4 ++-- tests/generators/epoch_processing/main.py | 2 +- tests/generators/operations/main.py | 2 +- tests/generators/rewards/main.py | 2 +- tests/generators/sanity/main.py | 2 +- 17 files changed, 64 insertions(+), 55 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_final_updates.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_final_updates.py index 8cb09be0e..27676a59a 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_final_updates.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_final_updates.py @@ -1,5 +1,5 @@ from eth2spec.test.context import spec_state_test, with_all_phases -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import ( +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import ( run_epoch_processing_with, run_epoch_processing_to ) from eth2spec.test.helpers.state import transition_to diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_justification_and_finalization.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_justification_and_finalization.py index 09af2126d..a5408c9ad 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_justification_and_finalization.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_justification_and_finalization.py @@ -1,5 +1,5 @@ from eth2spec.test.context import spec_state_test, with_all_phases -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import ( +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import ( run_epoch_processing_with ) from eth2spec.test.helpers.state import transition_to diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py index b6597b1cf..c734010f3 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_registry_updates.py @@ -1,7 +1,7 @@ from eth2spec.test.helpers.deposits import mock_deposit from eth2spec.test.helpers.state import next_epoch, next_slots from eth2spec.test.context import spec_state_test, with_all_phases -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import run_epoch_processing_with def run_process_registry_updates(spec, state): diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_rewards_and_penalties.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_rewards_and_penalties.py index bafefcad6..d3744f897 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_rewards_and_penalties.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_rewards_and_penalties.py @@ -1,4 +1,5 @@ from eth2spec.test.context import ( + PHASE0, spec_state_test, spec_test, with_all_phases, with_phases, single_phase, with_custom_state, @@ -16,7 +17,7 @@ from eth2spec.test.helpers.attestations import ( ) from eth2spec.test.helpers.rewards import leaking from eth2spec.test.helpers.attester_slashings import get_indexed_attestation_participants -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import run_epoch_processing_with from random import Random @@ -24,7 +25,7 @@ def run_process_rewards_and_penalties(spec, state): yield from run_epoch_processing_with(spec, state, 'process_rewards_and_penalties') -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_genesis_epoch_no_attestations_no_penalties(spec, state): pre_state = state.copy() @@ -37,7 +38,7 @@ def test_genesis_epoch_no_attestations_no_penalties(spec, state): assert state.balances[index] == pre_state.balances[index] -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_genesis_epoch_full_attestations_no_rewards(spec, state): attestations = [] diff --git a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py index 23c8ce11a..5101c7548 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py +++ b/tests/core/pyspec/eth2spec/test/phase0/epoch_processing/test_process_slashings.py @@ -1,5 +1,5 @@ from eth2spec.test.context import spec_state_test, with_all_phases -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import ( +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import ( run_epoch_processing_with, run_epoch_processing_to ) from eth2spec.test.helpers.state import next_epoch diff --git a/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py index 1e057e5a9..c3b1dceed 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py +++ b/tests/core/pyspec/eth2spec/test/phase0/sanity/test_blocks.py @@ -21,8 +21,8 @@ from eth2spec.test.helpers.deposits import prepare_state_and_deposit from eth2spec.test.helpers.shard_transitions import get_shard_transition_of_committee from eth2spec.test.context import ( + PHASE0, PHASE1, spec_state_test, with_all_phases, expect_assertion_error, always_bls, with_phases, - PHASE1 ) @@ -113,7 +113,7 @@ def process_and_sign_block_without_header_validations(spec, state, block): return sign_block(spec, state, block) -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_proposal_for_genesis_slot(spec, state): assert state.slot == spec.GENESIS_SLOT @@ -484,7 +484,7 @@ def test_duplicate_attester_slashing(spec, state): # All AttesterSlashing tests should be adopted for Phase 1 but helper support is not yet there -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_multiple_attester_slashings_no_overlap(spec, state): # Skip test if config cannot handle multiple AttesterSlashings per block @@ -525,7 +525,7 @@ def test_multiple_attester_slashings_no_overlap(spec, state): check_attester_slashing_effect(spec, pre_state, state, full_indices) -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_multiple_attester_slashings_partial_overlap(spec, state): # Skip test if config cannot handle multiple AttesterSlashings per block @@ -740,7 +740,7 @@ def prepare_signed_exits(spec, state, indices): # exceeding the minimal-config randao mixes memory size. # Applies to all voluntary-exit sanity block tests. -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_voluntary_exit(spec, state): validator_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1] @@ -768,7 +768,7 @@ def test_voluntary_exit(spec, state): assert state.validators[validator_index].exit_epoch < spec.FAR_FUTURE_EPOCH -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_double_validator_exit_same_block(spec, state): validator_index = spec.get_active_validator_indices(state, spec.get_current_epoch(state))[-1] @@ -789,7 +789,7 @@ def test_double_validator_exit_same_block(spec, state): yield 'post', None -@with_phases(['phase0']) +@with_phases([PHASE0]) @spec_state_test def test_multiple_different_validator_exits_same_block(spec, state): validator_indices = [ diff --git a/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_attestation.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_attestation.py index 34ff28412..a0cf7472f 100644 --- a/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_attestation.py +++ b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_attestation.py @@ -1,4 +1,5 @@ from eth2spec.test.context import ( + PHASE0, with_all_phases_except, spec_state_test, always_bls, @@ -11,7 +12,7 @@ from eth2spec.test.helpers.attestations import ( ) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test @always_bls def test_on_time_success(spec, state): @@ -22,7 +23,7 @@ def test_on_time_success(spec, state): yield from run_attestation_processing(spec, state, attestation) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test @always_bls def test_late_success(spec, state): diff --git a/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_chunk_challenge.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_chunk_challenge.py index bdb4325fd..c9adabb62 100644 --- a/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_chunk_challenge.py +++ b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_chunk_challenge.py @@ -8,11 +8,12 @@ from eth2spec.test.helpers.attestations import ( ) from eth2spec.test.helpers.state import transition_to from eth2spec.test.context import ( + PHASE0, with_all_phases_except, spec_state_test, expect_assertion_error, ) -from eth2spec.test.phase_0.block_processing.test_process_attestation import run_attestation_processing +from eth2spec.test.phase0.block_processing.test_process_attestation import run_attestation_processing def run_chunk_challenge_processing(spec, state, custody_chunk_challenge, valid=True): @@ -64,7 +65,7 @@ def run_custody_chunk_response_processing(spec, state, custody_response, valid=T yield 'post', state -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_challenge_appended(spec, state): transition_to(spec, state, state.slot + 1) @@ -85,7 +86,7 @@ def test_challenge_appended(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_challenge_empty_element_replaced(spec, state): transition_to(spec, state, state.slot + 1) @@ -108,7 +109,7 @@ def test_challenge_empty_element_replaced(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_duplicate_challenge(spec, state): transition_to(spec, state, state.slot + 1) @@ -131,7 +132,7 @@ def test_duplicate_challenge(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge, valid=False) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_second_challenge(spec, state): transition_to(spec, state, state.slot + 1) @@ -156,7 +157,7 @@ def test_second_challenge(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge1) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_multiple_epochs_custody(spec, state): transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 3) @@ -178,7 +179,7 @@ def test_multiple_epochs_custody(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_many_epochs_custody(spec, state): transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 20) @@ -200,7 +201,7 @@ def test_many_epochs_custody(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_off_chain_attestation(spec, state): transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH) @@ -218,7 +219,7 @@ def test_off_chain_attestation(spec, state): yield from run_chunk_challenge_processing(spec, state, challenge) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_custody_response(spec, state): transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH) @@ -246,7 +247,7 @@ def test_custody_response(spec, state): yield from run_custody_chunk_response_processing(spec, state, custody_response) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_custody_response_multiple_epochs(spec, state): transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 3) @@ -274,7 +275,7 @@ def test_custody_response_multiple_epochs(spec, state): yield from run_custody_chunk_response_processing(spec, state, custody_response) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_custody_response_many_epochs(spec, state): transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 20) diff --git a/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_slashing.py b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_slashing.py index ec0bac82d..07cd76996 100644 --- a/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_slashing.py +++ b/tests/core/pyspec/eth2spec/test/phase1/block_processing/test_process_custody_slashing.py @@ -9,11 +9,12 @@ from eth2spec.test.helpers.attestations import ( from eth2spec.utils.ssz.ssz_typing import ByteList from eth2spec.test.helpers.state import get_balance, transition_to from eth2spec.test.context import ( + PHASE0, with_all_phases_except, spec_state_test, expect_assertion_error, ) -from eth2spec.test.phase_0.block_processing.test_process_attestation import run_attestation_processing +from eth2spec.test.phase0.block_processing.test_process_attestation import run_attestation_processing def run_custody_slashing_processing(spec, state, custody_slashing, valid=True, correct=True): @@ -102,31 +103,31 @@ def run_standard_custody_slashing_test(spec, yield from run_custody_slashing_processing(spec, state, slashing, valid=valid, correct=correct) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_custody_slashing(spec, state): yield from run_standard_custody_slashing_test(spec, state) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_incorrect_custody_slashing(spec, state): yield from run_standard_custody_slashing_test(spec, state, correct=False) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_multiple_epochs_custody(spec, state): yield from run_standard_custody_slashing_test(spec, state, shard_lateness=spec.SLOTS_PER_EPOCH * 3) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_many_epochs_custody(spec, state): yield from run_standard_custody_slashing_test(spec, state, shard_lateness=spec.SLOTS_PER_EPOCH * 10) -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_invalid_custody_slashing(spec, state): yield from run_standard_custody_slashing_test( diff --git a/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_challenge_deadlines.py b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_challenge_deadlines.py index f3675732a..675b0d8da 100644 --- a/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_challenge_deadlines.py +++ b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_challenge_deadlines.py @@ -7,13 +7,14 @@ from eth2spec.test.helpers.attestations import ( ) from eth2spec.test.helpers.state import transition_to from eth2spec.test.context import ( + PHASE0, with_all_phases_except, spec_state_test, ) -from eth2spec.test.phase_0.block_processing.test_process_attestation import run_attestation_processing -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with +from eth2spec.test.phase0.block_processing.test_process_attestation import run_attestation_processing +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import run_epoch_processing_with -from eth2spec.test.phase_1.block_processing.test_process_chunk_challenge import ( +from eth2spec.test.phase1.block_processing.test_process_chunk_challenge import ( run_chunk_challenge_processing, ) @@ -22,7 +23,7 @@ def run_process_challenge_deadlines(spec, state): yield from run_epoch_processing_with(spec, state, 'process_challenge_deadlines') -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_slashed_after_chunk_challenge(spec, state): transition_to(spec, state, state.slot + 1) diff --git a/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_custody_final_updates.py b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_custody_final_updates.py index 6ca6c8c99..630ddc3a7 100644 --- a/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_custody_final_updates.py +++ b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_custody_final_updates.py @@ -1,3 +1,6 @@ +from eth2spec.test.context import ( + PHASE0, +) from eth2spec.test.helpers.custody import ( get_valid_chunk_challenge, get_valid_custody_chunk_response, @@ -12,21 +15,21 @@ from eth2spec.test.context import ( with_all_phases_except, spec_state_test, ) -from eth2spec.test.phase_0.block_processing.test_process_attestation import run_attestation_processing -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with +from eth2spec.test.phase0.block_processing.test_process_attestation import run_attestation_processing +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import run_epoch_processing_with -from eth2spec.test.phase_1.block_processing.test_process_chunk_challenge import ( +from eth2spec.test.phase1.block_processing.test_process_chunk_challenge import ( run_chunk_challenge_processing, run_custody_chunk_response_processing, ) -from eth2spec.test.phase_1.block_processing.test_process_custody_key_reveal import run_custody_key_reveal_processing +from eth2spec.test.phase1.block_processing.test_process_custody_key_reveal import run_custody_key_reveal_processing def run_process_custody_final_updates(spec, state): yield from run_epoch_processing_with(spec, state, 'process_custody_final_updates') -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_withdrawal_delay(spec, state): spec.initiate_validator_exit(state, 0) @@ -37,7 +40,7 @@ def test_validator_withdrawal_delay(spec, state): assert state.validators[0].withdrawable_epoch == spec.FAR_FUTURE_EPOCH -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_withdrawal_reenable_after_custody_reveal(spec, state): spec.initiate_validator_exit(state, 0) @@ -60,7 +63,7 @@ def test_validator_withdrawal_reenable_after_custody_reveal(spec, state): assert state.validators[0].withdrawable_epoch < spec.FAR_FUTURE_EPOCH -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_withdrawal_suspend_after_chunk_challenge(spec, state): transition_to(spec, state, state.slot + 1) @@ -108,7 +111,7 @@ def test_validator_withdrawal_suspend_after_chunk_challenge(spec, state): assert state.validators[validator_index].withdrawable_epoch == spec.FAR_FUTURE_EPOCH -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_withdrawal_resume_after_chunk_challenge_response(spec, state): transition_to(spec, state, state.slot + 1) diff --git a/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_reveal_deadlines.py b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_reveal_deadlines.py index 9cc0069b9..da1a60446 100644 --- a/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_reveal_deadlines.py +++ b/tests/core/pyspec/eth2spec/test/phase1/epoch_processing/test_process_reveal_deadlines.py @@ -3,18 +3,19 @@ from eth2spec.test.helpers.custody import ( ) from eth2spec.test.helpers.state import transition_to from eth2spec.test.context import ( + PHASE0, with_all_phases_except, spec_state_test, ) -from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with -from eth2spec.test.phase_1.block_processing.test_process_custody_key_reveal import run_custody_key_reveal_processing +from eth2spec.test.phase0.epoch_processing.run_epoch_process_base import run_epoch_processing_with +from eth2spec.test.phase1.block_processing.test_process_custody_key_reveal import run_custody_key_reveal_processing def run_process_challenge_deadlines(spec, state): yield from run_epoch_processing_with(spec, state, 'process_challenge_deadlines') -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_slashed_after_reveal_deadline(spec, state): assert state.validators[0].slashed == 0 @@ -33,7 +34,7 @@ def test_validator_slashed_after_reveal_deadline(spec, state): assert state.validators[0].slashed == 1 -@with_all_phases_except(['phase0']) +@with_all_phases_except([PHASE0]) @spec_state_test def test_validator_not_slashed_after_reveal(spec, state): transition_to(spec, state, spec.EPOCHS_PER_CUSTODY_PERIOD * spec.SLOTS_PER_EPOCH) diff --git a/tests/core/pyspec/eth2spec/test/test_finality.py b/tests/core/pyspec/eth2spec/test/test_finality.py index 55ccde2d9..adbadcdf2 100644 --- a/tests/core/pyspec/eth2spec/test/test_finality.py +++ b/tests/core/pyspec/eth2spec/test/test_finality.py @@ -1,4 +1,4 @@ -from eth2spec.test.context import spec_state_test, never_bls, with_all_phases, with_phases +from eth2spec.test.context import PHASE0, spec_state_test, never_bls, with_all_phases, with_phases from eth2spec.test.helpers.state import next_epoch_via_block from eth2spec.test.helpers.attestations import next_epoch_with_attestations @@ -28,7 +28,7 @@ def check_finality(spec, assert state.finalized_checkpoint == prev_state.finalized_checkpoint -@with_phases(["phase0"]) +@with_phases([PHASE0]) @spec_state_test @never_bls def test_finality_no_updates_at_genesis(spec, state): diff --git a/tests/generators/epoch_processing/main.py b/tests/generators/epoch_processing/main.py index f3bbc21e6..13ac76f41 100644 --- a/tests/generators/epoch_processing/main.py +++ b/tests/generators/epoch_processing/main.py @@ -2,7 +2,7 @@ from typing import Iterable from eth2spec.phase0 import spec as spec_phase0 from eth2spec.phase1 import spec as spec_phase1 -from eth2spec.test.phase_0.epoch_processing import ( +from eth2spec.test.phase0.epoch_processing import ( test_process_final_updates, test_process_justification_and_finalization, test_process_registry_updates, diff --git a/tests/generators/operations/main.py b/tests/generators/operations/main.py index 935c7aa63..6d4f6d139 100644 --- a/tests/generators/operations/main.py +++ b/tests/generators/operations/main.py @@ -1,6 +1,6 @@ from typing import Iterable -from eth2spec.test.phase_0.block_processing import ( +from eth2spec.test.phase0.block_processing import ( test_process_attestation, test_process_attester_slashing, test_process_block_header, diff --git a/tests/generators/rewards/main.py b/tests/generators/rewards/main.py index c90943cab..5d063c434 100644 --- a/tests/generators/rewards/main.py +++ b/tests/generators/rewards/main.py @@ -2,7 +2,7 @@ from typing import Iterable from eth2spec.phase0 import spec as spec_phase0 from eth2spec.phase1 import spec as spec_phase1 -from eth2spec.test.phase_0.rewards import ( +from eth2spec.test.phase0.rewards import ( test_basic, test_leak, test_random, diff --git a/tests/generators/sanity/main.py b/tests/generators/sanity/main.py index 89fb89838..45a1c8c4f 100644 --- a/tests/generators/sanity/main.py +++ b/tests/generators/sanity/main.py @@ -5,7 +5,7 @@ from gen_base import gen_runner, gen_typing from gen_from_tests.gen import generate_from_tests from eth2spec.test.context import PHASE0 -from eth2spec.test.phase_0.sanity import test_blocks, test_slots +from eth2spec.test.phase0.sanity import test_blocks, test_slots from eth2spec.config import config_util from eth2spec.phase0 import spec as spec_phase0 from eth2spec.phase1 import spec as spec_phase1 From 7dbecdf9044a65ff438791c90ad7dfc32763f76f Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 17:06:38 +0800 Subject: [PATCH 15/23] Fix some missing arguments --- specs/phase1/validator.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specs/phase1/validator.md b/specs/phase1/validator.md index 1ce98a409..073458009 100644 --- a/specs/phase1/validator.md +++ b/specs/phase1/validator.md @@ -94,7 +94,7 @@ Beacon chain validator assignments to beacon committees and beacon block proposa Lookahead for beacon committee assignments operates in the same manner as Phase 0, but committee members must join a shard block pubsub topic in addition to the committee attestation topic. Specifically _after_ finding stable peers of attestation subnets (see Phase 0) a validator should: -* Let `shard = compute_shard_from_committee_index(committe_index)` +* Let `shard = compute_shard_from_committee_index(state, committee_index, slot)` * Subscribe to the pubsub topic `shard_{shard}_block` (attestation subnet peers should have this topic available). ## Beacon chain responsibilities @@ -136,7 +136,7 @@ Up to `MAX_EARLY_DERIVED_SECRET_REVEALS`, [`EarlyDerivedSecretReveal`](./custody Exactly `MAX_SHARDS` [`ShardTransition`](./beacon-chain#shardtransition) objects are included in the block. Default each to an empty `ShardTransition()`. Then for each committee assigned to the slot with an associated `committee_index` and `shard`, set `shard_transitions[shard] = full_transitions[winning_root]` if the committee had enough weight to form a crosslink this slot. Specifically: -* Call `shards, winning_roots = get_shard_winning_roots(state, block.slot, block.body.attestations)` +* Call `shards, winning_roots = get_shard_winning_roots(state, block.body.attestations)` * Let `full_transitions` be a dictionary mapping from the `shard_transition_root`s found in `attestations` to the corresponding full `ShardTransition` * Then for each `shard` and `winning_root` in `zip(shards, winning_roots)` set `shard_transitions[shard] = full_transitions[winning_root]` @@ -185,7 +185,7 @@ def get_shard_winning_roots(state: BeaconState, ##### Light client fields -First retrieve `best_aggregate` from `get_best_light_client_aggregate` where `aggregates` is a list of valid aggregated `LightClientVote`s for the previous slot. +First retrieve `best_aggregate` from `get_best_light_client_aggregate(block, aggregates)` where `aggregates` is a list of valid aggregated `LightClientVote`s for the previous slot. Then: * Set `light_client_bits = best_aggregate.aggregation_bits` From 6aca7afd818aa6089128492173ec7856b46b65c4 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 17:20:27 +0800 Subject: [PATCH 16/23] Add notes of active shard count --- specs/phase1/validator.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/specs/phase1/validator.md b/specs/phase1/validator.md index 073458009..2c5baa1a5 100644 --- a/specs/phase1/validator.md +++ b/specs/phase1/validator.md @@ -97,6 +97,8 @@ Specifically _after_ finding stable peers of attestation subnets (see Phase 0) a * Let `shard = compute_shard_from_committee_index(state, committee_index, slot)` * Subscribe to the pubsub topic `shard_{shard}_block` (attestation subnet peers should have this topic available). +TODO: For now, the `state` we pass to `compute_shard_from_committee_index` is the current state without considering `len(state.shard_states)`, i.e., the result from `get_active_shard_count(state)` changes. We should fix it when we have shard count update logic. + ## Beacon chain responsibilities A validator has two primary responsibilities to the beacon chain: [proposing blocks](#block-proposal) and [creating attestations](#attestations-1). Proposals happen infrequently, whereas attestations should be created once per epoch. From 5171a91dfba310bccc2d63cb40ef820c387b6ff0 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 18:55:15 +0800 Subject: [PATCH 17/23] Fix path --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index d89092483..5ef25289e 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,8 @@ MARKDOWN_FILES = $(wildcard $(SPEC_DIR)/phase0/*.md) $(wildcard $(SPEC_DIR)/phas COV_HTML_OUT=.htmlcov COV_INDEX_FILE=$(PY_SPEC_DIR)/$(COV_HTML_OUT)/index.html -LINTER_CONFIG_FILE = $(CURDIR)/linter.ini +CURRENT_DIR = ${CURDIR} +LINTER_CONFIG_FILE = $(CURRENT_DIR)/linter.ini .PHONY: clean partial_clean all test citest lint generate_tests pyspec install_test open_cov \ install_deposit_contract_tester test_deposit_contract install_deposit_contract_compiler \ From 8cf07742901bdb467591cb98fe99de85433997fe Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 20:34:34 +0800 Subject: [PATCH 18/23] Fix shard_block_length type in `compute_updated_gasprice` --- specs/phase1/beacon-chain.md | 2 +- specs/phase1/shard-transition.md | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index cd938e0c5..6e8700e2f 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -493,7 +493,7 @@ def compute_offset_slots(start_slot: Slot, end_slot: Slot) -> Sequence[Slot]: #### `compute_updated_gasprice` ```python -def compute_updated_gasprice(prev_gasprice: Gwei, shard_block_length: uint8) -> Gwei: +def compute_updated_gasprice(prev_gasprice: Gwei, shard_block_length: uint64) -> Gwei: if shard_block_length > TARGET_SHARD_BLOCK_SIZE: delta = (prev_gasprice * (shard_block_length - TARGET_SHARD_BLOCK_SIZE) // TARGET_SHARD_BLOCK_SIZE // GASPRICE_ADJUSTMENT_COEFFICIENT) diff --git a/specs/phase1/shard-transition.md b/specs/phase1/shard-transition.md index 24c39aa3d..083064225 100644 --- a/specs/phase1/shard-transition.md +++ b/specs/phase1/shard-transition.md @@ -70,8 +70,9 @@ def shard_state_transition(shard_state: ShardState, """ shard_state.slot = block.slot prev_gasprice = shard_state.gasprice - shard_state.gasprice = compute_updated_gasprice(prev_gasprice, len(block.body)) - if len(block.body) == 0: + shard_block_length = len(block.body) + shard_state.gasprice = compute_updated_gasprice(prev_gasprice, uint64(shard_block_length)) + if shard_block_length == 0: latest_block_root = shard_state.latest_block_root else: latest_block_root = hash_tree_root(block) From 35bf3b5290bed6bbae03ca62d798766dbcd3791c Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 23:20:24 +0800 Subject: [PATCH 19/23] Refactor `validate_attestation` Co-authored-by: Danny Ryan --- specs/phase1/beacon-chain.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index f63654182..27f317bc1 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -765,9 +765,8 @@ def validate_attestation(state: BeaconState, attestation: Attestation) -> None: # Correct parent block root assert data.beacon_block_root == get_block_root_at_slot(state, compute_previous_slot(state.slot)) # Correct shard number - assert attestation.data.shard == compute_shard_from_committee_index( - state, attestation.data.index, attestation.data.slot - ) + shard = compute_shard_from_committee_index(state, attestation.data.index, attestation.data.slot) + assert attestation.data.shard == shard # Type 2: no shard transition else: # Ensure delayed attestation From fe47869d5f73ba5c4aea419186fad8e47b9ced63 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 18 Jun 2020 23:32:23 +0800 Subject: [PATCH 20/23] Revert `process_crosslinks` and add comment --- specs/phase1/beacon-chain.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 27f317bc1..485a52d06 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -926,20 +926,20 @@ def process_crosslinks(state: BeaconState, committee_count = get_committee_count_at_slot(state, on_time_attestation_slot) for committee_index in map(CommitteeIndex, range(committee_count)): # All attestations in the block for this committee/shard and current slot + shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot) + # Since the attestations are validated, all `shard_attestations` satisfy `attestation.data.shard == shard` shard_attestations = [ attestation for attestation in attestations if is_on_time_attestation(state, attestation) and attestation.data.index == committee_index ] - if len(shard_attestations) > 0: - shard = shard_attestations[0].data.shard - winning_root = process_crosslink_for_shard( - state, committee_index, shard_transitions[shard], shard_attestations - ) - if winning_root != Root(): - # Mark relevant pending attestations as creating a successful crosslink - for pending_attestation in state.current_epoch_attestations: - if is_winning_attestation(state, pending_attestation, committee_index, winning_root): - pending_attestation.crosslink_success = True + winning_root = process_crosslink_for_shard( + state, committee_index, shard_transitions[shard], shard_attestations + ) + if winning_root != Root(): + # Mark relevant pending attestations as creating a successful crosslink + for pending_attestation in state.current_epoch_attestations: + if is_winning_attestation(state, pending_attestation, committee_index, winning_root): + pending_attestation.crosslink_success = True ``` ###### `verify_empty_shard_transition` From bd61c2686b79f1ea56c8c9db14577702fb108cae Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 18 Jun 2020 09:45:10 -0600 Subject: [PATCH 21/23] PR feedback --- specs/phase0/p2p-interface.md | 2 +- specs/phase1/beacon-chain.md | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/specs/phase0/p2p-interface.md b/specs/phase0/p2p-interface.md index 211508f00..96bf856da 100644 --- a/specs/phase0/p2p-interface.md +++ b/specs/phase0/p2p-interface.md @@ -275,7 +275,7 @@ Additional global topics are used to propagate lower frequency validator message Attestation subnets are used to propagate unaggregated attestations to subsections of the network. Their `Name`s are: - `beacon_attestation_{subnet_id}` - These topics are used to propagate unaggregated attestations to the subnet `subnet_id` (typically beacon and persistent committees) to be aggregated before being gossiped to `beacon_aggregate_and_proof`. The following validations MUST pass before forwarding the `attestation` on the subnet. - - _[REJECT]_ The attestation is for the correct subnet -- i.e. `compute_subnet_for_attestation(committees_per_slot, attestation.data.slot, attestation.data.index) == subnet_id`, where `committees_per_slot = get_committee_count_per_slot(state, attestation.data.target.epoch)`, which may be computed along with the committee information for the signature check. + - _[REJECT]_ The attestation is for the correct subnet -- i.e. `compute_subnet_for_attestation(committees_per_slot, attestation.data.slot, attestation.data.index) == subnet_id`, where `committees_per_slot = get_committee_count_per_slot(state, attestation.data.target.epoch)`, which may be pre-computed along with the committee information for the signature check. - _[IGNORE]_ `attestation.data.slot` is within the last `ATTESTATION_PROPAGATION_SLOT_RANGE` slots (within a `MAXIMUM_GOSSIP_CLOCK_DISPARITY` allowance) -- i.e. `attestation.data.slot + ATTESTATION_PROPAGATION_SLOT_RANGE >= current_slot >= attestation.data.slot` (a client MAY queue future attestations for processing at the appropriate slot). - _[REJECT]_ The attestation is unaggregated -- that is, it has exactly one participating validator (`len([bit in bit attestation.aggregation_bits if bit]) == 1`, i.e. exactly 1 bit is set). - _[IGNORE]_ There has been no other valid attestation seen on an attestation subnet that has an identical `attestation.data.target.epoch` and participating validator index. diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 493f96f1d..ed01af6eb 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -593,8 +593,10 @@ def get_committee_count_delta(state: BeaconState, start_slot: Slot, stop_slot: S """ Return the sum of committee counts in range ``[start_slot, stop_slot)``. """ - return sum(get_committee_count_per_slot(state, compute_epoch_at_slot(Slot(slot))) - for slot in range(start_slot, stop_slot)) + return sum( + get_committee_count_per_slot(state, compute_epoch_at_slot(Slot(slot))) + for slot in range(start_slot, stop_slot) + ) ``` #### `get_start_shard` From db81f88c4ef1bfda8471f7e29f13f3e3c0236fea Mon Sep 17 00:00:00 2001 From: terence tsao Date: Thu, 18 Jun 2020 10:59:37 -0700 Subject: [PATCH 22/23] Update beacon-chain.md --- specs/phase1/beacon-chain.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index ed01af6eb..4542858fb 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -901,7 +901,7 @@ def process_crosslink_for_shard(state: BeaconState, assert shard_transition_root == hash_tree_root(shard_transition) # Apply transition - apply_shard_transition(state, attestation.data.shard, shard_transition) + apply_shard_transition(state, attestations[0].data.shard, shard_transition) # Apply proposer reward and cost beacon_proposer_index = get_beacon_proposer_index(state) estimated_attester_reward = sum([get_base_reward(state, attester) for attester in transition_participants]) @@ -909,11 +909,11 @@ def process_crosslink_for_shard(state: BeaconState, increase_balance(state, beacon_proposer_index, proposer_reward) states_slots_lengths = zip( shard_transition.shard_states, - get_offset_slots(state, attestation.data.shard), + get_offset_slots(state, attestations[0].data.shard), shard_transition.shard_block_lengths ) for shard_state, slot, length in states_slots_lengths: - proposer_index = get_shard_proposer_index(state, slot, attestation.data.shard) + proposer_index = get_shard_proposer_index(state, slot, attestations[0].data.shard) decrease_balance(state, proposer_index, shard_state.gasprice * length) # Return winning transition root From 3888dc27a9fe936027da6a2a4f926b81459d7e0f Mon Sep 17 00:00:00 2001 From: terence tsao Date: Thu, 18 Jun 2020 12:39:48 -0700 Subject: [PATCH 23/23] @djrtwo's feedback --- specs/phase1/beacon-chain.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/specs/phase1/beacon-chain.md b/specs/phase1/beacon-chain.md index 4542858fb..a1a940adf 100644 --- a/specs/phase1/beacon-chain.md +++ b/specs/phase1/beacon-chain.md @@ -876,6 +876,7 @@ def process_crosslink_for_shard(state: BeaconState, on_time_attestation_slot = compute_previous_slot(state.slot) committee = get_beacon_committee(state, on_time_attestation_slot, committee_index) online_indices = get_online_validator_indices(state) + shard = compute_shard_from_committee_index(state, committee_index, on_time_attestation_slot) # Loop over all shard transition roots shard_transition_roots = set([a.data.shard_transition_root for a in attestations]) @@ -901,7 +902,7 @@ def process_crosslink_for_shard(state: BeaconState, assert shard_transition_root == hash_tree_root(shard_transition) # Apply transition - apply_shard_transition(state, attestations[0].data.shard, shard_transition) + apply_shard_transition(state, shard, shard_transition) # Apply proposer reward and cost beacon_proposer_index = get_beacon_proposer_index(state) estimated_attester_reward = sum([get_base_reward(state, attester) for attester in transition_participants]) @@ -909,11 +910,11 @@ def process_crosslink_for_shard(state: BeaconState, increase_balance(state, beacon_proposer_index, proposer_reward) states_slots_lengths = zip( shard_transition.shard_states, - get_offset_slots(state, attestations[0].data.shard), + get_offset_slots(state, shard), shard_transition.shard_block_lengths ) for shard_state, slot, length in states_slots_lengths: - proposer_index = get_shard_proposer_index(state, slot, attestations[0].data.shard) + proposer_index = get_shard_proposer_index(state, slot, shard) decrease_balance(state, proposer_index, shard_state.gasprice * length) # Return winning transition root