diff --git a/specs/phase0/beacon-chain.md b/specs/phase0/beacon-chain.md index cdf38dc1e..1fd18336d 100644 --- a/specs/phase0/beacon-chain.md +++ b/specs/phase0/beacon-chain.md @@ -1219,7 +1219,7 @@ def verify_block_signature(state: BeaconState, signed_block: SignedBeaconBlock) ```python def process_slots(state: BeaconState, slot: Slot) -> None: - assert state.slot <= slot + assert state.slot < slot while state.slot < slot: process_slot(state) # Process epoch on the start slot of the next epoch diff --git a/tests/core/pyspec/eth2spec/test/helpers/attestations.py b/tests/core/pyspec/eth2spec/test/helpers/attestations.py index 8215f5c5b..76e90e89f 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/attestations.py +++ b/tests/core/pyspec/eth2spec/test/helpers/attestations.py @@ -243,7 +243,8 @@ def fill_aggregate_attestation(spec, state, attestation, signed=False): def add_attestations_to_state(spec, state, attestations, slot): - spec.process_slots(state, slot) + if state.slot < slot: + spec.process_slots(state, slot) for attestation in attestations: spec.process_attestation(state, attestation) diff --git a/tests/core/pyspec/eth2spec/test/helpers/block.py b/tests/core/pyspec/eth2spec/test/helpers/block.py index 96cc30e35..b6167c569 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/block.py +++ b/tests/core/pyspec/eth2spec/test/helpers/block.py @@ -15,7 +15,8 @@ def get_proposer_index_maybe(spec, state, slot, proposer_index=None): " Signing block is slow due to transition for proposer index calculation.") # use stub state to get proposer index of future slot stub_state = state.copy() - spec.process_slots(stub_state, slot) + if stub_state.slot < slot: + spec.process_slots(stub_state, slot) proposer_index = spec.get_beacon_proposer_index(stub_state) return proposer_index @@ -52,7 +53,10 @@ def sign_block(spec, state, block, proposer_index=None): def transition_unsigned_block(spec, state, block): - spec.process_slots(state, block.slot) + if state.slot < block.slot: + spec.process_slots(state, block.slot) + assert state.latest_block_header.slot < block.slot # There may not already be a block in this slot or past it. + assert state.slot == block.slot # The block must be for this slot spec.process_block(state, block) @@ -74,9 +78,10 @@ def build_empty_block(spec, state, slot=None): if slot < state.slot: raise Exception("build_empty_block cannot build blocks for past slots") if slot > state.slot: - # transition forward in copied state to grab relevant data from state - state = state.copy() - spec.process_slots(state, slot) + if state.slot < slot: + # transition forward in copied state to grab relevant data from state + state = state.copy() + spec.process_slots(state, slot) empty_block = spec.BeaconBlock() empty_block.slot = slot diff --git a/tests/core/pyspec/eth2spec/test/helpers/state.py b/tests/core/pyspec/eth2spec/test/helpers/state.py index 46a7ce2b5..3860a11ce 100644 --- a/tests/core/pyspec/eth2spec/test/helpers/state.py +++ b/tests/core/pyspec/eth2spec/test/helpers/state.py @@ -17,7 +17,8 @@ def next_slots(spec, state, slots): """ Transition given slots forward. """ - spec.process_slots(state, state.slot + slots) + if slots > 0: + spec.process_slots(state, state.slot + slots) def transition_to(spec, state, slot): @@ -35,7 +36,8 @@ def next_epoch(spec, state): Transition to the start slot of the next epoch """ slot = state.slot + spec.SLOTS_PER_EPOCH - (state.slot % spec.SLOTS_PER_EPOCH) - spec.process_slots(state, slot) + if slot > state.slot: + spec.process_slots(state, slot) def get_state_root(spec, state, slot) -> bytes: diff --git a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py b/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py index af4587a2a..b8692227f 100644 --- a/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py +++ b/tests/core/pyspec/eth2spec/test/phase_0/epoch_processing/run_epoch_process_base.py @@ -18,7 +18,8 @@ def run_epoch_processing_to(spec, state, process_name: str): slot = state.slot + (spec.SLOTS_PER_EPOCH - state.slot % spec.SLOTS_PER_EPOCH) # transition state to slot before epoch state transition - spec.process_slots(state, slot - 1) + if state.slot < slot - 1: + spec.process_slots(state, slot - 1) # start transitioning, do one slot update before the epoch itself. spec.process_slot(state) diff --git a/tests/core/pyspec/eth2spec/test/sanity/test_slots.py b/tests/core/pyspec/eth2spec/test/sanity/test_slots.py index 6ef6be4d3..dd4f302ae 100644 --- a/tests/core/pyspec/eth2spec/test/sanity/test_slots.py +++ b/tests/core/pyspec/eth2spec/test/sanity/test_slots.py @@ -51,7 +51,8 @@ def test_double_empty_epoch(spec, state): @with_all_phases @spec_state_test def test_over_epoch_boundary(spec, state): - spec.process_slots(state, state.slot + (spec.SLOTS_PER_EPOCH // 2)) + if spec.SLOTS_PER_EPOCH > 1: + spec.process_slots(state, state.slot + (spec.SLOTS_PER_EPOCH // 2)) yield 'pre', state slots = spec.SLOTS_PER_EPOCH yield 'slots', slots