test_process_rewards_and_penalties.py: test for case when eligible_validator_indices in get_attestation_deltas() != state.validators. In this test some validators were just never active.

This commit is contained in:
Denis Bogdanas 2019-10-06 19:55:27 +03:00
parent c108d1a356
commit 1a65570c9b
4 changed files with 91 additions and 4 deletions

View File

@ -2,7 +2,7 @@ from eth2spec.phase0 import spec as spec_phase0
from eth2spec.phase1 import spec as spec_phase1
from eth2spec.utils import bls
from .helpers.genesis import create_genesis_state
from .helpers.genesis import create_genesis_state, create_genesis_state_misc_balances
from .utils import vector_test, with_meta_tags
@ -29,6 +29,18 @@ def with_state_low_balance(fn):
return entry
def with_state_misc_balances(fn):
def entry(*args, **kw):
try:
validator_balances = [spec_phase0.MAX_EFFECTIVE_BALANCE] * (spec_phase0.SLOTS_PER_EPOCH * 8) + [
spec_phase0.MIN_DEPOSIT_AMOUNT] * spec_phase0.SLOTS_PER_EPOCH
kw['state'] = create_genesis_state_misc_balances(spec=kw['spec'], validator_balances=validator_balances)
except KeyError:
raise TypeError('Spec decorator must come within state decorator to inject spec into state.')
return fn(*args, **kw)
return entry
# BLS is turned off by default *for performance purposes during TESTING*.
# The runner of the test can indicate the preferred setting (test generators prefer BLS to be ON).
# - Some tests are marked as BLS-requiring, and ignore this setting.
@ -57,6 +69,10 @@ def spec_state_low_balance_test(fn):
return spec_test(with_state_low_balance(fn))
def spec_state_misc_balances_test(fn):
return spec_test(with_state_misc_balances(fn))
def expect_assertion_error(fn):
bad = False
try:

View File

@ -1,6 +1,7 @@
from eth2spec.test.helpers.keys import pubkeys
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
from eth2spec.utils.ssz.ssz_typing import List
import copy
def build_mock_validator(spec, i: int, balance: int):
@ -52,3 +53,39 @@ def create_genesis_state(spec, num_validators, validator_balance):
state.compact_committees_roots[index] = genesis_compact_committees_root
return state
def create_genesis_state_misc_balances(spec, validator_balances):
deposit_root = b'\x42' * 32
state = spec.BeaconState(
genesis_time=0,
eth1_deposit_index=len(validator_balances),
eth1_data=spec.Eth1Data(
deposit_root=deposit_root,
deposit_count=len(validator_balances),
block_hash=spec.Hash(),
),
latest_block_header=spec.BeaconBlockHeader(body_root=spec.hash_tree_root(spec.BeaconBlockBody())),
)
# We "hack" in the initial validators,
# as it is much faster than creating and processing genesis deposits for every single test case.
state.balances = copy.deepcopy(validator_balances)
state.validators = [build_mock_validator(spec, i, state.balances[i]) for i in range(len(validator_balances))]
# Process genesis activations
for validator in state.validators:
if validator.effective_balance > spec.EJECTION_BALANCE:
validator.activation_eligibility_epoch = spec.GENESIS_EPOCH
validator.activation_epoch = spec.GENESIS_EPOCH
genesis_active_index_root = hash_tree_root(List[spec.ValidatorIndex, spec.VALIDATOR_REGISTRY_LIMIT](
spec.get_active_validator_indices(state, spec.GENESIS_EPOCH)))
genesis_compact_committees_root = hash_tree_root(List[spec.ValidatorIndex, spec.VALIDATOR_REGISTRY_LIMIT](
spec.get_active_validator_indices(state, spec.GENESIS_EPOCH)))
for index in range(spec.EPOCHS_PER_HISTORICAL_VECTOR):
state.active_index_roots[index] = genesis_active_index_root
state.compact_committees_roots[index] = genesis_compact_committees_root
return state

View File

@ -1,6 +1,6 @@
from copy import deepcopy
from eth2spec.test.context import spec_state_test, with_all_phases
from eth2spec.test.context import spec_state_test, spec_state_misc_balances_test, with_all_phases
from eth2spec.test.helpers.state import (
next_epoch,
next_slot,
@ -86,6 +86,40 @@ def test_full_attestations(spec, state):
assert state.balances[index] < pre_state.balances[index]
@with_all_phases
@spec_state_misc_balances_test
def test_full_attestations_misc_balances(spec, state):
attestations = []
for slot in range(spec.SLOTS_PER_EPOCH + spec.MIN_ATTESTATION_INCLUSION_DELAY):
# create an attestation for each slot in epoch
if slot < spec.SLOTS_PER_EPOCH:
attestation = get_valid_attestation(spec, state, signed=True)
attestations.append(attestation)
# fill each created slot in state after inclusion delay
if slot - spec.MIN_ATTESTATION_INCLUSION_DELAY >= 0:
include_att = attestations[slot - spec.MIN_ATTESTATION_INCLUSION_DELAY]
add_attestations_to_state(spec, state, [include_att], state.slot)
next_slot(spec, state)
assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH + 1
assert len(state.previous_epoch_attestations) == spec.SLOTS_PER_EPOCH
pre_state = deepcopy(state)
yield from run_process_rewards_and_penalties(spec, state)
attesting_indices = spec.get_unslashed_attesting_indices(state, attestations)
assert len(attesting_indices) > 0
assert len(attesting_indices) != len(pre_state.validators)
for index in range(len(pre_state.validators)):
if index in attesting_indices:
assert state.balances[index] > pre_state.balances[index]
elif spec.is_active_validator(pre_state.validators[index], spec.compute_epoch_of_slot(state.slot)):
assert state.balances[index] < pre_state.balances[index]
else:
assert state.balances[index] == pre_state.balances[index]
@with_all_phases
@spec_state_test
def test_no_attestations_all_penalties(spec, state):