From aedd281edbcacfa68ff7ec91d4f3f2b0031a61c7 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 25 Jun 2019 23:18:19 +0200 Subject: [PATCH] clean up epoch processing testing --- .../run_epoch_process_base.py | 51 ++++++++--------- .../test_process_final_updates.py | 55 +++++++++++++------ 2 files changed, 60 insertions(+), 46 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py index 13e1c3f3b..7e0cffc79 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py @@ -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 = ( - '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): +def run_epoch_processing_to(spec, state, process_name: str, exclusive=False): """ - 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`` - 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) - 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) + slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) - # cache state before epoch transition - spec.process_slot(state) + # transition state to slot before epoch state transition + spec.process_slots(state, slot) # process components of epoch transition before final-updates for name in process_calls: @@ -39,6 +33,7 @@ def run_epoch_processing_to(spec, state, process_name: str): if hasattr(spec, name): getattr(spec, name)(state) - yield 'pre', state - getattr(spec, process_name)(state) - yield 'post', state + if not exclusive: + yield 'pre', state + getattr(spec, process_name)(state) + yield 'post', state diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py index 0c19f8e31..d1af7d396 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py @@ -10,8 +10,8 @@ def run_process_final_updates(spec, state): @spec_state_test def test_eth1_vote_no_reset(spec, state): assert spec.SLOTS_PER_ETH1_VOTING_PERIOD > spec.SLOTS_PER_EPOCH - # skip ahead to near the end of the epoch - state.slot = spec.SLOTS_PER_EPOCH - 2 + # skip ahead to the end of the epoch + state.slot = spec.SLOTS_PER_EPOCH - 1 for i in range(state.slot + 1): # add a vote for each skipped slot. state.eth1_data_votes.append( spec.Eth1Data(deposit_root=b'\xaa' * 32, @@ -26,8 +26,8 @@ def test_eth1_vote_no_reset(spec, state): @with_all_phases @spec_state_test def test_eth1_vote_reset(spec, state): - # skip ahead to near the end of the voting period - state.slot = spec.SLOTS_PER_ETH1_VOTING_PERIOD - 2 + # skip ahead to the end of the voting period + state.slot = spec.SLOTS_PER_ETH1_VOTING_PERIOD - 1 for i in range(state.slot + 1): # add a vote for each skipped slot. state.eth1_data_votes.append( spec.Eth1Data(deposit_root=b'\xaa' * 32, @@ -42,29 +42,48 @@ def test_eth1_vote_reset(spec, state): @with_all_phases @spec_state_test 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 max = spec.MAX_EFFECTIVE_BALANCE min = spec.EJECTION_BALANCE inc = spec.EFFECTIVE_BALANCE_INCREMENT half_inc = inc // 2 cases = [ - (max, max, max), # as is - (max, max - 1, max - inc), # round down, step lower - (max, max + 1, max), # round down - (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 - inc), # close to 1 step lower - (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 * 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) + 1, min + (2 * inc)), # over two steps, round down + (max, max, max, "as-is"), + (max, max - 1, max - inc, "round down, step lower"), + (max, max + 1, max, "round down"), + (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 - inc, "close to 1 step lower"), + (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 * 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) + 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.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) - for i, (_, _, post_eff) in enumerate(cases): - assert state.validators[i].effective_balance == post_eff + assert len(state.historical_roots) == history_len + 1