From 9b065c78167d1288e58913b56868e742207cd85e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Tue, 31 Aug 2021 17:42:10 +0800 Subject: [PATCH] To avoid using non-genesis anchor state, rewrite `test_on_block_finalized_skip_slots_not_in_skip_chain` --- .../test/phase0/fork_choice/test_on_block.py | 83 +++++++++++-------- 1 file changed, 50 insertions(+), 33 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/phase0/fork_choice/test_on_block.py b/tests/core/pyspec/eth2spec/test/phase0/fork_choice/test_on_block.py index 457eef7ff..0a3802338 100644 --- a/tests/core/pyspec/eth2spec/test/phase0/fork_choice/test_on_block.py +++ b/tests/core/pyspec/eth2spec/test/phase0/fork_choice/test_on_block.py @@ -26,7 +26,6 @@ from eth2spec.test.helpers.state import ( next_epoch, next_slots, state_transition_and_sign_block, - transition_to, ) @@ -191,6 +190,10 @@ def test_on_block_before_finalized(spec, state): @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_on_block_finalized_skip_slots(spec, state): + """ + Test case was originally from https://github.com/ethereum/consensus-specs/pull/1579 + And then rewrote largely. + """ test_steps = [] # Initialization store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state) @@ -200,21 +203,28 @@ def test_on_block_finalized_skip_slots(spec, state): on_tick_and_append_step(spec, store, current_time, test_steps) assert store.time == current_time - # Create a finalized chain - for _ in range(4): + # Fill epoch 0 and the first slot of epoch 1 + state, store, _ = yield from apply_next_slots_with_attestations( + spec, state, store, spec.SLOTS_PER_EPOCH, True, False, test_steps) + + # Skip the rest slots of epoch 1 and the first slot of epoch 2 + next_slots(spec, state, spec.SLOTS_PER_EPOCH) + + # Fill epoch 3 and 4 + for _ in range(2): state, store, _ = yield from apply_next_epoch_with_attestations( - spec, state, store, True, False, test_steps=test_steps) - assert store.finalized_checkpoint.epoch == 2 + spec, state, store, True, True, test_steps=test_steps) - # Another chain - another_state = store.block_states[store.finalized_checkpoint.root].copy() - # Build block that includes the skipped slots up to finality in chain - block = build_empty_block(spec, - another_state, - spec.compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) + 2) - block.body.graffiti = b'\x12' * 32 - signed_block = state_transition_and_sign_block(spec, another_state, block) + # Now we get finalized epoch 1, where compute_start_slot_at_epoch(1) is a skipped slot + assert state.finalized_checkpoint.epoch == store.finalized_checkpoint.epoch == 2 + assert store.finalized_checkpoint.root == spec.get_block_root(state, 1) == spec.get_block_root(state, 2) + assert state.current_justified_checkpoint.epoch == store.justified_checkpoint.epoch == 3 + assert store.justified_checkpoint == state.current_justified_checkpoint + # Now build a block at later slot than finalized *epoch* + # Includes finalized block in chain and the skipped slots + block = build_empty_block_for_next_slot(spec, state) + signed_block = state_transition_and_sign_block(spec, state, block) yield from tick_and_add_block(spec, store, signed_block, test_steps) yield 'steps', test_steps @@ -224,36 +234,43 @@ def test_on_block_finalized_skip_slots(spec, state): @spec_state_test @with_presets([MINIMAL], reason="too slow") def test_on_block_finalized_skip_slots_not_in_skip_chain(spec, state): + """ + Test case was originally from https://github.com/ethereum/consensus-specs/pull/1579 + And then rewrote largely. + """ test_steps = [] # Initialization - transition_to(spec, state, state.slot + spec.SLOTS_PER_EPOCH - 1) - block = build_empty_block_for_next_slot(spec, state) - transition_unsigned_block(spec, state, block) - block.state_root = state.hash_tree_root() - store = spec.get_forkchoice_store(state, block) + store, anchor_block = get_genesis_forkchoice_store_and_block(spec, state) yield 'anchor_state', state - yield 'anchor_block', block - + yield 'anchor_block', anchor_block current_time = state.slot * spec.config.SECONDS_PER_SLOT + store.genesis_time on_tick_and_append_step(spec, store, current_time, test_steps) assert store.time == current_time - pre_finalized_checkpoint_epoch = store.finalized_checkpoint.epoch + # Fill epoch 0 and the first slot of epoch 1 + state, store, _ = yield from apply_next_slots_with_attestations( + spec, state, store, spec.SLOTS_PER_EPOCH, True, False, test_steps) - # Finalized - for _ in range(3): + # Skip the rest slots of epoch 1 and the first slot of epoch 2 + next_slots(spec, state, spec.SLOTS_PER_EPOCH) + + # Fill epoch 3 and 4 + for _ in range(2): state, store, _ = yield from apply_next_epoch_with_attestations( - spec, state, store, True, False, test_steps=test_steps) - assert store.finalized_checkpoint.epoch == pre_finalized_checkpoint_epoch + 1 + spec, state, store, True, True, test_steps=test_steps) - # Now build a block at later slot than finalized epoch - # Includes finalized block in chain, but not at appropriate skip slot - pre_state = store.block_states[block.hash_tree_root()].copy() - block = build_empty_block(spec, - state=pre_state, - slot=spec.compute_start_slot_at_epoch(store.finalized_checkpoint.epoch) + 2) - block.body.graffiti = b'\x12' * 32 - signed_block = sign_block(spec, pre_state, block) + # Now we get finalized epoch 1, where compute_start_slot_at_epoch(1) is a skipped slot + assert state.finalized_checkpoint.epoch == store.finalized_checkpoint.epoch == 2 + assert store.finalized_checkpoint.root == spec.get_block_root(state, 1) == spec.get_block_root(state, 2) + assert state.current_justified_checkpoint.epoch == store.justified_checkpoint.epoch == 3 + assert store.justified_checkpoint == state.current_justified_checkpoint + + # Now build a block after the block of the finalized **root** + # Includes finalized block in chain, but does not include finalized skipped slots + another_state = store.block_states[store.finalized_checkpoint.root].copy() + assert another_state.slot == spec.compute_start_slot_at_epoch(store.finalized_checkpoint.epoch - 1) + block = build_empty_block_for_next_slot(spec, another_state) + signed_block = state_transition_and_sign_block(spec, another_state, block) yield from tick_and_add_block(spec, store, signed_block, test_steps, valid=False) yield 'steps', test_steps