From b85afcab7a36b0d51ae9625192d6a0cd301d4868 Mon Sep 17 00:00:00 2001 From: Aditya Asgaonkar Date: Thu, 11 Jun 2020 07:28:26 -0700 Subject: [PATCH 1/3] Added fix in store_target_checkpoint_state --- specs/phase0/fork-choice.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/phase0/fork-choice.md b/specs/phase0/fork-choice.md index b9d8ecd3c3..614c21cc63 100644 --- a/specs/phase0/fork-choice.md +++ b/specs/phase0/fork-choice.md @@ -301,7 +301,8 @@ def store_target_checkpoint_state(store: Store, target: Checkpoint) -> None: # Store target checkpoint state if not yet seen if target not in store.checkpoint_states: base_state = store.block_states[target.root].copy() - process_slots(base_state, compute_start_slot_at_epoch(target.epoch)) + if base_state.slot < compute_start_slot_at_epoch(target.epoch): + process_slots(base_state, compute_start_slot_at_epoch(target.epoch)) store.checkpoint_states[target] = base_state ``` From 993ed5c2c6474af552326582153bebc2f210080d Mon Sep 17 00:00:00 2001 From: Aditya Asgaonkar Date: Fri, 12 Jun 2020 14:37:07 -0700 Subject: [PATCH 2/3] Resetting branch to dev and adding single commit --- specs/phase0/fork-choice.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/specs/phase0/fork-choice.md b/specs/phase0/fork-choice.md index 132477ee8a..02143d0a45 100644 --- a/specs/phase0/fork-choice.md +++ b/specs/phase0/fork-choice.md @@ -301,7 +301,8 @@ def store_target_checkpoint_state(store: Store, target: Checkpoint) -> None: # Store target checkpoint state if not yet seen if target not in store.checkpoint_states: base_state = store.block_states[target.root].copy() - process_slots(base_state, compute_start_slot_at_epoch(target.epoch)) + if base_state.slot < compute_start_slot_at_epoch(target.epoch): + process_slots(base_state, compute_start_slot_at_epoch(target.epoch)) store.checkpoint_states[target] = base_state ``` From a1e3392d2f0b62209577174a79e87c09da9149b2 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 22 Jun 2020 09:47:22 -0600 Subject: [PATCH 3/3] add tests for on_attestation ceckpont state fix --- .../test/fork_choice/test_on_attestation.py | 58 ++++++++++++++++++- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py b/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py index a5334c5c78..d8885a0147 100644 --- a/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py +++ b/tests/core/pyspec/eth2spec/test/fork_choice/test_on_attestation.py @@ -163,9 +163,9 @@ def test_on_attestation_inconsistent_target_and_head(spec, state): @with_all_phases @spec_state_test -def test_on_attestation_target_not_in_store(spec, state): +def test_on_attestation_target_block_not_in_store(spec, state): store = spec.get_forkchoice_store(state) - time = store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH + time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1) spec.on_tick(store, time) # move to immediately before next epoch to make block new target @@ -183,11 +183,63 @@ def test_on_attestation_target_not_in_store(spec, state): run_on_attestation(spec, state, store, attestation, False) +@with_all_phases +@spec_state_test +def test_on_attestation_target_checkpoint_not_in_store(spec, state): + store = spec.get_forkchoice_store(state) + time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1) + spec.on_tick(store, time) + + # move to immediately before next epoch to make block new target + next_epoch = spec.get_current_epoch(state) + 1 + transition_to(spec, state, spec.compute_start_slot_at_epoch(next_epoch) - 1) + + target_block = build_empty_block_for_next_slot(spec, state) + signed_target_block = state_transition_and_sign_block(spec, state, target_block) + + # add target block to store + spec.on_block(store, signed_target_block) + + # target checkpoint state is not yet in store + + attestation = get_valid_attestation(spec, state, slot=target_block.slot, signed=True) + assert attestation.data.target.root == target_block.hash_tree_root() + + run_on_attestation(spec, state, store, attestation) + + +@with_all_phases +@spec_state_test +def test_on_attestation_target_checkpoint_not_in_store_diff_slot(spec, state): + store = spec.get_forkchoice_store(state) + time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1) + spec.on_tick(store, time) + + # move to two slots before next epoch to make target block one before an empty slot + next_epoch = spec.get_current_epoch(state) + 1 + transition_to(spec, state, spec.compute_start_slot_at_epoch(next_epoch) - 2) + + target_block = build_empty_block_for_next_slot(spec, state) + signed_target_block = state_transition_and_sign_block(spec, state, target_block) + + # add target block to store + spec.on_block(store, signed_target_block) + + # target checkpoint state is not yet in store + + attestation_slot = target_block.slot + 1 + transition_to(spec, state, attestation_slot) + attestation = get_valid_attestation(spec, state, slot=attestation_slot, signed=True) + assert attestation.data.target.root == target_block.hash_tree_root() + + run_on_attestation(spec, state, store, attestation) + + @with_all_phases @spec_state_test def test_on_attestation_beacon_block_not_in_store(spec, state): store = spec.get_forkchoice_store(state) - time = store.time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH + time = store.time + spec.SECONDS_PER_SLOT * (spec.SLOTS_PER_EPOCH + 1) spec.on_tick(store, time) # move to immediately before next epoch to make block new target