clean up epoch processing testing

This commit is contained in:
protolambda 2019-06-25 23:18:19 +02:00
parent c4c9bd32e2
commit aedd281edb
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623
2 changed files with 60 additions and 46 deletions

View File

@ -1,35 +1,29 @@
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
from eth2spec.test.helpers.state import state_transition_and_sign_block process_calls = [
'process_justification_and_finalization',
'process_crosslinks',
'process_rewards_and_penalties',
'process_registry_updates',
'process_reveal_deadlines',
'process_challenge_deadlines',
'process_slashings',
'process_final_updates',
'after_process_final_updates',
]
process_calls = ( def run_epoch_processing_to(spec, state, process_name: str, exclusive=False):
'process_justification_and_finalization'
'process_crosslinks'
'process_rewards_and_penalties'
'process_registry_updates'
'process_reveal_deadlines'
'process_challenge_deadlines'
'process_slashings'
'process_final_updates'
'after_process_final_updates'
)
def run_epoch_processing_to(spec, state, process_name: str):
""" """
Run the epoch processing functions up to ``process_name`` (incl.), yielding: Run the epoch processing functions up to ``process_name``.
If ``exclusive`` is True, the process itself will not be ran.
If ``exclusive`` is False (default), this function yields:
- pre-state ('pre'), state before calling ``process_name`` - pre-state ('pre'), state before calling ``process_name``
- post-state ('post'), state after calling ``process_name`` - post-state ('post'), state after calling ``process_name``
""" """
# transition state to slot before state transition slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH)
slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) - 1
block = build_empty_block_for_next_slot(spec, state)
block.slot = slot
sign_block(spec, state, block)
state_transition_and_sign_block(spec, state, block)
# cache state before epoch transition # transition state to slot before epoch state transition
spec.process_slot(state) spec.process_slots(state, slot)
# process components of epoch transition before final-updates # process components of epoch transition before final-updates
for name in process_calls: for name in process_calls:
@ -39,6 +33,7 @@ def run_epoch_processing_to(spec, state, process_name: str):
if hasattr(spec, name): if hasattr(spec, name):
getattr(spec, name)(state) getattr(spec, name)(state)
if not exclusive:
yield 'pre', state yield 'pre', state
getattr(spec, process_name)(state) getattr(spec, process_name)(state)
yield 'post', state yield 'post', state

View File

@ -10,8 +10,8 @@ def run_process_final_updates(spec, state):
@spec_state_test @spec_state_test
def test_eth1_vote_no_reset(spec, state): def test_eth1_vote_no_reset(spec, state):
assert spec.SLOTS_PER_ETH1_VOTING_PERIOD > spec.SLOTS_PER_EPOCH assert spec.SLOTS_PER_ETH1_VOTING_PERIOD > spec.SLOTS_PER_EPOCH
# skip ahead to near the end of the epoch # skip ahead to the end of the epoch
state.slot = spec.SLOTS_PER_EPOCH - 2 state.slot = spec.SLOTS_PER_EPOCH - 1
for i in range(state.slot + 1): # add a vote for each skipped slot. for i in range(state.slot + 1): # add a vote for each skipped slot.
state.eth1_data_votes.append( state.eth1_data_votes.append(
spec.Eth1Data(deposit_root=b'\xaa' * 32, spec.Eth1Data(deposit_root=b'\xaa' * 32,
@ -26,8 +26,8 @@ def test_eth1_vote_no_reset(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_eth1_vote_reset(spec, state): def test_eth1_vote_reset(spec, state):
# skip ahead to near the end of the voting period # skip ahead to the end of the voting period
state.slot = spec.SLOTS_PER_ETH1_VOTING_PERIOD - 2 state.slot = spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1
for i in range(state.slot + 1): # add a vote for each skipped slot. for i in range(state.slot + 1): # add a vote for each skipped slot.
state.eth1_data_votes.append( state.eth1_data_votes.append(
spec.Eth1Data(deposit_root=b'\xaa' * 32, spec.Eth1Data(deposit_root=b'\xaa' * 32,
@ -42,29 +42,48 @@ def test_eth1_vote_reset(spec, state):
@with_all_phases @with_all_phases
@spec_state_test @spec_state_test
def test_effective_balance_hysteresis(spec, state): def test_effective_balance_hysteresis(spec, state):
# Prepare state up to the final-updates.
# Then overwrite the balances, we only want to focus to be on the hysteresis based changes.
run_epoch_processing_to(spec, state, 'process_final_updates')
# Set some edge cases for balances # Set some edge cases for balances
max = spec.MAX_EFFECTIVE_BALANCE max = spec.MAX_EFFECTIVE_BALANCE
min = spec.EJECTION_BALANCE min = spec.EJECTION_BALANCE
inc = spec.EFFECTIVE_BALANCE_INCREMENT inc = spec.EFFECTIVE_BALANCE_INCREMENT
half_inc = inc // 2 half_inc = inc // 2
cases = [ cases = [
(max, max, max), # as is (max, max, max, "as-is"),
(max, max - 1, max - inc), # round down, step lower (max, max - 1, max - inc, "round down, step lower"),
(max, max + 1, max), # round down (max, max + 1, max, "round down"),
(max, max - inc, max - inc), # exactly 1 step lower (max, max - inc, max - inc, "exactly 1 step lower"),
(max, max - inc - 1, max - (2 * inc)), # just 1 over 1 step lower (max, max - inc - 1, max - (2 * inc), "just 1 over 1 step lower"),
(max, max - inc + 1, max - inc), # close to 1 step lower (max, max - inc + 1, max - inc, "close to 1 step lower"),
(min, min + (half_inc * 3), min), # bigger balance, but not high enough (min, min + (half_inc * 3), min, "bigger balance, but not high enough"),
(min, min + (half_inc * 3) + 1, min + inc), # bigger balance, high enough, but small step (min, min + (half_inc * 3) + 1, min + inc, "bigger balance, high enough, but small step"),
(min, min + (half_inc * 4) - 1, min + inc), # bigger balance, high enough, close to double step (min, min + (half_inc * 4) - 1, min + inc, "bigger balance, high enough, close to double step"),
(min, min + (half_inc * 4), min + (2 * inc)), # exact two step balance increment (min, min + (half_inc * 4), min + (2 * inc), "exact two step balance increment"),
(min, min + (half_inc * 4) + 1, min + (2 * inc)), # over two steps, round down (min, min + (half_inc * 4) + 1, min + (2 * inc), "over two steps, round down"),
] ]
for i, (pre_eff, bal, _) in enumerate(cases): current_epoch = spec.get_current_epoch(state)
for i, (pre_eff, bal, _, _) in enumerate(cases):
assert spec.is_active_validator(state.validators[i], current_epoch)
state.validators[i].effective_balance = pre_eff state.validators[i].effective_balance = pre_eff
state.balances[i] = bal state.balances[i] = bal
yield 'pre', state
spec.process_final_updates(state)
yield 'post', state
for i, (_, _, post_eff, name) in enumerate(cases):
assert state.validators[i].effective_balance == post_eff, name
@with_all_phases
@spec_state_test
def test_historical_root_accumulator(spec, state):
# skip ahead to near the end of the historical roots period (excl block before epoch processing)
state.slot = spec.SLOTS_PER_HISTORICAL_ROOT - 1
history_len = len(state.historical_roots)
yield from run_process_final_updates(spec, state) yield from run_process_final_updates(spec, state)
for i, (_, _, post_eff) in enumerate(cases): assert len(state.historical_roots) == history_len + 1
assert state.validators[i].effective_balance == post_eff