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:
parent
c108d1a356
commit
1a65570c9b
|
@ -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:
|
||||
|
|
|
@ -36,7 +36,7 @@ def test_initialize_beacon_state_from_eth1(spec):
|
|||
def test_initialize_beacon_state_some_small_balances(spec):
|
||||
main_deposit_count = spec.MIN_GENESIS_ACTIVE_VALIDATOR_COUNT
|
||||
main_deposits, _, deposit_data_list = prepare_genesis_deposits(spec, main_deposit_count,
|
||||
spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
spec.MAX_EFFECTIVE_BALANCE, signed=True)
|
||||
# For deposits above, and for another deposit_count, add a balance of EFFECTIVE_BALANCE_INCREMENT
|
||||
small_deposit_count = main_deposit_count * 2
|
||||
small_deposits, deposit_root, _ = prepare_genesis_deposits(spec, small_deposit_count,
|
||||
|
@ -64,4 +64,4 @@ def test_initialize_beacon_state_some_small_balances(spec):
|
|||
assert spec.get_total_active_balance(state) == main_deposit_count * spec.MAX_EFFECTIVE_BALANCE
|
||||
|
||||
# yield state
|
||||
yield 'state', state
|
||||
yield 'state', state
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
Loading…
Reference in New Issue