mirror of
https://github.com/status-im/eth2.0-specs.git
synced 2025-02-26 01:05:15 +00:00
generalize epoch processing testing, add final-processing tests
This commit is contained in:
parent
0e3c2cef5c
commit
b2034a54a0
@ -0,0 +1,44 @@
|
|||||||
|
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'
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def run_epoch_processing_to(spec, state, process_name: str):
|
||||||
|
"""
|
||||||
|
Run the epoch processing functions up to ``process_name`` (incl.), yielding:
|
||||||
|
- 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)
|
||||||
|
|
||||||
|
# cache state before epoch transition
|
||||||
|
spec.process_slot(state)
|
||||||
|
|
||||||
|
# process components of epoch transition before final-updates
|
||||||
|
for name in process_calls:
|
||||||
|
if name == process_name:
|
||||||
|
break
|
||||||
|
# only run when present. Later phases introduce more to the epoch-processing.
|
||||||
|
if hasattr(spec, name):
|
||||||
|
getattr(spec, name)(state)
|
||||||
|
|
||||||
|
yield 'pre', state
|
||||||
|
getattr(spec, process_name)(state)
|
||||||
|
yield 'post', state
|
@ -4,41 +4,19 @@ from eth2spec.test.context import spec_state_test, with_all_phases
|
|||||||
from eth2spec.test.helpers.state import (
|
from eth2spec.test.helpers.state import (
|
||||||
next_epoch,
|
next_epoch,
|
||||||
next_slot,
|
next_slot,
|
||||||
state_transition_and_sign_block,
|
|
||||||
)
|
)
|
||||||
from eth2spec.test.helpers.block import apply_empty_block, sign_block
|
from eth2spec.test.helpers.block import apply_empty_block
|
||||||
from eth2spec.test.helpers.attestations import (
|
from eth2spec.test.helpers.attestations import (
|
||||||
add_attestation_to_state,
|
add_attestation_to_state,
|
||||||
build_empty_block_for_next_slot,
|
|
||||||
fill_aggregate_attestation,
|
fill_aggregate_attestation,
|
||||||
get_valid_attestation,
|
get_valid_attestation,
|
||||||
sign_attestation,
|
sign_attestation,
|
||||||
)
|
)
|
||||||
|
from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_to
|
||||||
|
|
||||||
|
|
||||||
def run_process_crosslinks(spec, state, valid=True):
|
def run_process_crosslinks(spec, state):
|
||||||
"""
|
yield from run_epoch_processing_to(spec, state, 'process_crosslinks')
|
||||||
Run ``process_crosslinks``, yielding:
|
|
||||||
- pre-state ('pre')
|
|
||||||
- post-state ('post').
|
|
||||||
If ``valid == False``, run expecting ``AssertionError``
|
|
||||||
"""
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# cache state before epoch transition
|
|
||||||
spec.process_slot(state)
|
|
||||||
|
|
||||||
# process components of epoch transition before processing crosslinks
|
|
||||||
spec.process_justification_and_finalization(state)
|
|
||||||
|
|
||||||
yield 'pre', state
|
|
||||||
spec.process_crosslinks(state)
|
|
||||||
yield 'post', state
|
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
|
@ -0,0 +1,53 @@
|
|||||||
|
from eth2spec.test.context import spec_state_test, with_all_phases
|
||||||
|
from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_to
|
||||||
|
|
||||||
|
|
||||||
|
def run_process_final_updates(spec, state):
|
||||||
|
yield from run_epoch_processing_to(spec, state, 'process_final_updates')
|
||||||
|
|
||||||
|
|
||||||
|
@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
|
||||||
|
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,
|
||||||
|
deposit_count=state.eth1_deposit_index,
|
||||||
|
block_hash=b'\xbb' * 32))
|
||||||
|
|
||||||
|
yield from run_process_final_updates(spec, state)
|
||||||
|
|
||||||
|
assert len(state.eth1_data_votes) == 0
|
||||||
|
|
||||||
|
|
||||||
|
@with_all_phases
|
||||||
|
@spec_state_test
|
||||||
|
def test_effective_balance_hysteresis(spec, state):
|
||||||
|
# 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
|
||||||
|
]
|
||||||
|
for i, (pre_eff, bal, _) in enumerate(cases):
|
||||||
|
state.validators[i].effective_balance = pre_eff
|
||||||
|
state.balances[i] = bal
|
||||||
|
|
||||||
|
yield from run_process_final_updates(spec, state)
|
||||||
|
|
||||||
|
for i, (_, _, post_eff) in enumerate(cases):
|
||||||
|
assert state.validators[i].effective_balance == post_eff
|
@ -1,33 +1,10 @@
|
|||||||
from eth2spec.test.helpers.block import build_empty_block_for_next_slot, sign_block
|
from eth2spec.test.helpers.state import next_epoch
|
||||||
from eth2spec.test.helpers.state import next_epoch, state_transition_and_sign_block
|
|
||||||
from eth2spec.test.context import spec_state_test, with_all_phases
|
from eth2spec.test.context import spec_state_test, with_all_phases
|
||||||
|
from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_to
|
||||||
|
|
||||||
|
|
||||||
def run_process_registry_updates(spec, state, valid=True):
|
def run_process_registry_updates(spec, state):
|
||||||
"""
|
yield from run_epoch_processing_to(spec, state, 'process_registry_updates')
|
||||||
Run ``process_crosslinks``, yielding:
|
|
||||||
- pre-state ('pre')
|
|
||||||
- post-state ('post').
|
|
||||||
If ``valid == False``, run expecting ``AssertionError``
|
|
||||||
"""
|
|
||||||
# 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)
|
|
||||||
|
|
||||||
# cache state before epoch transition
|
|
||||||
spec.process_slot(state)
|
|
||||||
|
|
||||||
# process components of epoch transition before registry update
|
|
||||||
spec.process_justification_and_finalization(state)
|
|
||||||
spec.process_crosslinks(state)
|
|
||||||
spec.process_rewards_and_penalties(state)
|
|
||||||
|
|
||||||
yield 'pre', state
|
|
||||||
spec.process_registry_updates(state)
|
|
||||||
yield 'post', state
|
|
||||||
|
|
||||||
|
|
||||||
def mock_deposit(spec, state, index):
|
def mock_deposit(spec, state, index):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user