Skip to content

Add to epoch processing tests generation states before and after full epoch processing #4155

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
46 changes: 40 additions & 6 deletions tests/core/pyspec/eth2spec/test/helpers/epoch_processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,28 @@ def get_process_calls(spec):
]


def run_epoch_processing_to(spec, state, process_name: str):
def run_epoch_processing_to(spec, state, process_name: str, disable_slots_processing=False):
"""
Processes to the next epoch transition, up to, but not including, the sub-transition named ``process_name``
"""
slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH)
if not disable_slots_processing:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to put it this way:

Suggested change
if not disable_slots_processing:
if enable_slot_processing:

run_process_slots_up_to_epoch_boundary(spec, state)

# process components of epoch transition before final-updates
for name in get_process_calls(spec):
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)


def run_process_slots_up_to_epoch_boundary(spec, state):
"""
Processes slots until the next epoch transition
"""
slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot %
spec.SLOTS_PER_EPOCH)

# transition state to slot before epoch state transition
if state.slot < slot - 1:
Expand All @@ -53,12 +70,20 @@ def run_epoch_processing_to(spec, state, process_name: str):
# start transitioning, do one slot update before the epoch itself.
spec.process_slot(state)

# process components of epoch transition before final-updates

def run_epoch_processing_from(spec, state, process_name: str):
"""
Processes to the next epoch transition, from, but not including, the sub-transition named ``process_name``
"""
assert (state.slot + 1) % spec.SLOTS_PER_EPOCH == 0

processing = False
for name in get_process_calls(spec):
if name == process_name:
break
processing = True
continue
# only run when present. Later phases introduce more to the epoch-processing.
if hasattr(spec, name):
if processing and hasattr(spec, name):
getattr(spec, name)(state)


Expand All @@ -67,8 +92,17 @@ def run_epoch_processing_with(spec, state, process_name: str):
Processes to the next epoch transition, up to and including the sub-transition named ``process_name``
- pre-state ('pre'), state before calling ``process_name``
- post-state ('post'), state after calling ``process_name``
- pre-full-state ('pre_full'), state before epoch transition
- post-full-state ('post_full'), state after epoch transition
The state passed by reference will be modified to be the ``process_name``post state.
"""
run_epoch_processing_to(spec, state, process_name)
run_process_slots_up_to_epoch_boundary(spec, state)
yield "pre_full", state
run_epoch_processing_to(spec, state, process_name,
disable_slots_processing=True)
yield 'pre', state
getattr(spec, process_name)(state)
yield 'post', state
continue_state = state.copy()
run_epoch_processing_from(spec, continue_state, process_name)
yield 'post_full', continue_state
20 changes: 20 additions & 0 deletions tests/formats/epoch_processing/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ An SSZ-snappy encoded `BeaconState`, the state before running the epoch sub-tran

An SSZ-snappy encoded `BeaconState`, the state after applying the epoch sub-transition. No value if the sub-transition processing is aborted.

### `pre_full.ssz_snappy`

An SSZ-snappy encoded `BeaconState`, the state before running the epoch transition.

### `post_full.ssz_snappy`

An SSZ-snappy encoded `BeaconState`, the state after applying the epoch transition. No value if the transition processing is aborted.

## Condition

A handler of the `epoch_processing` test-runner should process these cases,
Expand Down Expand Up @@ -50,3 +58,15 @@ Sub-transitions:
- `pending_deposits` (>=Electra)

The resulting state should match the expected `post` state.

## Condition (alternative)

Instead of having a different handler for each sub-transition, a single handler for all cases, should load `pre_full` state, call `process_epoch` and then assert that the result state should match `post_full` state.

This has the advanges:

- Less code to maintain for the epoch processing handler.
- Works with single pass epoch processing.
- Can detect bugs related to data dependencies between different sub-transitions.

As a disadvantage this condition takes more resources to compute, but just a constant amount per test vector.