From dde49cbedafa4301f33dea56ad0830d866ae5a57 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Wed, 20 Mar 2019 08:47:41 -0600 Subject: [PATCH 1/4] fix and extend header tests --- .../test_process_block_header.py | 90 ++++++++++++++++++- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/tests/phase0/block_processing/test_process_block_header.py b/tests/phase0/block_processing/test_process_block_header.py index 4ec7e336f..650bc387c 100644 --- a/tests/phase0/block_processing/test_process_block_header.py +++ b/tests/phase0/block_processing/test_process_block_header.py @@ -4,6 +4,8 @@ import pytest from build.phase0.spec import ( get_beacon_proposer_index, + cache_state, + advance_slot, process_block_header, ) from tests.phase0.helpers import ( @@ -14,13 +16,93 @@ from tests.phase0.helpers import ( pytestmark = pytest.mark.header -def test_proposer_slashed(state): +def test_sucess(state): + pre_state = deepcopy(state) + block = build_empty_block_for_next_slot(pre_state) + + # + # setup pre_state to be ready for block transition + # + cache_state(pre_state) + advance_slot(pre_state) + + post_state = deepcopy(pre_state) + + # + # test block header + # + process_block_header(post_state, block) + + return state, [block], post_state + + +def test_invalid_slot(state): pre_state = deepcopy(state) + # mess up previous block root block = build_empty_block_for_next_slot(pre_state) - proposer_index = get_beacon_proposer_index(pre_state, block.slot) - pre_state.validator_registry[proposer_index].slashed = True + block.previous_block_root = b'\12'*32 + + # + # setup pre_state advancing two slots to induce error + # + cache_state(pre_state) + advance_slot(pre_state) + advance_slot(pre_state) + + post_state = deepcopy(pre_state) + + # + # test block header + # with pytest.raises(AssertionError): - process_block_header(pre_state, block) + process_block_header(post_state, block) + + return state, [block], None + + +def test_invalid_previous_block_root(state): + pre_state = deepcopy(state) + + # mess up previous block root + block = build_empty_block_for_next_slot(pre_state) + block.previous_block_root = b'\12'*32 + + # + # setup pre_state to be ready for block transition + # + cache_state(pre_state) + advance_slot(pre_state) + + post_state = deepcopy(pre_state) + + # + # test block header + # + with pytest.raises(AssertionError): + process_block_header(post_state, block) + + return state, [block], None + + +def test_proposer_slashed(state): + pre_state = deepcopy(state) + proposer_index = get_beacon_proposer_index(pre_state, pre_state.slot + 1) + pre_state.validator_registry[proposer_index].slashed = True + block = build_empty_block_for_next_slot(pre_state) + + # + # setup pre_state to be ready for block transition + # + cache_state(pre_state) + advance_slot(pre_state) + + post_state = deepcopy(pre_state) + + # + # test block header + # + with pytest.raises(AssertionError): + process_block_header(post_state, block) return state, [block], None From f4012ee309dfa5b238bd55e05acd0c041e8c9280 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Wed, 20 Mar 2019 09:59:29 -0600 Subject: [PATCH 2/4] make process block header tests more modular --- .../test_process_block_header.py | 107 ++++++------------ 1 file changed, 35 insertions(+), 72 deletions(-) diff --git a/tests/phase0/block_processing/test_process_block_header.py b/tests/phase0/block_processing/test_process_block_header.py index 650bc387c..4981b656c 100644 --- a/tests/phase0/block_processing/test_process_block_header.py +++ b/tests/phase0/block_processing/test_process_block_header.py @@ -16,93 +16,56 @@ from tests.phase0.helpers import ( pytestmark = pytest.mark.header -def test_sucess(state): - pre_state = deepcopy(state) - block = build_empty_block_for_next_slot(pre_state) +def prepare_state_for_header_processing(state): + cache_state(state) + advance_slot(state) - # - # setup pre_state to be ready for block transition - # - cache_state(pre_state) - advance_slot(pre_state) - post_state = deepcopy(pre_state) +def run_block_header_processing(state, block, valid=True): + """ + Run ``process_block_header`` returning the pre and post state. + If ``valid == False``, run expecting ``AssertionError`` + """ + prepare_state_for_header_processing(state) + post_state = deepcopy(state) + + if not valid: + with pytest.raises(AssertionError): + process_block_header(post_state, block) + return state, None - # - # test block header - # process_block_header(post_state, block) + return state, post_state - return state, [block], post_state + +def test_success(state): + block = build_empty_block_for_next_slot(state) + pre_state, post_state = run_block_header_processing(state, block) + return state, block, post_state def test_invalid_slot(state): - pre_state = deepcopy(state) + block = build_empty_block_for_next_slot(state) + block.slot = state.slot + 2 # invalid slot - # mess up previous block root - block = build_empty_block_for_next_slot(pre_state) - block.previous_block_root = b'\12'*32 - - # - # setup pre_state advancing two slots to induce error - # - cache_state(pre_state) - advance_slot(pre_state) - advance_slot(pre_state) - - post_state = deepcopy(pre_state) - - # - # test block header - # - with pytest.raises(AssertionError): - process_block_header(post_state, block) - - return state, [block], None + pre_state, post_state = run_block_header_processing(state, block, valid=False) + return pre_state, block, None def test_invalid_previous_block_root(state): - pre_state = deepcopy(state) + block = build_empty_block_for_next_slot(state) + block.previous_block_root = b'\12'*32 # invalid prev root - # mess up previous block root - block = build_empty_block_for_next_slot(pre_state) - block.previous_block_root = b'\12'*32 - - # - # setup pre_state to be ready for block transition - # - cache_state(pre_state) - advance_slot(pre_state) - - post_state = deepcopy(pre_state) - - # - # test block header - # - with pytest.raises(AssertionError): - process_block_header(post_state, block) - - return state, [block], None + pre_state, post_state = run_block_header_processing(state, block, valid=False) + return pre_state, block, None def test_proposer_slashed(state): - pre_state = deepcopy(state) - proposer_index = get_beacon_proposer_index(pre_state, pre_state.slot + 1) - pre_state.validator_registry[proposer_index].slashed = True - block = build_empty_block_for_next_slot(pre_state) + # set proposer to slashed + proposer_index = get_beacon_proposer_index(state, state.slot + 1) + state.validator_registry[proposer_index].slashed = True - # - # setup pre_state to be ready for block transition - # - cache_state(pre_state) - advance_slot(pre_state) + block = build_empty_block_for_next_slot(state) - post_state = deepcopy(pre_state) - - # - # test block header - # - with pytest.raises(AssertionError): - process_block_header(post_state, block) - - return state, [block], None + pre_state, post_state = run_block_header_processing(state, block, valid=False) + return pre_state, block, None From fdcfc910080f283f62926954150a47ffb681224e Mon Sep 17 00:00:00 2001 From: vbuterin Date: Thu, 21 Mar 2019 07:38:25 -0500 Subject: [PATCH 3/4] Add docstring into get_split_offset --- specs/core/0_beacon-chain.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index d32aa1a0e..e198f5c35 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -779,6 +779,10 @@ def get_permuted_index(index: int, list_size: int, seed: Bytes32) -> int: ```python def get_split_offset(list_length: int, split_count: int, index: int) -> int: + """ + Returns a value such that for a list L, chunk count k and index i, + split(L, k)[i] == L[get_split_offset(len(L), k, i): get_split_offset(len(L), k, i + 1)] + """ return (list_length * index) // split_count ``` From fd6d80fcb648a397fc43644199bf78d267d8a988 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 21 Mar 2019 08:24:26 -0600 Subject: [PATCH 4/4] remove get_split_offset from phase 1 doc --- specs/core/0_beacon-chain.md | 12 ++++++------ specs/core/1_shard-data-chains.md | 12 ------------ 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index e198f5c35..1067c3dc0 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -778,12 +778,12 @@ def get_permuted_index(index: int, list_size: int, seed: Bytes32) -> int: ### `get_split_offset` ```python -def get_split_offset(list_length: int, split_count: int, index: int) -> int: - """ - Returns a value such that for a list L, chunk count k and index i, - split(L, k)[i] == L[get_split_offset(len(L), k, i): get_split_offset(len(L), k, i + 1)] - """ - return (list_length * index) // split_count +def get_split_offset(list_size: int, chunks: int, index: int) -> int: + """ + Returns a value such that for a list L, chunk count k and index i, + split(L, k)[i] == L[get_split_offset(len(L), k, i): get_split_offset(len(L), k, i+1)] + """ + return (list_size * index) // chunks ``` ### `get_epoch_committee_count` diff --git a/specs/core/1_shard-data-chains.md b/specs/core/1_shard-data-chains.md index c76f9ba08..92cee4d19 100644 --- a/specs/core/1_shard-data-chains.md +++ b/specs/core/1_shard-data-chains.md @@ -19,7 +19,6 @@ At the current stage, Phase 1, while fundamentally feature-complete, is still su - [Signature domains](#signature-domains) - [Shard chains and crosslink data](#shard-chains-and-crosslink-data) - [Helper functions](#helper-functions) - - [`get_split_offset`](#get_split_offset) - [`get_shuffled_committee`](#get_shuffled_committee) - [`get_persistent_committee`](#get_persistent_committee) - [`get_shard_proposer_index`](#get_shard_proposer_index) @@ -122,17 +121,6 @@ Phase 1 depends upon all of the constants defined in [Phase 0](0_beacon-chain.md ## Helper functions -#### `get_split_offset` - -````python -def get_split_offset(list_size: int, chunks: int, index: int) -> int: - """ - Returns a value such that for a list L, chunk count k and index i, - split(L, k)[i] == L[get_split_offset(len(L), k, i): get_split_offset(len(L), k, i+1)] - """ - return (list_size * index) // chunks -```` - #### `get_shuffled_committee` ```python