Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 40 additions & 7 deletions tests/core/pyspec/eth2spec/test/helpers/epoch_processing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from eth2spec.test.helpers.forks import (
is_post_altair,
is_post_capella,
Expand Down Expand Up @@ -40,11 +39,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 +69,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 +91,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-epoch-state ('pre_epoch'), state before epoch transition
- post-epoch-state ('post_epoch'), 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_epoch", 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_epoch', 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_epoch.ssz_snappy`

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

### `post_epoch.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.
Copy link
Contributor

Choose a reason for hiding this comment

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

Why it should be instead and couldn't be in addition to the pre and post state checks?


This has the advantages:

- 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.