working through phase 0 tests after crosslink/shard removal
This commit is contained in:
parent
dfdf3ab5cf
commit
b3b9b434b4
|
@ -84,7 +84,6 @@
|
|||
- [`get_committee_count`](#get_committee_count)
|
||||
- [`get_crosslink_committee`](#get_crosslink_committee)
|
||||
- [`get_beacon_proposer_index`](#get_beacon_proposer_index)
|
||||
- [`get_attestation_data_slot`](#get_attestation_data_slot)
|
||||
- [`get_total_balance`](#get_total_balance)
|
||||
- [`get_total_active_balance`](#get_total_active_balance)
|
||||
- [`get_domain`](#get_domain)
|
||||
|
|
|
@ -53,6 +53,7 @@ This document describes the shard transition function (data layer only) and the
|
|||
|
||||
| Name | SSZ equivalent | Description |
|
||||
| - | - | - |
|
||||
| `Shard` | `uint64` | a shard number |
|
||||
| `ShardSlot` | `uint64` | a shard slot number |
|
||||
|
||||
## Configuration
|
||||
|
@ -101,6 +102,14 @@ This document describes the shard transition function (data layer only) and the
|
|||
|
||||
## Containers
|
||||
|
||||
### `Crosslink`
|
||||
|
||||
```python
|
||||
class Crosslink(Container):
|
||||
# STUB: placeholder data structure while reworking phase 0
|
||||
shard: Shard
|
||||
```
|
||||
|
||||
### `ShardBlock`
|
||||
|
||||
```python
|
||||
|
|
|
@ -3,11 +3,10 @@ from typing import List
|
|||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
|
||||
from eth2spec.test.helpers.keys import privkeys
|
||||
from eth2spec.utils.bls import bls_sign, bls_aggregate_signatures
|
||||
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
||||
from eth2spec.utils.ssz.ssz_typing import Bitlist
|
||||
|
||||
|
||||
def build_attestation_data(spec, state, slot, shard):
|
||||
def build_attestation_data(spec, state, slot, index):
|
||||
assert state.slot >= slot
|
||||
|
||||
if slot == state.slot:
|
||||
|
@ -30,40 +29,27 @@ def build_attestation_data(spec, state, slot, shard):
|
|||
source_epoch = state.current_justified_checkpoint.epoch
|
||||
source_root = state.current_justified_checkpoint.root
|
||||
|
||||
if spec.compute_epoch_of_slot(slot) == spec.get_current_epoch(state):
|
||||
parent_crosslink = state.current_crosslinks[shard]
|
||||
else:
|
||||
parent_crosslink = state.previous_crosslinks[shard]
|
||||
|
||||
return spec.AttestationData(
|
||||
slot=slot,
|
||||
beacon_block_root=block_root,
|
||||
source=spec.Checkpoint(epoch=source_epoch, root=source_root),
|
||||
target=spec.Checkpoint(epoch=spec.compute_epoch_of_slot(slot), root=epoch_boundary_root),
|
||||
crosslink=spec.Crosslink(
|
||||
shard=shard,
|
||||
start_epoch=parent_crosslink.end_epoch,
|
||||
end_epoch=min(spec.compute_epoch_of_slot(slot), parent_crosslink.end_epoch + spec.MAX_EPOCHS_PER_CROSSLINK),
|
||||
data_root=spec.Hash(),
|
||||
parent_root=hash_tree_root(parent_crosslink),
|
||||
),
|
||||
index=index,
|
||||
)
|
||||
|
||||
|
||||
def get_valid_attestation(spec, state, slot=None, signed=False):
|
||||
def get_valid_attestation(spec, state, slot=None, index=None, signed=False):
|
||||
if slot is None:
|
||||
slot = state.slot
|
||||
if index is None:
|
||||
index = 0
|
||||
|
||||
epoch = spec.compute_epoch_of_slot(slot)
|
||||
epoch_start_shard = spec.get_start_shard(state, epoch)
|
||||
committees_per_slot = spec.get_committee_count(state, epoch) // spec.SLOTS_PER_EPOCH
|
||||
shard = (epoch_start_shard + committees_per_slot * (slot % spec.SLOTS_PER_EPOCH)) % spec.SHARD_COUNT
|
||||
|
||||
attestation_data = build_attestation_data(spec, state, slot, shard)
|
||||
attestation_data = build_attestation_data(spec, state, slot, index)
|
||||
|
||||
crosslink_committee = spec.get_crosslink_committee(
|
||||
state,
|
||||
attestation_data.target.epoch,
|
||||
attestation_data.crosslink.shard,
|
||||
attestation_data.index,
|
||||
)
|
||||
|
||||
committee_size = len(crosslink_committee)
|
||||
|
@ -132,7 +118,7 @@ def fill_aggregate_attestation(spec, state, attestation):
|
|||
crosslink_committee = spec.get_crosslink_committee(
|
||||
state,
|
||||
attestation.data.target.epoch,
|
||||
attestation.data.crosslink.shard,
|
||||
attestation.data.index,
|
||||
)
|
||||
for i in range(len(crosslink_committee)):
|
||||
attestation.aggregation_bits[i] = True
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
from eth2spec.test.context import spec_state_test, expect_assertion_error, always_bls, with_all_phases, with_phases
|
||||
from eth2spec.test.context import (
|
||||
spec_state_test,
|
||||
expect_assertion_error,
|
||||
always_bls, never_bls,
|
||||
with_all_phases, with_phases,
|
||||
)
|
||||
from eth2spec.test.helpers.attestations import (
|
||||
get_valid_attestation,
|
||||
sign_aggregate_attestation,
|
||||
|
@ -6,7 +11,6 @@ from eth2spec.test.helpers.attestations import (
|
|||
)
|
||||
from eth2spec.test.helpers.state import (
|
||||
next_epoch,
|
||||
next_slot,
|
||||
)
|
||||
from eth2spec.test.helpers.block import apply_empty_block
|
||||
from eth2spec.utils.ssz.ssz_typing import Bitlist
|
||||
|
@ -67,54 +71,6 @@ def test_success_previous_epoch(spec, state):
|
|||
yield from run_attestation_processing(spec, state, attestation)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_success_since_max_epochs_per_crosslink(spec, state):
|
||||
# Do not run mainnet (64 epochs), that would mean the equivalent of ~7 hours chain simulation.
|
||||
if spec.MAX_EPOCHS_PER_CROSSLINK > 4:
|
||||
return
|
||||
for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2):
|
||||
next_epoch(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state, signed=True)
|
||||
data = attestation.data
|
||||
# test logic sanity check: make sure the attestation only includes MAX_EPOCHS_PER_CROSSLINK epochs
|
||||
assert data.crosslink.end_epoch - data.crosslink.start_epoch == spec.MAX_EPOCHS_PER_CROSSLINK
|
||||
|
||||
for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY):
|
||||
next_slot(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_wrong_end_epoch_with_max_epochs_per_crosslink(spec, state):
|
||||
# Do not run mainnet (64 epochs), that would mean the equivalent of ~7 hours chain simulation.
|
||||
if spec.MAX_EPOCHS_PER_CROSSLINK > 4:
|
||||
return
|
||||
for _ in range(spec.MAX_EPOCHS_PER_CROSSLINK + 2):
|
||||
next_epoch(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state)
|
||||
data = attestation.data
|
||||
# test logic sanity check: make sure the attestation only includes MAX_EPOCHS_PER_CROSSLINK epochs
|
||||
assert data.crosslink.end_epoch - data.crosslink.start_epoch == spec.MAX_EPOCHS_PER_CROSSLINK
|
||||
# Now change it to be different
|
||||
data.crosslink.end_epoch += 1
|
||||
|
||||
sign_attestation(spec, state, attestation)
|
||||
|
||||
for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY):
|
||||
next_slot(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
@always_bls
|
||||
|
@ -168,27 +124,13 @@ def test_old_source_epoch(spec, state):
|
|||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_wrong_shard(spec, state):
|
||||
attestation = get_valid_attestation(spec, state)
|
||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||
|
||||
attestation.data.crosslink.shard += 1
|
||||
|
||||
sign_attestation(spec, state, attestation)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_invalid_shard(spec, state):
|
||||
@never_bls
|
||||
def test_invalid_index(spec, state):
|
||||
attestation = get_valid_attestation(spec, state)
|
||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||
|
||||
# off by one (with respect to valid range) on purpose
|
||||
attestation.data.crosslink.shard = spec.SHARD_COUNT
|
||||
|
||||
sign_attestation(spec, state, attestation)
|
||||
attestation.data.index = spec.COMMITTEES_PER_SLOT
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
@ -290,73 +232,6 @@ def test_bad_source_root(spec, state):
|
|||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_phases(['phase0'])
|
||||
@spec_state_test
|
||||
def test_non_zero_crosslink_data_root(spec, state):
|
||||
attestation = get_valid_attestation(spec, state)
|
||||
state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY
|
||||
|
||||
attestation.data.crosslink.data_root = b'\x42' * 32
|
||||
|
||||
sign_attestation(spec, state, attestation)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_bad_parent_crosslink(spec, state):
|
||||
state.slot = spec.SLOTS_PER_EPOCH - 1
|
||||
next_epoch(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state, signed=False)
|
||||
for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY):
|
||||
next_slot(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation.data.crosslink.parent_root = b'\x27' * 32
|
||||
sign_attestation(spec, state, attestation)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_bad_crosslink_start_epoch(spec, state):
|
||||
state.slot = spec.SLOTS_PER_EPOCH - 1
|
||||
next_epoch(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state, signed=False)
|
||||
for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY):
|
||||
next_slot(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation.data.crosslink.start_epoch += 1
|
||||
sign_attestation(spec, state, attestation)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_bad_crosslink_end_epoch(spec, state):
|
||||
state.slot = spec.SLOTS_PER_EPOCH - 1
|
||||
next_epoch(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state, signed=False)
|
||||
for _ in range(spec.MIN_ATTESTATION_INCLUSION_DELAY):
|
||||
next_slot(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
attestation.data.crosslink.end_epoch += 1
|
||||
sign_attestation(spec, state, attestation)
|
||||
|
||||
yield from run_attestation_processing(spec, state, attestation, False)
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_inconsistent_bits(spec, state):
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
from copy import deepcopy
|
||||
|
||||
from eth2spec.test.context import spec_state_test, with_all_phases
|
||||
from eth2spec.test.helpers.state import (
|
||||
next_epoch,
|
||||
next_slot
|
||||
)
|
||||
from eth2spec.test.helpers.block import apply_empty_block
|
||||
from eth2spec.test.helpers.attestations import (
|
||||
add_attestation_to_state,
|
||||
fill_aggregate_attestation,
|
||||
get_valid_attestation,
|
||||
sign_attestation,
|
||||
)
|
||||
from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with
|
||||
|
||||
|
||||
def run_process_crosslinks(spec, state):
|
||||
yield from run_epoch_processing_with(spec, state, 'process_crosslinks')
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_no_attestations(spec, state):
|
||||
yield from run_process_crosslinks(spec, state)
|
||||
|
||||
for shard in range(spec.SHARD_COUNT):
|
||||
assert state.previous_crosslinks[shard] == state.current_crosslinks[shard]
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_single_crosslink_update_from_current_epoch(spec, state):
|
||||
next_epoch(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state, signed=True)
|
||||
|
||||
fill_aggregate_attestation(spec, state, attestation)
|
||||
add_attestation_to_state(spec, state, attestation, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
|
||||
|
||||
assert len(state.current_epoch_attestations) == 1
|
||||
|
||||
shard = attestation.data.crosslink.shard
|
||||
pre_crosslink = deepcopy(state.current_crosslinks[shard])
|
||||
|
||||
yield from run_process_crosslinks(spec, state)
|
||||
|
||||
assert state.previous_crosslinks[shard] != state.current_crosslinks[shard]
|
||||
assert pre_crosslink != state.current_crosslinks[shard]
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_single_crosslink_update_from_previous_epoch(spec, state):
|
||||
next_epoch(spec, state)
|
||||
|
||||
attestation = get_valid_attestation(spec, state, signed=True)
|
||||
|
||||
fill_aggregate_attestation(spec, state, attestation)
|
||||
add_attestation_to_state(spec, state, attestation, state.slot + spec.SLOTS_PER_EPOCH)
|
||||
|
||||
assert len(state.previous_epoch_attestations) == 1
|
||||
|
||||
shard = attestation.data.crosslink.shard
|
||||
pre_crosslink = deepcopy(state.current_crosslinks[shard])
|
||||
|
||||
crosslink_deltas = spec.get_crosslink_deltas(state)
|
||||
|
||||
yield from run_process_crosslinks(spec, state)
|
||||
|
||||
assert state.previous_crosslinks[shard] != state.current_crosslinks[shard]
|
||||
assert pre_crosslink != state.current_crosslinks[shard]
|
||||
|
||||
# ensure rewarded
|
||||
for index in spec.get_crosslink_committee(
|
||||
state,
|
||||
attestation.data.target.epoch,
|
||||
attestation.data.crosslink.shard):
|
||||
assert crosslink_deltas[0][index] > 0
|
||||
assert crosslink_deltas[1][index] == 0
|
||||
|
||||
|
||||
@with_all_phases
|
||||
@spec_state_test
|
||||
def test_double_late_crosslink(spec, state):
|
||||
if spec.get_committee_count(state, spec.get_current_epoch(state)) < spec.SHARD_COUNT:
|
||||
print("warning: ignoring test, test-assumptions are incompatible with configuration")
|
||||
return
|
||||
|
||||
next_epoch(spec, state)
|
||||
state.slot += 4
|
||||
|
||||
attestation_1 = get_valid_attestation(spec, state, signed=True)
|
||||
fill_aggregate_attestation(spec, state, attestation_1)
|
||||
|
||||
# add attestation_1 to next epoch
|
||||
next_epoch(spec, state)
|
||||
add_attestation_to_state(spec, state, attestation_1, state.slot + 1)
|
||||
|
||||
for _ in range(spec.SLOTS_PER_EPOCH):
|
||||
attestation_2 = get_valid_attestation(spec, state)
|
||||
if attestation_2.data.crosslink.shard == attestation_1.data.crosslink.shard:
|
||||
sign_attestation(spec, state, attestation_2)
|
||||
break
|
||||
next_slot(spec, state)
|
||||
apply_empty_block(spec, state)
|
||||
|
||||
fill_aggregate_attestation(spec, state, attestation_2)
|
||||
|
||||
# add attestation_2 in the next epoch after attestation_1 has
|
||||
# already updated the relevant crosslink
|
||||
next_epoch(spec, state)
|
||||
add_attestation_to_state(spec, state, attestation_2, state.slot + 1)
|
||||
|
||||
assert len(state.previous_epoch_attestations) == 1
|
||||
assert len(state.current_epoch_attestations) == 0
|
||||
|
||||
crosslink_deltas = spec.get_crosslink_deltas(state)
|
||||
|
||||
yield from run_process_crosslinks(spec, state)
|
||||
|
||||
shard = attestation_2.data.crosslink.shard
|
||||
|
||||
# ensure that the current crosslinks were not updated by the second attestation
|
||||
assert state.previous_crosslinks[shard] == state.current_crosslinks[shard]
|
||||
# ensure no reward, only penalties for the failed crosslink
|
||||
for index in spec.get_crosslink_committee(
|
||||
state,
|
||||
attestation_2.data.target.epoch,
|
||||
attestation_2.data.crosslink.shard):
|
||||
assert crosslink_deltas[0][index] == 0
|
||||
assert crosslink_deltas[1][index] > 0
|
Loading…
Reference in New Issue