From 687b262f0d96f3b331758b35520ec27597585d15 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 20 Sep 2019 11:27:42 -0500 Subject: [PATCH 1/8] add test case for crosslink tie breaking between epochs --- .../eth2spec/test/helpers/attestations.py | 5 +- .../test_process_crosslinks.py | 52 +++++++++++++++++-- 2 files changed, 50 insertions(+), 7 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/helpers/attestations.py b/test_libs/pyspec/eth2spec/test/helpers/attestations.py index 868517018..43d9bf44f 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/attestations.py +++ b/test_libs/pyspec/eth2spec/test/helpers/attestations.py @@ -138,10 +138,11 @@ def fill_aggregate_attestation(spec, state, attestation): attestation.aggregation_bits[i] = True -def add_attestation_to_state(spec, state, attestation, slot): +def add_attestations_to_state(spec, state, attestations, slot): block = build_empty_block_for_next_slot(spec, state) block.slot = slot - block.body.attestations.append(attestation) + for attestation in attestations: + block.body.attestations.append(attestation) spec.process_slots(state, block.slot) sign_block(spec, state, block) spec.state_transition(state, block) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py index 41d784c50..a335896df 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py @@ -7,7 +7,7 @@ from eth2spec.test.helpers.state import ( ) from eth2spec.test.helpers.block import apply_empty_block from eth2spec.test.helpers.attestations import ( - add_attestation_to_state, + add_attestations_to_state, fill_aggregate_attestation, get_valid_attestation, sign_attestation, @@ -36,7 +36,7 @@ def test_single_crosslink_update_from_current_epoch(spec, state): attestation = get_valid_attestation(spec, state, signed=True) fill_aggregate_attestation(spec, state, attestation) - add_attestation_to_state(spec, state, attestation, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) + add_attestations_to_state(spec, state, [attestation], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) assert len(state.current_epoch_attestations) == 1 @@ -57,7 +57,7 @@ def test_single_crosslink_update_from_previous_epoch(spec, state): attestation = get_valid_attestation(spec, state, signed=True) fill_aggregate_attestation(spec, state, attestation) - add_attestation_to_state(spec, state, attestation, state.slot + spec.SLOTS_PER_EPOCH) + add_attestations_to_state(spec, state, [attestation], state.slot + spec.SLOTS_PER_EPOCH) assert len(state.previous_epoch_attestations) == 1 @@ -95,7 +95,7 @@ def test_double_late_crosslink(spec, state): # add attestation_1 to next epoch next_epoch(spec, state) - add_attestation_to_state(spec, state, attestation_1, state.slot + 1) + add_attestations_to_state(spec, state, [attestation_1], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) for _ in range(spec.SLOTS_PER_EPOCH): attestation_2 = get_valid_attestation(spec, state) @@ -110,7 +110,7 @@ def test_double_late_crosslink(spec, state): # add attestation_2 in the next epoch after attestation_1 has # already updated the relevant crosslink next_epoch(spec, state) - add_attestation_to_state(spec, state, attestation_2, state.slot + 1) + add_attestations_to_state(spec, state, [attestation_2], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) assert len(state.previous_epoch_attestations) == 1 assert len(state.current_epoch_attestations) == 0 @@ -130,3 +130,45 @@ def test_double_late_crosslink(spec, state): attestation_2.data.crosslink.shard): assert crosslink_deltas[0][index] == 0 assert crosslink_deltas[1][index] > 0 + + +@with_all_phases +@spec_state_test +def test_tied_crosslink_between_epochs(spec, state): + """ + Addresses scenario found at Interop described by this test case + https://github.com/djrtwo/interop-test-cases/tree/master/tests/night_one_16_crosslinks + + Ensure that ties on crosslinks between epochs are broken by previous epoch. + """ + prev_attestation = get_valid_attestation(spec, state, signed=True) + fill_aggregate_attestation(spec, state, prev_attestation) + + # add attestation at start of next epoch + next_epoch(spec, state) + add_attestations_to_state(spec, state, [prev_attestation], state.slot) + + # create attestation from current epoch for same shard + for _ in range(spec.SLOTS_PER_EPOCH): + cur_attestation = get_valid_attestation(spec, state) + if cur_attestation.data.crosslink.shard == prev_attestation.data.crosslink.shard: + sign_attestation(spec, state, cur_attestation) + break + next_slot(spec, state) + fill_aggregate_attestation(spec, state, cur_attestation) + + add_attestations_to_state(spec, state, [cur_attestation], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) + + shard = prev_attestation.data.crosslink.shard + pre_crosslink = deepcopy(state.current_crosslinks[shard]) + + assert prev_attestation.data.crosslink != cur_attestation.data.crosslink + assert state.current_crosslinks[shard] == spec.Crosslink() + assert len(state.previous_epoch_attestations) == 1 + assert len(state.current_epoch_attestations) == 1 + + yield from run_process_crosslinks(spec, state) + + assert state.previous_crosslinks[shard] != state.current_crosslinks[shard] + assert pre_crosslink != state.current_crosslinks[shard] + assert state.current_crosslinks[shard] == prev_attestation.data.crosslink From ad4da4cd14aecd95424a5c38da735051e1056940 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 20 Sep 2019 12:45:46 -0500 Subject: [PATCH 2/8] rewards test for duplicate attestation --- .../test_process_rewards_and_penalties.py | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py new file mode 100644 index 000000000..8b79e8d68 --- /dev/null +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py @@ -0,0 +1,96 @@ +from copy import deepcopy + +from eth2spec.test.context import spec_state_test, with_all_phases +from eth2spec.test.helpers.state import ( + next_epoch, + next_slot, +) +from eth2spec.test.helpers.attestations import ( + add_attestations_to_state, + fill_aggregate_attestation, + get_valid_attestation, + sign_attestation, +) +from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with + + +def run_process_rewards_and_penalties(spec, state): + yield from run_epoch_processing_with(spec, state, 'process_rewards_and_penalties') + + +@with_all_phases +@spec_state_test +def test_genesis_epoch_no_attestations_no_penalties(spec, state): + pre_state = deepcopy(state) + + assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH + + yield from run_process_rewards_and_penalties(spec, state) + + for index in range(len(pre_state.validators)): + assert state.balances[index] == pre_state.balances[index] + + +@with_all_phases +@spec_state_test +def test_genesis_epoch_full_attestations_no_rewards(spec, state): + attestations = [] + for slot in range(spec.SLOTS_PER_EPOCH - spec.MIN_ATTESTATION_INCLUSION_DELAY - 1): + attestation = get_valid_attestation(spec, state, signed=True) + fill_aggregate_attestation(spec, state, attestation) + attestations.append(attestation) + next_slot(spec, state) + add_attestations_to_state(spec, state, attestations, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) + + assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH + + pre_state = deepcopy(state) + + yield from run_process_rewards_and_penalties(spec, state) + + for index in range(len(pre_state.validators)): + assert state.balances[index] == pre_state.balances[index] + + +@with_all_phases +@spec_state_test +def test_no_attestations_all_penalties(spec, state): + next_epoch(spec, state) + pre_state = deepcopy(state) + + yield from run_process_rewards_and_penalties(spec, state) + + for index in range(len(pre_state.validators)): + assert state.balances[index] < pre_state.balances[index] + + +@with_all_phases +@spec_state_test +def test_duplicate_attestation(spec, state): + attestation = get_valid_attestation(spec, state, signed=True) + fill_aggregate_attestation(spec, state, attestation) + + indexed_attestation = spec.get_indexed_attestation(state, attestation) + participants = indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices + + assert len(participants) > 0 + + single_state = deepcopy(state) + dup_state = deepcopy(state) + + inclusion_slot = state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY + add_attestations_to_state(spec, single_state, [attestation], inclusion_slot) + add_attestations_to_state(spec, dup_state, [attestation, attestation], inclusion_slot) + + next_epoch(spec, single_state) + next_epoch(spec, dup_state) + + # Run non-duplicate inclusion rewards for comparision. Do not yield test vectors + pre, post = run_process_rewards_and_penalties(spec, single_state) + + # Output duplicate inclusion to test vectors + yield from run_process_rewards_and_penalties(spec, dup_state) + + for index in participants: + assert state.balances[index] < single_state.balances[index] + assert single_state.balances[index] == dup_state.balances[index] From b3f7dd9dae4cb3bd7a5e004ebe64b44427e8bf8c Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Fri, 20 Sep 2019 16:05:10 -0500 Subject: [PATCH 3/8] fix up rewards/penalties test signatures --- .../eth2spec/test/helpers/attestations.py | 5 +++- .../test_process_crosslinks.py | 24 ++++++++----------- .../test_process_rewards_and_penalties.py | 9 ++++--- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/helpers/attestations.py b/test_libs/pyspec/eth2spec/test/helpers/attestations.py index 43d9bf44f..394579413 100644 --- a/test_libs/pyspec/eth2spec/test/helpers/attestations.py +++ b/test_libs/pyspec/eth2spec/test/helpers/attestations.py @@ -128,7 +128,7 @@ def get_attestation_signature(spec, state, attestation_data, privkey, custody_bi ) -def fill_aggregate_attestation(spec, state, attestation): +def fill_aggregate_attestation(spec, state, attestation, signed=False): crosslink_committee = spec.get_crosslink_committee( state, attestation.data.target.epoch, @@ -137,6 +137,9 @@ def fill_aggregate_attestation(spec, state, attestation): for i in range(len(crosslink_committee)): attestation.aggregation_bits[i] = True + if signed: + sign_attestation(spec, state, attestation) + def add_attestations_to_state(spec, state, attestations, slot): block = build_empty_block_for_next_slot(spec, state) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py index a335896df..83e2bb017 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py @@ -10,7 +10,6 @@ from eth2spec.test.helpers.attestations import ( add_attestations_to_state, fill_aggregate_attestation, get_valid_attestation, - sign_attestation, ) from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with @@ -33,9 +32,9 @@ def test_no_attestations(spec, state): def test_single_crosslink_update_from_current_epoch(spec, state): next_epoch(spec, state) - attestation = get_valid_attestation(spec, state, signed=True) + attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation) + fill_aggregate_attestation(spec, state, attestation, signed=True) add_attestations_to_state(spec, state, [attestation], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) assert len(state.current_epoch_attestations) == 1 @@ -54,9 +53,9 @@ def test_single_crosslink_update_from_current_epoch(spec, state): def test_single_crosslink_update_from_previous_epoch(spec, state): next_epoch(spec, state) - attestation = get_valid_attestation(spec, state, signed=True) + attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation) + fill_aggregate_attestation(spec, state, attestation, signed=True) add_attestations_to_state(spec, state, [attestation], state.slot + spec.SLOTS_PER_EPOCH) assert len(state.previous_epoch_attestations) == 1 @@ -90,8 +89,8 @@ def test_double_late_crosslink(spec, state): next_epoch(spec, state) state.slot += 4 - attestation_1 = get_valid_attestation(spec, state, signed=True) - fill_aggregate_attestation(spec, state, attestation_1) + attestation_1 = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, attestation_1, signed=True) # add attestation_1 to next epoch next_epoch(spec, state) @@ -100,13 +99,11 @@ def test_double_late_crosslink(spec, state): for _ in range(spec.SLOTS_PER_EPOCH): attestation_2 = get_valid_attestation(spec, state) if attestation_2.data.crosslink.shard == attestation_1.data.crosslink.shard: - sign_attestation(spec, state, attestation_2) + fill_aggregate_attestation(spec, state, attestation_2, signed=True) break next_slot(spec, state) apply_empty_block(spec, state) - fill_aggregate_attestation(spec, state, attestation_2) - # add attestation_2 in the next epoch after attestation_1 has # already updated the relevant crosslink next_epoch(spec, state) @@ -141,8 +138,8 @@ def test_tied_crosslink_between_epochs(spec, state): Ensure that ties on crosslinks between epochs are broken by previous epoch. """ - prev_attestation = get_valid_attestation(spec, state, signed=True) - fill_aggregate_attestation(spec, state, prev_attestation) + prev_attestation = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, prev_attestation, signed=True) # add attestation at start of next epoch next_epoch(spec, state) @@ -152,10 +149,9 @@ def test_tied_crosslink_between_epochs(spec, state): for _ in range(spec.SLOTS_PER_EPOCH): cur_attestation = get_valid_attestation(spec, state) if cur_attestation.data.crosslink.shard == prev_attestation.data.crosslink.shard: - sign_attestation(spec, state, cur_attestation) + fill_aggregate_attestation(spec, state, cur_attestation, signed=True) break next_slot(spec, state) - fill_aggregate_attestation(spec, state, cur_attestation) add_attestations_to_state(spec, state, [cur_attestation], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py index 8b79e8d68..e42092941 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py @@ -9,7 +9,6 @@ from eth2spec.test.helpers.attestations import ( add_attestations_to_state, fill_aggregate_attestation, get_valid_attestation, - sign_attestation, ) from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with @@ -36,8 +35,8 @@ def test_genesis_epoch_no_attestations_no_penalties(spec, state): def test_genesis_epoch_full_attestations_no_rewards(spec, state): attestations = [] for slot in range(spec.SLOTS_PER_EPOCH - spec.MIN_ATTESTATION_INCLUSION_DELAY - 1): - attestation = get_valid_attestation(spec, state, signed=True) - fill_aggregate_attestation(spec, state, attestation) + attestation = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, attestation, signed=True) attestations.append(attestation) next_slot(spec, state) add_attestations_to_state(spec, state, attestations, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) @@ -67,8 +66,8 @@ def test_no_attestations_all_penalties(spec, state): @with_all_phases @spec_state_test def test_duplicate_attestation(spec, state): - attestation = get_valid_attestation(spec, state, signed=True) - fill_aggregate_attestation(spec, state, attestation) + attestation = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, attestation, signed=True) indexed_attestation = spec.get_indexed_attestation(state, attestation) participants = indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices From cf1323b79e5d1786a5d81888dd428c45f95b62c0 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 22 Sep 2019 09:35:18 -0500 Subject: [PATCH 4/8] add rewards/penalties test for full epoch of attestations --- .../test_process_rewards_and_penalties.py | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py index e42092941..f0cde1a73 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py @@ -51,12 +51,37 @@ def test_genesis_epoch_full_attestations_no_rewards(spec, state): assert state.balances[index] == pre_state.balances[index] +@with_all_phases +@spec_state_test +def test_full_attestations(spec, state): + attestations = [] + for slot in range(spec.SLOTS_PER_EPOCH - spec.MIN_ATTESTATION_INCLUSION_DELAY): + attestation = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, attestation, signed=True) + attestations.append(attestation) + next_slot(spec, state) + add_attestations_to_state(spec, state, attestations, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) + + assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH + 1 + + pre_state = deepcopy(state) + + yield from run_process_rewards_and_penalties(spec, state) + + attesting_indices = spec.get_unslashed_attesting_indices(state, attestations) + assert len(attesting_indices) > 0 + for index in attesting_indices: + assert state.balances[index] > pre_state.balances[index] + + @with_all_phases @spec_state_test def test_no_attestations_all_penalties(spec, state): next_epoch(spec, state) pre_state = deepcopy(state) + assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH + 1 + yield from run_process_rewards_and_penalties(spec, state) for index in range(len(pre_state.validators)): @@ -66,6 +91,12 @@ def test_no_attestations_all_penalties(spec, state): @with_all_phases @spec_state_test def test_duplicate_attestation(spec, state): + """ + Although duplicate attestations can be included on-chain, they should only + be rewarded for once. + This test addresses this issue found at Interop + https://github.com/djrtwo/interop-test-cases/tree/master/tests/prysm_16_duplicate_attestation_rewards + """ attestation = get_valid_attestation(spec, state) fill_aggregate_attestation(spec, state, attestation, signed=True) From 1aa12034e55867554739b0f941aecb65b83edf27 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 22 Sep 2019 09:51:12 -0500 Subject: [PATCH 5/8] make full_attestation reward test better --- .../test_process_rewards_and_penalties.py | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py index f0cde1a73..114898abf 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py @@ -55,14 +55,20 @@ def test_genesis_epoch_full_attestations_no_rewards(spec, state): @spec_state_test def test_full_attestations(spec, state): attestations = [] - for slot in range(spec.SLOTS_PER_EPOCH - spec.MIN_ATTESTATION_INCLUSION_DELAY): - attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation, signed=True) - attestations.append(attestation) + for slot in range(spec.SLOTS_PER_EPOCH + spec.MIN_ATTESTATION_INCLUSION_DELAY): + # create an attestation for each slot in epoch + if slot < spec.SLOTS_PER_EPOCH: + attestation = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, attestation, signed=True) + attestations.append(attestation) + # fill each created slot in state after inclusion delay + if slot - spec.MIN_ATTESTATION_INCLUSION_DELAY >= 0: + include_att = attestations[slot - spec.MIN_ATTESTATION_INCLUSION_DELAY] + add_attestations_to_state(spec, state, [include_att], state.slot) next_slot(spec, state) - add_attestations_to_state(spec, state, attestations, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH + 1 + assert len(state.previous_epoch_attestations) == spec.SLOTS_PER_EPOCH pre_state = deepcopy(state) @@ -70,8 +76,11 @@ def test_full_attestations(spec, state): attesting_indices = spec.get_unslashed_attesting_indices(state, attestations) assert len(attesting_indices) > 0 - for index in attesting_indices: - assert state.balances[index] > pre_state.balances[index] + for index in range(len(pre_state.validators)): + if index in attesting_indices: + assert state.balances[index] > pre_state.balances[index] + else: + assert state.balances[index] < pre_state.balances[index] @with_all_phases From 16887215541b416a74edf8f5fcb5b809091352e8 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Sun, 22 Sep 2019 09:54:17 -0500 Subject: [PATCH 6/8] fix up attesation reward tests --- .../test_process_rewards_and_penalties.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py index 114898abf..40f6d781e 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py @@ -34,13 +34,19 @@ def test_genesis_epoch_no_attestations_no_penalties(spec, state): @spec_state_test def test_genesis_epoch_full_attestations_no_rewards(spec, state): attestations = [] - for slot in range(spec.SLOTS_PER_EPOCH - spec.MIN_ATTESTATION_INCLUSION_DELAY - 1): - attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation, signed=True) - attestations.append(attestation) + for slot in range(spec.SLOTS_PER_EPOCH - 1): + # create an attestation for each slot + if slot < spec.SLOTS_PER_EPOCH: + attestation = get_valid_attestation(spec, state) + fill_aggregate_attestation(spec, state, attestation, signed=True) + attestations.append(attestation) + # fill each created slot in state after inclusion delay + if slot - spec.MIN_ATTESTATION_INCLUSION_DELAY >= 0: + include_att = attestations[slot - spec.MIN_ATTESTATION_INCLUSION_DELAY] + add_attestations_to_state(spec, state, [include_att], state.slot) next_slot(spec, state) - add_attestations_to_state(spec, state, attestations, state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) + # ensure has not cross the epoch boundary assert spec.compute_epoch_of_slot(state.slot) == spec.GENESIS_EPOCH pre_state = deepcopy(state) From a6e543fd37110eaaaba9bb1521e9c28982159e86 Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 24 Sep 2019 12:24:20 +0900 Subject: [PATCH 7/8] just signing, attestations are already filled by get_valid_attestation --- .../test_process_crosslinks.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py index 83e2bb017..18dd3ce81 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_crosslinks.py @@ -8,9 +8,8 @@ from eth2spec.test.helpers.state import ( from eth2spec.test.helpers.block import apply_empty_block from eth2spec.test.helpers.attestations import ( add_attestations_to_state, - fill_aggregate_attestation, get_valid_attestation, -) + sign_attestation) from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with @@ -32,9 +31,8 @@ def test_no_attestations(spec, state): def test_single_crosslink_update_from_current_epoch(spec, state): next_epoch(spec, state) - attestation = get_valid_attestation(spec, state) + attestation = get_valid_attestation(spec, state, signed=True) - fill_aggregate_attestation(spec, state, attestation, signed=True) add_attestations_to_state(spec, state, [attestation], state.slot + spec.MIN_ATTESTATION_INCLUSION_DELAY) assert len(state.current_epoch_attestations) == 1 @@ -53,9 +51,8 @@ def test_single_crosslink_update_from_current_epoch(spec, state): def test_single_crosslink_update_from_previous_epoch(spec, state): next_epoch(spec, state) - attestation = get_valid_attestation(spec, state) + attestation = get_valid_attestation(spec, state, signed=True) - fill_aggregate_attestation(spec, state, attestation, signed=True) add_attestations_to_state(spec, state, [attestation], state.slot + spec.SLOTS_PER_EPOCH) assert len(state.previous_epoch_attestations) == 1 @@ -89,8 +86,7 @@ def test_double_late_crosslink(spec, state): next_epoch(spec, state) state.slot += 4 - attestation_1 = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation_1, signed=True) + attestation_1 = get_valid_attestation(spec, state, signed=True) # add attestation_1 to next epoch next_epoch(spec, state) @@ -99,7 +95,7 @@ def test_double_late_crosslink(spec, state): for _ in range(spec.SLOTS_PER_EPOCH): attestation_2 = get_valid_attestation(spec, state) if attestation_2.data.crosslink.shard == attestation_1.data.crosslink.shard: - fill_aggregate_attestation(spec, state, attestation_2, signed=True) + sign_attestation(spec, state, attestation_2) break next_slot(spec, state) apply_empty_block(spec, state) @@ -139,7 +135,7 @@ def test_tied_crosslink_between_epochs(spec, state): Ensure that ties on crosslinks between epochs are broken by previous epoch. """ prev_attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, prev_attestation, signed=True) + sign_attestation(spec, state, prev_attestation) # add attestation at start of next epoch next_epoch(spec, state) @@ -149,7 +145,7 @@ def test_tied_crosslink_between_epochs(spec, state): for _ in range(spec.SLOTS_PER_EPOCH): cur_attestation = get_valid_attestation(spec, state) if cur_attestation.data.crosslink.shard == prev_attestation.data.crosslink.shard: - fill_aggregate_attestation(spec, state, cur_attestation, signed=True) + sign_attestation(spec, state, cur_attestation) break next_slot(spec, state) From 525d7330334435c3ff05cd9c1a7a9a58398218be Mon Sep 17 00:00:00 2001 From: protolambda Date: Tue, 24 Sep 2019 13:56:29 +0900 Subject: [PATCH 8/8] rewards testing now with cleaner attestation signing --- .../test_process_rewards_and_penalties.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py index 40f6d781e..0d2547436 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_rewards_and_penalties.py @@ -7,7 +7,6 @@ from eth2spec.test.helpers.state import ( ) from eth2spec.test.helpers.attestations import ( add_attestations_to_state, - fill_aggregate_attestation, get_valid_attestation, ) from eth2spec.test.phase_0.epoch_processing.run_epoch_process_base import run_epoch_processing_with @@ -37,8 +36,7 @@ def test_genesis_epoch_full_attestations_no_rewards(spec, state): for slot in range(spec.SLOTS_PER_EPOCH - 1): # create an attestation for each slot if slot < spec.SLOTS_PER_EPOCH: - attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation, signed=True) + attestation = get_valid_attestation(spec, state, signed=True) attestations.append(attestation) # fill each created slot in state after inclusion delay if slot - spec.MIN_ATTESTATION_INCLUSION_DELAY >= 0: @@ -64,8 +62,7 @@ def test_full_attestations(spec, state): for slot in range(spec.SLOTS_PER_EPOCH + spec.MIN_ATTESTATION_INCLUSION_DELAY): # create an attestation for each slot in epoch if slot < spec.SLOTS_PER_EPOCH: - attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation, signed=True) + attestation = get_valid_attestation(spec, state, signed=True) attestations.append(attestation) # fill each created slot in state after inclusion delay if slot - spec.MIN_ATTESTATION_INCLUSION_DELAY >= 0: @@ -112,8 +109,7 @@ def test_duplicate_attestation(spec, state): This test addresses this issue found at Interop https://github.com/djrtwo/interop-test-cases/tree/master/tests/prysm_16_duplicate_attestation_rewards """ - attestation = get_valid_attestation(spec, state) - fill_aggregate_attestation(spec, state, attestation, signed=True) + attestation = get_valid_attestation(spec, state, signed=True) indexed_attestation = spec.get_indexed_attestation(state, attestation) participants = indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices @@ -131,7 +127,8 @@ def test_duplicate_attestation(spec, state): next_epoch(spec, dup_state) # Run non-duplicate inclusion rewards for comparision. Do not yield test vectors - pre, post = run_process_rewards_and_penalties(spec, single_state) + for _ in run_process_rewards_and_penalties(spec, single_state): + pass # Output duplicate inclusion to test vectors yield from run_process_rewards_and_penalties(spec, dup_state)