working through test issues

This commit is contained in:
Danny Ryan 2020-02-22 09:21:39 -06:00
parent ceb6633eb9
commit 97fa3741af
No known key found for this signature in database
GPG Key ID: 2765A792E42CE07A
8 changed files with 135 additions and 51 deletions

View File

@ -622,8 +622,7 @@ def validate_attestation(state: BeaconState, attestation: Attestation) -> None:
# Type 2: no shard transition, no custody bits # TODO: could only allow for older attestations. # Type 2: no shard transition, no custody bits # TODO: could only allow for older attestations.
else: else:
# Ensure delayed attestation # Ensure delayed attestation
# Currently commented out because breaks a ton of phase 0 tests assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY < state.slot
# assert data.slot + MIN_ATTESTATION_INCLUSION_DELAY < state.slot
# Late attestations cannot have a shard transition root # Late attestations cannot have a shard transition root
assert data.shard_transition_root == Root() assert data.shard_transition_root == Root()

View File

@ -1,9 +1,8 @@
from eth2spec.test.context import with_all_phases, spec_state_test from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.attestations import get_valid_attestation from eth2spec.test.helpers.attestations import get_valid_attestation, next_epoch_with_attestations
from eth2spec.test.helpers.block import build_empty_block_for_next_slot from eth2spec.test.helpers.block import build_empty_block_for_next_slot
from eth2spec.test.helpers.state import ( from eth2spec.test.helpers.state import (
next_epoch, next_epoch,
next_epoch_with_attestations,
state_transition_and_sign_block, state_transition_and_sign_block,
) )

View File

@ -4,7 +4,8 @@ from eth2spec.utils.ssz.ssz_impl import hash_tree_root
from eth2spec.test.context import with_all_phases, spec_state_test from eth2spec.test.context import with_all_phases, spec_state_test
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block, transition_unsigned_block, \ from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block, transition_unsigned_block, \
build_empty_block build_empty_block
from eth2spec.test.helpers.state import next_epoch, next_epoch_with_attestations, state_transition_and_sign_block from eth2spec.test.helpers.attestations import next_epoch_with_attestations
from eth2spec.test.helpers.state import next_epoch, state_transition_and_sign_block
def run_on_block(spec, store, signed_block, valid=True): def run_on_block(spec, store, signed_block, valid=True):

View File

@ -1,7 +1,8 @@
from typing import List from typing import List
from eth2spec.test.helpers.block import build_empty_block_for_next_slot
from eth2spec.test.context import expect_assertion_error from eth2spec.test.context import expect_assertion_error
from eth2spec.test.helpers.state import next_slot, state_transition_and_sign_block
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, transition_unsigned_block
from eth2spec.test.helpers.keys import privkeys from eth2spec.test.helpers.keys import privkeys
from eth2spec.utils import bls from eth2spec.utils import bls
from eth2spec.utils.ssz.ssz_typing import Bitlist from eth2spec.utils.ssz.ssz_typing import Bitlist
@ -74,7 +75,48 @@ def build_attestation_data(spec, state, slot, index):
) )
def get_valid_attestation(spec, state, slot=None, index=None, signed=False): def convert_to_valid_on_time_attestation(spec, state, attestation, signed=False):
shard = spec.get_shard(state, attestation)
next_state = state.copy()
next_slot(spec, next_state)
offset_slots = spec.get_offset_slots(next_state, spec.get_next_slot_for_shard(next_state, shard))
for offset_slot in offset_slots:
attestation.custody_bits_blocks.append(
Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE]([0 for _ in attestation.aggregation_bits])
)
if signed:
sign_attestation(spec, state, attestation)
return attestation
def get_valid_on_time_attestation(spec, state, slot=None, index=None, signed=False):
'''
Construct on-time attestation for next slot
'''
if slot is None:
slot = state.slot
if index is None:
index = 0
return get_valid_attestation(spec, state, slot, index, signed, True)
def get_valid_late_attestation(spec, state, slot=None, index=None, signed=False):
'''
Construct on-time attestation for next slot
'''
if slot is None:
slot = state.slot
if index is None:
index = 0
return get_valid_attestation(spec, state, slot, index, signed, False)
def get_valid_attestation(spec, state, slot=None, index=None, signed=False, on_time=True):
if slot is None: if slot is None:
slot = state.slot slot = state.slot
if index is None: if index is None:
@ -97,6 +139,10 @@ def get_valid_attestation(spec, state, slot=None, index=None, signed=False):
fill_aggregate_attestation(spec, state, attestation) fill_aggregate_attestation(spec, state, attestation)
if signed: if signed:
sign_attestation(spec, state, attestation) sign_attestation(spec, state, attestation)
if spec.fork == 'phase1' and on_time:
attestation = convert_to_valid_on_time_attestation(spec, state, attestation, signed)
return attestation return attestation
@ -112,7 +158,6 @@ def sign_aggregate_attestation(spec, state, attestation_data, participants: List
privkey privkey
) )
) )
# TODO: we should try signing custody bits if spec.fork == 'phase1'
return bls.Aggregate(signatures) return bls.Aggregate(signatures)
@ -130,7 +175,47 @@ def sign_indexed_attestation(spec, state, indexed_attestation):
indexed_attestation.attestation.signature = sign_aggregate_attestation(spec, state, data, participants) indexed_attestation.attestation.signature = sign_aggregate_attestation(spec, state, data, participants)
def sign_on_time_attestation(spec, state, attestation):
if not any(attestation.custody_bits_blocks):
sign_attestation(spec, state, attestation)
return
committee = spec.get_beacon_committee(state, attestation.data.slot, attestation.data.index)
signatures = []
for block_index, custody_bits in enumerate(attestation.custody_bits_blocks):
for participant, abit, cbit in zip(committee, attestation.aggregation_bits, custody_bits):
if not abit:
continue
signatures.append(get_attestation_custody_signature(
spec,
state,
attestation.data,
block_index,
cbit,
privkeys[participant]
))
attestation.signature = bls.Aggregate(signatures)
def get_attestation_custody_signature(spec, state, attestation_data, block_index, bit, privkey):
domain = spec.get_domain(state, spec.DOMAIN_BEACON_ATTESTER, attestation_data.target.epoch)
signing_root = spec.compute_signing_root(
spec.AttestationCustodyBitWrapper(
attestation_data.hash_tree_root(),
block_index,
bit,
),
domain,
)
return bls.Sign(privkey, signing_root)
def sign_attestation(spec, state, attestation): def sign_attestation(spec, state, attestation):
if spec.fork == 'phase1' and any(attestation.custody_bits_blocks):
sign_on_time_attestation(spec, state,attestation)
return
participants = spec.get_attesting_indices( participants = spec.get_attesting_indices(
state, state,
attestation.data, attestation.data,
@ -163,3 +248,35 @@ def add_attestations_to_state(spec, state, attestations, slot):
spec.process_slots(state, slot) spec.process_slots(state, slot)
for attestation in attestations: for attestation in attestations:
spec.process_attestation(state, attestation) spec.process_attestation(state, attestation)
def next_epoch_with_attestations(spec,
state,
fill_cur_epoch,
fill_prev_epoch):
assert state.slot % spec.SLOTS_PER_EPOCH == 0
post_state = state.copy()
signed_blocks = []
for _ in range(spec.SLOTS_PER_EPOCH):
block = build_empty_block_for_next_slot(spec, post_state)
if fill_cur_epoch and post_state.slot >= spec.MIN_ATTESTATION_INCLUSION_DELAY:
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)
if slot_to_attest >= spec.compute_start_slot_at_epoch(spec.get_current_epoch(post_state)):
for index in range(committees_per_slot):
cur_attestation = get_valid_attestation(spec, post_state, slot_to_attest, index=index, signed=True)
block.body.attestations.append(cur_attestation)
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)
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)
block.body.attestations.append(prev_attestation)
signed_block = state_transition_and_sign_block(spec, post_state, block)
signed_blocks.append(signed_block)
return state, signed_blocks, post_state

View File

@ -1,5 +1,4 @@
from eth2spec.test.context import expect_assertion_error from eth2spec.test.context import expect_assertion_error
from eth2spec.test.helpers.attestations import get_valid_attestation
from eth2spec.test.helpers.block import sign_block, build_empty_block_for_next_slot, transition_unsigned_block from eth2spec.test.helpers.block import sign_block, build_empty_block_for_next_slot, transition_unsigned_block
@ -58,34 +57,3 @@ def state_transition_and_sign_block(spec, state, block, expect_fail=False):
transition_unsigned_block(spec, state, block) transition_unsigned_block(spec, state, block)
block.state_root = state.hash_tree_root() block.state_root = state.hash_tree_root()
return sign_block(spec, state, block) return sign_block(spec, state, block)
def next_epoch_with_attestations(spec,
state,
fill_cur_epoch,
fill_prev_epoch):
assert state.slot % spec.SLOTS_PER_EPOCH == 0
post_state = state.copy()
signed_blocks = []
for _ in range(spec.SLOTS_PER_EPOCH):
block = build_empty_block_for_next_slot(spec, post_state)
if fill_cur_epoch and post_state.slot >= spec.MIN_ATTESTATION_INCLUSION_DELAY:
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)
if slot_to_attest >= spec.compute_start_slot_at_epoch(spec.get_current_epoch(post_state)):
for index in range(committees_per_slot):
cur_attestation = get_valid_attestation(spec, post_state, slot_to_attest, index=index, signed=True)
block.body.attestations.append(cur_attestation)
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)
for index in range(committees_per_slot):
prev_attestation = get_valid_attestation(spec, post_state, slot_to_attest, index=index, signed=True)
block.body.attestations.append(prev_attestation)
signed_block = state_transition_and_sign_block(spec, post_state, block)
signed_blocks.append(signed_block)
return state, signed_blocks, post_state

View File

@ -13,7 +13,10 @@ from eth2spec.test.helpers.attestations import (
sign_attestation, sign_attestation,
) )
from eth2spec.test.helpers.state import ( from eth2spec.test.helpers.state import (
next_epoch, next_slots next_epoch,
next_slots,
next_slot,
next_epoch,
) )
from eth2spec.test.helpers.block import apply_empty_block from eth2spec.test.helpers.block import apply_empty_block
from eth2spec.utils.ssz.ssz_typing import Bitlist from eth2spec.utils.ssz.ssz_typing import Bitlist
@ -166,7 +169,7 @@ def test_old_target_epoch(spec, state):
attestation = get_valid_attestation(spec, state, signed=True) attestation = get_valid_attestation(spec, state, signed=True)
state.slot = spec.SLOTS_PER_EPOCH * 2 # target epoch will be too old to handle transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 2) # target epoch will be too old to handle
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, False)
@ -222,7 +225,8 @@ def test_source_root_is_target_root(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_invalid_current_source_root(spec, state): def test_invalid_current_source_root(spec, state):
state.slot = spec.SLOTS_PER_EPOCH * 5 transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH * 5)
state.finalized_checkpoint.epoch = 2 state.finalized_checkpoint.epoch = 2
state.previous_justified_checkpoint = spec.Checkpoint(epoch=3, root=b'\x01' * 32) state.previous_justified_checkpoint = spec.Checkpoint(epoch=3, root=b'\x01' * 32)
@ -259,6 +263,7 @@ def test_bad_source_root(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_empty_aggregation_bits(spec, state): def test_empty_aggregation_bits(spec, state):
next_slot(spec, state)
attestation = get_valid_attestation(spec, state) attestation = get_valid_attestation(spec, state)
next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY) next_slots(spec, state, spec.MIN_ATTESTATION_INCLUSION_DELAY)

View File

@ -6,9 +6,7 @@ from eth2spec.test.context import (
from eth2spec.test.helpers.state import next_slot, transition_to from eth2spec.test.helpers.state import next_slot, transition_to
from eth2spec.test.helpers.attestations import ( from eth2spec.test.helpers.attestations import (
run_attestation_processing, run_attestation_processing,
# get_valid_attestation as get_valid_late_attestation, get_valid_late_attestation,
)
from eth2spec.test.helpers.phase1.attestations import (
get_valid_on_time_attestation, get_valid_on_time_attestation,
) )
@ -29,9 +27,6 @@ def test_on_time_success(spec, state):
@spec_state_test @spec_state_test
@always_bls @always_bls
def test_on_time_empty_custody_bits_blocks(spec, state): def test_on_time_empty_custody_bits_blocks(spec, state):
# Causing this test to pass causes many phase0 tests to fail
pass
"""
next_slot(spec, state) next_slot(spec, state)
attestation = get_valid_late_attestation(spec, state, signed=True) attestation = get_valid_late_attestation(spec, state, signed=True)
@ -40,7 +35,6 @@ def test_on_time_empty_custody_bits_blocks(spec, state):
transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) transition_to(spec, state, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY)
yield from run_attestation_processing(spec, state, attestation, False) yield from run_attestation_processing(spec, state, attestation, False)
"""
@with_all_phases_except(['phase0']) @with_all_phases_except(['phase0'])

View File

@ -1,5 +1,6 @@
from eth2spec.test.context import spec_state_test, never_bls, with_all_phases from eth2spec.test.context import spec_state_test, never_bls, with_all_phases
from eth2spec.test.helpers.state import next_epoch, next_epoch_with_attestations from eth2spec.test.helpers.state import next_epoch
from eth2spec.test.helpers.attestations import next_epoch_with_attestations
from eth2spec.test.helpers.block import apply_empty_block from eth2spec.test.helpers.block import apply_empty_block