From 8d5d7387f959e6393da5b29684d52ae04e64722f Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 12 Dec 2019 02:36:20 +0100 Subject: [PATCH 1/3] Two tests for proposer indices being off because of active validators status, fixes #1515 --- .../eth2spec/test/sanity/test_blocks.py | 52 ++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py index 41316e92d..3c42446cb 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py @@ -3,7 +3,7 @@ from copy import deepcopy from eth2spec.utils.ssz.ssz_impl import hash_tree_root from eth2spec.utils.bls import bls_sign -from eth2spec.test.helpers.state import get_balance, state_transition_and_sign_block +from eth2spec.test.helpers.state import get_balance, state_transition_and_sign_block, next_slot from eth2spec.test.helpers.block import build_empty_block_for_next_slot, build_empty_block, sign_block, \ transition_unsigned_block from eth2spec.test.helpers.keys import privkeys, pubkeys @@ -253,6 +253,56 @@ def test_attester_slashing(spec, state): ) +@with_all_phases +@spec_state_test +def test_proposer_after_inactive_index(spec, state): + # disable some low validator index to check after for + inactive_index = 10 + state.validators[inactive_index].exit_epoch = spec.get_current_epoch(state) + + # skip forward, get brand new proposers + state.slot = spec.SLOTS_PER_EPOCH * 2 + + while True: + proposer_index = spec.get_beacon_proposer_index(state) + if proposer_index > inactive_index: + # found a proposer that has a higher index than a disabled validator + yield 'pre', state + # test if the proposer can be recognized correctly after the inactive validator + signed_block = sign_block(spec, state, build_empty_block(spec, state), proposer_index=proposer_index) + yield 'blocks', [signed_block] + yield 'post', state + break + else: + next_slot(spec, state) + + +@with_all_phases +@spec_state_test +def test_high_proposer_index(spec, state): + # disable a good amount of validators to make the active count lower, for a faster test + current_epoch = spec.get_current_epoch(state) + for i in range(len(state.validators) // 3): + state.validators[i].exit_epoch = current_epoch + + # skip forward, get brand new proposers + state.slot = spec.SLOTS_PER_EPOCH * 2 + + active_count = len(spec.get_active_validator_indices(state, current_epoch)) + while True: + proposer_index = spec.get_beacon_proposer_index(state) + if proposer_index >= active_count: + # found a proposer that has a higher index than the active validator count + yield 'pre', state + # test if the proposer can be recognized correctly, even while it has a high index. + signed_block = sign_block(spec, state, build_empty_block(spec, state), proposer_index=proposer_index) + yield 'blocks', [signed_block] + yield 'post', state + break + else: + next_slot(spec, state) + + @with_all_phases @spec_state_test def test_expected_deposit_in_block(spec, state): From 020dbb1ecd3ac29f7e8e0a0beae304f5769c4304 Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 12 Dec 2019 16:16:52 +0100 Subject: [PATCH 2/3] fix missing transition --- test_libs/pyspec/eth2spec/test/sanity/test_blocks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py index 3c42446cb..2c08a88fe 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py @@ -269,7 +269,7 @@ def test_proposer_after_inactive_index(spec, state): # found a proposer that has a higher index than a disabled validator yield 'pre', state # test if the proposer can be recognized correctly after the inactive validator - signed_block = sign_block(spec, state, build_empty_block(spec, state), proposer_index=proposer_index) + signed_block = state_transition_and_sign_block(spec, state, build_empty_block(spec, state)) yield 'blocks', [signed_block] yield 'post', state break @@ -295,7 +295,7 @@ def test_high_proposer_index(spec, state): # found a proposer that has a higher index than the active validator count yield 'pre', state # test if the proposer can be recognized correctly, even while it has a high index. - signed_block = sign_block(spec, state, build_empty_block(spec, state), proposer_index=proposer_index) + signed_block = state_transition_and_sign_block(spec, state, build_empty_block(spec, state)) yield 'blocks', [signed_block] yield 'post', state break From 020af2707ac5c26e2753cc69f8a02af5086543eb Mon Sep 17 00:00:00 2001 From: protolambda Date: Thu, 12 Dec 2019 16:40:57 +0100 Subject: [PATCH 3/3] fix: don't get stuck in same slot doing a transition, and clean up latest-block-header with starting block for pre-state --- test_libs/pyspec/eth2spec/test/sanity/test_blocks.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py index 2c08a88fe..c2f980ba0 100644 --- a/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py +++ b/test_libs/pyspec/eth2spec/test/sanity/test_blocks.py @@ -262,8 +262,11 @@ def test_proposer_after_inactive_index(spec, state): # skip forward, get brand new proposers state.slot = spec.SLOTS_PER_EPOCH * 2 + block = build_empty_block_for_next_slot(spec, state) + state_transition_and_sign_block(spec, state, block) while True: + next_slot(spec, state) proposer_index = spec.get_beacon_proposer_index(state) if proposer_index > inactive_index: # found a proposer that has a higher index than a disabled validator @@ -273,8 +276,6 @@ def test_proposer_after_inactive_index(spec, state): yield 'blocks', [signed_block] yield 'post', state break - else: - next_slot(spec, state) @with_all_phases @@ -287,9 +288,12 @@ def test_high_proposer_index(spec, state): # skip forward, get brand new proposers state.slot = spec.SLOTS_PER_EPOCH * 2 + block = build_empty_block_for_next_slot(spec, state) + state_transition_and_sign_block(spec, state, block) active_count = len(spec.get_active_validator_indices(state, current_epoch)) while True: + next_slot(spec, state) proposer_index = spec.get_beacon_proposer_index(state) if proposer_index >= active_count: # found a proposer that has a higher index than the active validator count @@ -299,8 +303,6 @@ def test_high_proposer_index(spec, state): yield 'blocks', [signed_block] yield 'post', state break - else: - next_slot(spec, state) @with_all_phases