From 1644ae61255ce25ddc318a299ab0a67e42b068ee Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 10 Jul 2019 16:46:59 +0800 Subject: [PATCH 01/15] Clarify the illegal types --- specs/simple-serialize.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/simple-serialize.md b/specs/simple-serialize.md index 8efd08c0a..0419a524e 100644 --- a/specs/simple-serialize.md +++ b/specs/simple-serialize.md @@ -89,7 +89,7 @@ An SSZ object is called empty (and thus, `is_empty(object)` returns true) if it ### Illegal types -Empty vector types (i.e. `[subtype, 0]` for some `subtype`) are not legal. The `null` type is only legal as the first type in a union subtype (i.e. with type index zero). +The empty `List[subtype, N]`, `Vector[subtype, N]`, `Bitlist[N]`, and `Bitvector[N]` types, where `N == 0` are not legal. The `null` type is only legal as the first type in a union subtype (i.e. with type index zero). ## Serialization From 25ec084cc58e97f9c797068c1cd65013b8b7e0be Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Wed, 10 Jul 2019 17:20:50 +0800 Subject: [PATCH 02/15] To fit in `MAX_TRANSFERS=0` case --- specs/simple-serialize.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/specs/simple-serialize.md b/specs/simple-serialize.md index 0419a524e..db7b5ad75 100644 --- a/specs/simple-serialize.md +++ b/specs/simple-serialize.md @@ -89,7 +89,7 @@ An SSZ object is called empty (and thus, `is_empty(object)` returns true) if it ### Illegal types -The empty `List[subtype, N]`, `Vector[subtype, N]`, `Bitlist[N]`, and `Bitvector[N]` types, where `N == 0` are not legal. The `null` type is only legal as the first type in a union subtype (i.e. with type index zero). +The empty `Vector[subtype, N]` and `Bitvector[N]` types, where `N == 0` are not legal. The `null` type is only legal as the first type in a union subtype (i.e. with type index zero). ## Serialization From 01af3044032735fa9266d08656090f1bc1e09351 Mon Sep 17 00:00:00 2001 From: protolambda Date: Sat, 20 Jul 2019 02:13:31 +0200 Subject: [PATCH 03/15] =?UTF-8?q?Found=20by=20Cem=20=C3=96zer:=20Ignore=20?= =?UTF-8?q?older=20latest=20messages=20in=20attesting=20balance=20sum,=20i?= =?UTF-8?q?nstead=20of=20assertion=20error?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- specs/core/0_fork-choice.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/specs/core/0_fork-choice.md b/specs/core/0_fork-choice.md index 9fd8ab53e..00374fee9 100644 --- a/specs/core/0_fork-choice.md +++ b/specs/core/0_fork-choice.md @@ -101,8 +101,12 @@ def get_genesis_store(genesis_state: BeaconState) -> Store: ```python def get_ancestor(store: Store, root: Hash, slot: Slot) -> Hash: block = store.blocks[root] - assert block.slot >= slot - return root if block.slot == slot else get_ancestor(store, block.parent_root, slot) + if block.slot > slot: + return get_ancestor(store, block.parent_root, slot) + elif block.slot == slot: + return root + else: + return Bytes32() # root is older than queried slot: no results. ``` #### `get_latest_attesting_balance` From 43a0ca4eebf0532a130b8273a3c85e90e845bb34 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Mon, 22 Jul 2019 07:13:07 -0600 Subject: [PATCH 04/15] check bit lengths --- specs/core/0_beacon-chain.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f0169f1d2..c17815ee8 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1654,6 +1654,9 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: attestation_slot = get_attestation_data_slot(state, data) assert attestation_slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= attestation_slot + SLOTS_PER_EPOCH + assert len(attestation.aggregation_bits) == len(committee) + assert len(attestation.custody_bits) == len(committee) + pending_attestation = PendingAttestation( data=data, aggregation_bits=attestation.aggregation_bits, From f229d21faae0e59e9769ed361ffc39d30be84a3e Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 11 Jul 2019 20:51:34 +0800 Subject: [PATCH 05/15] Bump `py-ssz` to `0.1.0a11` and update the fuzzing tests --- test_libs/pyspec/eth2spec/fuzzing/decoder.py | 6 +++--- test_libs/pyspec/eth2spec/fuzzing/test_decoder.py | 4 +--- test_libs/pyspec/requirements.txt | 2 +- test_libs/pyspec/setup.py | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test_libs/pyspec/eth2spec/fuzzing/decoder.py b/test_libs/pyspec/eth2spec/fuzzing/decoder.py index ccca17385..e3b4de318 100644 --- a/test_libs/pyspec/eth2spec/fuzzing/decoder.py +++ b/test_libs/pyspec/eth2spec/fuzzing/decoder.py @@ -19,13 +19,13 @@ def translate_typ(typ) -> ssz.BaseSedes: return ssz.Vector(translate_typ(typ.elem_type), typ.length) elif issubclass(typ, spec_ssz.List): # TODO: Make py-ssz List support the new fixed length list - return ssz.List(translate_typ(typ.elem_type)) + return ssz.List(translate_typ(typ.elem_type), typ.length) elif issubclass(typ, spec_ssz.Bitlist): # TODO: Once Bitlist implemented in py-ssz, use appropriate type - return ssz.List(translate_typ(typ.elem_type)) + return ssz.Bitlist(typ.length) elif issubclass(typ, spec_ssz.Bitvector): # TODO: Once Bitvector implemented in py-ssz, use appropriate type - return ssz.Vector(translate_typ(typ.elem_type), typ.length) + return ssz.Bitvector(typ.length) elif issubclass(typ, spec_ssz.boolean): return ssz.boolean elif issubclass(typ, spec_ssz.uint): diff --git a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py index ea1f1d47f..e68133bd6 100644 --- a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py +++ b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py @@ -9,9 +9,7 @@ def test_decoder(): rng = Random(123) # check these types only, Block covers a lot of operation types already. - # TODO: Once has Bitlists and Bitvectors, add back - # spec.BeaconState and spec.BeaconBlock - for typ in [spec.IndexedAttestation, spec.AttestationDataAndCustodyBit]: + for typ in [spec.BeaconState, spec.BeaconBlock]: # create a random pyspec value original = random_value.get_random_ssz_object(rng, typ, 100, 10, mode=random_value.RandomizationMode.mode_random, diff --git a/test_libs/pyspec/requirements.txt b/test_libs/pyspec/requirements.txt index 713b4331a..5aeea4cab 100644 --- a/test_libs/pyspec/requirements.txt +++ b/test_libs/pyspec/requirements.txt @@ -3,4 +3,4 @@ eth-typing>=2.1.0,<3.0.0 pycryptodome==3.7.3 py_ecc==1.7.1 dataclasses==0.6 -ssz==0.1.0a10 +ssz==0.1.0a11 diff --git a/test_libs/pyspec/setup.py b/test_libs/pyspec/setup.py index 07e538e80..9bdbdb2e9 100644 --- a/test_libs/pyspec/setup.py +++ b/test_libs/pyspec/setup.py @@ -9,7 +9,7 @@ setup( "eth-typing>=2.1.0,<3.0.0", "pycryptodome==3.7.3", "py_ecc==1.7.1", - "ssz==0.1.0a10", + "ssz==0.1.0a11", "dataclasses==0.6", ] ) From b08ecb018a97a5a50581e4fcac218f7c65f46360 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 13 Jul 2019 12:29:08 +0800 Subject: [PATCH 06/15] Apply suggestions from code review Co-Authored-By: Diederik Loerakker --- test_libs/pyspec/eth2spec/fuzzing/decoder.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/test_libs/pyspec/eth2spec/fuzzing/decoder.py b/test_libs/pyspec/eth2spec/fuzzing/decoder.py index e3b4de318..272ed0c44 100644 --- a/test_libs/pyspec/eth2spec/fuzzing/decoder.py +++ b/test_libs/pyspec/eth2spec/fuzzing/decoder.py @@ -18,13 +18,10 @@ def translate_typ(typ) -> ssz.BaseSedes: elif issubclass(typ, spec_ssz.Vector): return ssz.Vector(translate_typ(typ.elem_type), typ.length) elif issubclass(typ, spec_ssz.List): - # TODO: Make py-ssz List support the new fixed length list return ssz.List(translate_typ(typ.elem_type), typ.length) elif issubclass(typ, spec_ssz.Bitlist): - # TODO: Once Bitlist implemented in py-ssz, use appropriate type return ssz.Bitlist(typ.length) elif issubclass(typ, spec_ssz.Bitvector): - # TODO: Once Bitvector implemented in py-ssz, use appropriate type return ssz.Bitvector(typ.length) elif issubclass(typ, spec_ssz.boolean): return ssz.boolean From db9091f507a8a83a37b0c3ae4c3ecde4e9c68c8c Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Sat, 13 Jul 2019 12:31:41 +0800 Subject: [PATCH 07/15] Add `AttestationDataAndCustodyBit` back --- test_libs/pyspec/eth2spec/fuzzing/test_decoder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py index e68133bd6..c38fd69af 100644 --- a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py +++ b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py @@ -9,7 +9,7 @@ def test_decoder(): rng = Random(123) # check these types only, Block covers a lot of operation types already. - for typ in [spec.BeaconState, spec.BeaconBlock]: + for typ in [spec.AttestationDataAndCustodyBit, spec.BeaconState, spec.BeaconBlock]: # create a random pyspec value original = random_value.get_random_ssz_object(rng, typ, 100, 10, mode=random_value.RandomizationMode.mode_random, From 82e2c559ca0d382c734b2abcf9f9196c6a491794 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Mon, 15 Jul 2019 11:33:09 +0800 Subject: [PATCH 08/15] ssz==0.1.3 --- test_generators/ssz_generic/requirements.txt | 2 +- test_libs/pyspec/requirements.txt | 2 +- test_libs/pyspec/setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test_generators/ssz_generic/requirements.txt b/test_generators/ssz_generic/requirements.txt index dcdb0824f..94c019c4e 100644 --- a/test_generators/ssz_generic/requirements.txt +++ b/test_generators/ssz_generic/requirements.txt @@ -1,4 +1,4 @@ eth-utils==1.6.0 ../../test_libs/gen_helpers ../../test_libs/config_helpers -ssz==0.1.0a2 +ssz==0.1.3 diff --git a/test_libs/pyspec/requirements.txt b/test_libs/pyspec/requirements.txt index 5aeea4cab..480602779 100644 --- a/test_libs/pyspec/requirements.txt +++ b/test_libs/pyspec/requirements.txt @@ -3,4 +3,4 @@ eth-typing>=2.1.0,<3.0.0 pycryptodome==3.7.3 py_ecc==1.7.1 dataclasses==0.6 -ssz==0.1.0a11 +ssz==0.1.3 diff --git a/test_libs/pyspec/setup.py b/test_libs/pyspec/setup.py index 9bdbdb2e9..94575f2a1 100644 --- a/test_libs/pyspec/setup.py +++ b/test_libs/pyspec/setup.py @@ -9,7 +9,7 @@ setup( "eth-typing>=2.1.0,<3.0.0", "pycryptodome==3.7.3", "py_ecc==1.7.1", - "ssz==0.1.0a11", + "ssz==0.1.3", "dataclasses==0.6", ] ) From 62138fed347aed04833e7c25d2a4aa802ae4cfb2 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 25 Jul 2019 17:26:27 +0800 Subject: [PATCH 09/15] Update Illegal types --- specs/simple-serialize.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/specs/simple-serialize.md b/specs/simple-serialize.md index e62dbcd7f..cfc1a4aa2 100644 --- a/specs/simple-serialize.md +++ b/specs/simple-serialize.md @@ -75,7 +75,7 @@ For convenience we alias: * `bit` to `boolean` * `byte` to `uint8` (this is a basic type) * `BytesN` to `Vector[byte, N]` (this is *not* a basic type) -* `null`: `{}`, i.e. the empty container +* `null`: `{}` ### Default values @@ -87,7 +87,9 @@ An SSZ object is called empty (and thus, `is_empty(object)` returns true) if it ### Illegal types -The empty `Vector[subtype, N]` and `Bitvector[N]` types, where `N == 0` are not legal. The `null` type is only legal as the first type in a union subtype (i.e. with type index zero). +- Empty vector types (`Vector[type, 0]`, `Bitvector[0]`) are illegal. +- Containers with no fields are illegal. +- The `null` type is only legal as the first type in a union subtype (i.e. with type index zero). ## Serialization From f336e7ffb33e736b6f201d98562c833e1e0b5611 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 25 Jul 2019 17:32:27 +0800 Subject: [PATCH 10/15] Rename `is_empty` to `is_zero` --- scripts/build_spec.py | 2 +- specs/core/1_custody-game.md | 2 +- specs/simple-serialize.md | 6 +++--- test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/build_spec.py b/scripts/build_spec.py index 8b541ff50..c221a5fba 100644 --- a/scripts/build_spec.py +++ b/scripts/build_spec.py @@ -49,7 +49,7 @@ from eth2spec.utils.ssz.ssz_impl import ( hash_tree_root, signing_root, serialize, - is_empty, + is_zero, ) from eth2spec.utils.ssz.ssz_typing import ( bit, boolean, Container, List, Vector, Bytes, uint64, diff --git a/specs/core/1_custody-game.md b/specs/core/1_custody-game.md index f79977442..63900681e 100644 --- a/specs/core/1_custody-game.md +++ b/specs/core/1_custody-game.md @@ -328,7 +328,7 @@ def get_reveal_period(state: BeaconState, validator_index: ValidatorIndex, epoch ```python def replace_empty_or_append(list: MutableSequence[Any], new_element: Any) -> int: for i in range(len(list)): - if is_empty(list[i]): + if is_zero(list[i]): list[i] = new_element return i list.append(new_element) diff --git a/specs/simple-serialize.md b/specs/simple-serialize.md index cfc1a4aa2..f479c5d00 100644 --- a/specs/simple-serialize.md +++ b/specs/simple-serialize.md @@ -14,7 +14,7 @@ - [Variable-size and fixed-size](#variable-size-and-fixed-size) - [Aliases](#aliases) - [Default values](#default-values) - - [`is_empty`](#is_empty) + - [`is_zero`](#is_zero) - [Illegal types](#illegal-types) - [Serialization](#serialization) - [`uintN`](#uintn) @@ -81,9 +81,9 @@ For convenience we alias: The default value of a type upon initialization is recursively defined using `0` for `uintN`, `False` for `boolean` and the elements of `Bitvector`, and `[]` for lists and `Bitlist`. Unions default to the first type in the union (with type index zero), which is `null` if present in the union. -#### `is_empty` +#### `is_zero` -An SSZ object is called empty (and thus, `is_empty(object)` returns true) if it is equal to the default value for that type. +An SSZ object is called zeroed (and thus, `is_zero(object)` returns true) if it is equal to the default value for that type. ### Illegal types diff --git a/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py b/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py index b005f2456..748386733 100644 --- a/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py +++ b/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py @@ -33,7 +33,7 @@ def deserialize_basic(value, typ: BasicType): raise Exception(f"Type not supported: {typ}") -def is_empty(obj: SSZValue): +def is_zero(obj: SSZValue): return type(obj).default() == obj From 47714cbf64026ecf74dee52601e9a8c5d7923cc5 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 25 Jul 2019 00:17:43 +0800 Subject: [PATCH 11/15] Add hash_tree_root tests against py-ssz --- test_libs/pyspec/eth2spec/fuzzing/test_decoder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py index c38fd69af..3c3afa975 100644 --- a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py +++ b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py @@ -31,3 +31,4 @@ def test_decoder(): # and see if the hash-tree-root of the original matches the hash-tree-root of the decoded & translated value. assert spec_ssz_impl.hash_tree_root(original) == spec_ssz_impl.hash_tree_root(block) + assert spec_ssz_impl.hash_tree_root(original) == block_sedes.get_hash_tree_root(raw_value) From 62772c9e79cea51278ecb16bd931c6e1d3b26498 Mon Sep 17 00:00:00 2001 From: Hsiao-Wei Wang Date: Thu, 25 Jul 2019 19:41:12 +0800 Subject: [PATCH 12/15] Refactor --- test_libs/pyspec/eth2spec/fuzzing/test_decoder.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py index 3c3afa975..77b52e7a2 100644 --- a/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py +++ b/test_libs/pyspec/eth2spec/fuzzing/test_decoder.py @@ -30,5 +30,6 @@ def test_decoder(): block = translate_value(raw_value, typ) # and see if the hash-tree-root of the original matches the hash-tree-root of the decoded & translated value. - assert spec_ssz_impl.hash_tree_root(original) == spec_ssz_impl.hash_tree_root(block) - assert spec_ssz_impl.hash_tree_root(original) == block_sedes.get_hash_tree_root(raw_value) + original_hash_tree_root = spec_ssz_impl.hash_tree_root(original) + assert original_hash_tree_root == spec_ssz_impl.hash_tree_root(block) + assert original_hash_tree_root == block_sedes.get_hash_tree_root(raw_value) From bd69dc7e3cb3db2ba74b9b39afb5f572b30f0d73 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 25 Jul 2019 12:28:29 -0600 Subject: [PATCH 13/15] add tests for bit lengths --- specs/core/0_beacon-chain.md | 1 + .../test_process_attestation.py | 58 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index c17815ee8..1822ca5a9 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1654,6 +1654,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: attestation_slot = get_attestation_data_slot(state, data) assert attestation_slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= attestation_slot + SLOTS_PER_EPOCH + committee = get_crosslink_committee(state, data.target.epoch, data.crosslink.shard) assert len(attestation.aggregation_bits) == len(committee) assert len(attestation.custody_bits) == len(committee) diff --git a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py index ab46a0d8c..39b5d03c2 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/block_processing/test_process_attestation.py @@ -398,3 +398,61 @@ def test_empty_aggregation_bits(spec, state): sign_attestation(spec, state, attestation) yield from run_attestation_processing(spec, state, attestation) + + +@with_all_phases +@spec_state_test +def test_too_many_aggregation_bits(spec, state): + attestation = get_valid_attestation(spec, state, signed=True) + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY + + # one too many bits + attestation.aggregation_bits.append(0b0) + + yield from run_attestation_processing(spec, state, attestation, False) + + +@with_all_phases +@spec_state_test +def test_too_few_aggregation_bits(spec, state): + attestation = get_valid_attestation(spec, state) + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY + + attestation.aggregation_bits = Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE]( + *([0b1] + [0b0] * (len(attestation.aggregation_bits) - 1))) + + sign_attestation(spec, state, attestation) + + # one too few bits + attestation.aggregation_bits = attestation.aggregation_bits[:-1] + + yield from run_attestation_processing(spec, state, attestation, False) + + +@with_all_phases +@spec_state_test +def test_too_many_custody_bits(spec, state): + attestation = get_valid_attestation(spec, state, signed=True) + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY + + # one too many bits + attestation.custody_bits.append(0b0) + + yield from run_attestation_processing(spec, state, attestation, False) + + +@with_all_phases +@spec_state_test +def test_too_few_custody_bits(spec, state): + attestation = get_valid_attestation(spec, state) + state.slot += spec.MIN_ATTESTATION_INCLUSION_DELAY + + attestation.custody_bits = Bitlist[spec.MAX_VALIDATORS_PER_COMMITTEE]( + *([0b1] + [0b0] * (len(attestation.custody_bits) - 1))) + + sign_attestation(spec, state, attestation) + + # one too few bits + attestation.custody_bits = attestation.custody_bits[:-1] + + yield from run_attestation_processing(spec, state, attestation, False) From 3f75f1e2c36460fe19741b82a36f29199b0c1e50 Mon Sep 17 00:00:00 2001 From: Justin Date: Thu, 25 Jul 2019 19:32:56 +0100 Subject: [PATCH 14/15] Update 0_beacon-chain.md --- specs/core/0_beacon-chain.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index 1822ca5a9..2dfc3d570 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1655,8 +1655,7 @@ def process_attestation(state: BeaconState, attestation: Attestation) -> None: assert attestation_slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot <= attestation_slot + SLOTS_PER_EPOCH committee = get_crosslink_committee(state, data.target.epoch, data.crosslink.shard) - assert len(attestation.aggregation_bits) == len(committee) - assert len(attestation.custody_bits) == len(committee) + assert len(attestation.aggregation_bits) == len(attestation.custody_bits) == len(committee) pending_attestation = PendingAttestation( data=data, From 1ec20f6c1f7ee2b30ad0b94179b29b2702dc5ce3 Mon Sep 17 00:00:00 2001 From: Danny Ryan Date: Thu, 25 Jul 2019 12:59:38 -0600 Subject: [PATCH 15/15] do not reset start_shard until after processing compact root --- specs/core/0_beacon-chain.md | 4 ++-- .../test_process_final_updates.py | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/specs/core/0_beacon-chain.md b/specs/core/0_beacon-chain.md index f0169f1d2..46702abd2 100644 --- a/specs/core/0_beacon-chain.md +++ b/specs/core/0_beacon-chain.md @@ -1504,8 +1504,6 @@ def process_final_updates(state: BeaconState) -> None: HALF_INCREMENT = EFFECTIVE_BALANCE_INCREMENT // 2 if balance < validator.effective_balance or validator.effective_balance + 3 * HALF_INCREMENT < balance: validator.effective_balance = min(balance - balance % EFFECTIVE_BALANCE_INCREMENT, MAX_EFFECTIVE_BALANCE) - # Update start shard - state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT) # Set active index root index_epoch = Epoch(next_epoch + ACTIVATION_EXIT_DELAY) index_root_position = index_epoch % EPOCHS_PER_HISTORICAL_VECTOR @@ -1522,6 +1520,8 @@ def process_final_updates(state: BeaconState) -> None: if next_epoch % (SLOTS_PER_HISTORICAL_ROOT // SLOTS_PER_EPOCH) == 0: historical_batch = HistoricalBatch(block_roots=state.block_roots, state_roots=state.state_roots) state.historical_roots.append(hash_tree_root(historical_batch)) + # Update start shard + state.start_shard = Shard((state.start_shard + get_shard_delta(state, current_epoch)) % SHARD_COUNT) # Rotate current/previous epoch attestations state.previous_epoch_attestations = state.current_epoch_attestations state.current_epoch_attestations = [] diff --git a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py index 58882a44f..385cc289b 100644 --- a/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py +++ b/test_libs/pyspec/eth2spec/test/phase_0/epoch_processing/test_process_final_updates.py @@ -89,3 +89,20 @@ def test_historical_root_accumulator(spec, state): yield from run_process_final_updates(spec, state) assert len(state.historical_roots) == history_len + 1 + + +@with_all_phases +@spec_state_test +def test_compact_committees_root(spec, state): + assert spec.SLOTS_PER_ETH1_VOTING_PERIOD > spec.SLOTS_PER_EPOCH + # skip ahead to the end of the epoch + state.slot = spec.SLOTS_PER_EPOCH - 1 + + next_epoch = spec.get_current_epoch(state) + 1 + + # ensure that order in which items are processed in final_updates + # does not alter the expected_root + expected_root = spec.get_compact_committees_root(state, next_epoch) + yield from run_process_final_updates(spec, state) + + assert state.compact_committees_roots[next_epoch % spec.EPOCHS_PER_HISTORICAL_VECTOR] == expected_root