From 4deb311b71ea6e1dabe956dc2de374d517d9dc35 Mon Sep 17 00:00:00 2001 From: Carl Beekhuizen Date: Sun, 16 Jun 2019 12:17:31 -0400 Subject: [PATCH] Debugging 1st test --- specs/core/0_fork-choice.md | 7 +- .../pyspec/eth2spec/test/test_finality.py | 334 +++++++++--------- .../pyspec/eth2spec/test/test_fork_choice.py | 2 +- .../pyspec/eth2spec/utils/ssz/ssz_typing.py | 41 +-- 4 files changed, 187 insertions(+), 197 deletions(-) diff --git a/specs/core/0_fork-choice.md b/specs/core/0_fork-choice.md index 3ed794584..3d1e70ca4 100644 --- a/specs/core/0_fork-choice.md +++ b/specs/core/0_fork-choice.md @@ -83,6 +83,7 @@ class Store(Container): def get_genesis_store(genesis_state: BeaconState) -> Store: genesis_block = BeaconBlock(state_root=hash_tree_root(genesis_state)) root = signing_root(genesis_block) + print('groot', root) return Store(blocks={root: genesis_block}, states={root: genesis_state}, finalized_root=root, justified_root=root) ``` @@ -90,6 +91,7 @@ def get_genesis_store(genesis_state: BeaconState) -> Store: ```python def get_ancestor(store: Store, root: Bytes32, slot: Slot) -> Bytes32: + print('ruut', root) block = store.blocks[root] assert block.slot >= slot return root if block.slot == slot else get_ancestor(store, block.parent_root, slot) @@ -135,14 +137,17 @@ def on_tick(store: Store, time: int) -> None: ```python def on_block(store: Store, block: BeaconBlock) -> None: # Add new block to the store + print('setting', signing_root(block)) store.blocks[signing_root(block)] = block # Check block is a descendant of the finalized block assert get_ancestor(store, signing_root(block), store.blocks[store.finalized_root].slot) == store.finalized_root # Check block slot against Unix time pre_state = store.states[block.parent_root].copy() + print('store.states[block.parent_root]', hash_tree_root(store.states[block.parent_root])) assert store.time >= pre_state.genesis_time + block.slot * SECONDS_PER_SLOT # Check the block is valid and compute the post-state state = state_transition(pre_state, block) + print('store.states[block.parent_root]', hash_tree_root(store.states[block.parent_root])) # Add new state to the store store.states[signing_root(block)] = state # Update justified and finalized blocks @@ -150,7 +155,7 @@ def on_block(store: Store, block: BeaconBlock) -> None: store.finalized_root = state.finalized_root if state.current_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot): store.justified_root = state.current_justified_root - if state.previous_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot): + elif state.previous_justified_epoch > slot_to_epoch(store.blocks[store.justified_root].slot): store.justified_root = state.previous_justified_root ``` diff --git a/test_libs/pyspec/eth2spec/test/test_finality.py b/test_libs/pyspec/eth2spec/test/test_finality.py index 801e8b4fd..9556abbd1 100644 --- a/test_libs/pyspec/eth2spec/test/test_finality.py +++ b/test_libs/pyspec/eth2spec/test/test_finality.py @@ -1,203 +1,203 @@ -from copy import deepcopy -from typing import List +# from copy import deepcopy +# from typing import List -from eth2spec.test.context import spec_state_test, never_bls, with_all_phases -from eth2spec.test.helpers.state import next_epoch -from eth2spec.test.helpers.block import build_empty_block_for_next_slot, apply_empty_block -from eth2spec.test.helpers.attestations import get_valid_attestation +# from eth2spec.test.context import spec_state_test, never_bls, with_all_phases +# from eth2spec.test.helpers.state import next_epoch +# from eth2spec.test.helpers.block import build_empty_block_for_next_slot, apply_empty_block +# from eth2spec.test.helpers.attestations import get_valid_attestation -def check_finality(spec, - state, - prev_state, - current_justified_changed, - previous_justified_changed, - finalized_changed): - if current_justified_changed: - assert state.current_justified_epoch > prev_state.current_justified_epoch - assert state.current_justified_root != prev_state.current_justified_root - else: - assert state.current_justified_epoch == prev_state.current_justified_epoch - assert state.current_justified_root == prev_state.current_justified_root +# def check_finality(spec, +# state, +# prev_state, +# current_justified_changed, +# previous_justified_changed, +# finalized_changed): +# if current_justified_changed: +# assert state.current_justified_epoch > prev_state.current_justified_epoch +# assert state.current_justified_root != prev_state.current_justified_root +# else: +# assert state.current_justified_epoch == prev_state.current_justified_epoch +# assert state.current_justified_root == prev_state.current_justified_root - if previous_justified_changed: - assert state.previous_justified_epoch > prev_state.previous_justified_epoch - assert state.previous_justified_root != prev_state.previous_justified_root - else: - assert state.previous_justified_epoch == prev_state.previous_justified_epoch - assert state.previous_justified_root == prev_state.previous_justified_root +# if previous_justified_changed: +# assert state.previous_justified_epoch > prev_state.previous_justified_epoch +# assert state.previous_justified_root != prev_state.previous_justified_root +# else: +# assert state.previous_justified_epoch == prev_state.previous_justified_epoch +# assert state.previous_justified_root == prev_state.previous_justified_root - if finalized_changed: - assert state.finalized_epoch > prev_state.finalized_epoch - assert state.finalized_root != prev_state.finalized_root - else: - assert state.finalized_epoch == prev_state.finalized_epoch - assert state.finalized_root == prev_state.finalized_root +# if finalized_changed: +# assert state.finalized_epoch > prev_state.finalized_epoch +# assert state.finalized_root != prev_state.finalized_root +# else: +# assert state.finalized_epoch == prev_state.finalized_epoch +# assert state.finalized_root == prev_state.finalized_root -def next_epoch_with_attestations(spec, - state, - fill_cur_epoch, - fill_prev_epoch): - post_state = deepcopy(state) - blocks = [] - for _ in range(spec.SLOTS_PER_EPOCH): - block = build_empty_block_for_next_slot(spec, post_state) - if fill_cur_epoch: - slot_to_attest = post_state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1 - if slot_to_attest >= spec.get_epoch_start_slot(spec.get_current_epoch(post_state)): - cur_attestation = get_valid_attestation(spec, post_state, slot_to_attest) - block.body.attestations.append(cur_attestation) +# def next_epoch_with_attestations(spec, +# state, +# fill_cur_epoch, +# fill_prev_epoch): +# post_state = deepcopy(state) +# blocks = [] +# for _ in range(spec.SLOTS_PER_EPOCH): +# block = build_empty_block_for_next_slot(spec, post_state) +# if fill_cur_epoch: +# slot_to_attest = post_state.slot - spec.MIN_ATTESTATION_INCLUSION_DELAY + 1 +# if slot_to_attest >= spec.get_epoch_start_slot(spec.get_current_epoch(post_state)): +# cur_attestation = get_valid_attestation(spec, post_state, slot_to_attest) +# block.body.attestations.append(cur_attestation) - if fill_prev_epoch: - slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1 - prev_attestation = get_valid_attestation(spec, post_state, slot_to_attest) - block.body.attestations.append(prev_attestation) +# if fill_prev_epoch: +# slot_to_attest = post_state.slot - spec.SLOTS_PER_EPOCH + 1 +# prev_attestation = get_valid_attestation(spec, post_state, slot_to_attest) +# block.body.attestations.append(prev_attestation) - spec.state_transition(post_state, block) - blocks.append(block) +# spec.state_transition(post_state, block) +# blocks.append(block) - return state, blocks, post_state +# return state, blocks, post_state -@with_all_phases -@never_bls -@spec_state_test -def test_finality_rule_4(spec, state): - yield 'pre', state +# @with_all_phases +# @never_bls +# @spec_state_test +# def test_finality_rule_4(spec, state): +# yield 'pre', state - blocks = [] - for epoch in range(4): - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) - blocks += new_blocks +# blocks = [] +# for epoch in range(4): +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) +# blocks += new_blocks - # justification/finalization skipped at GENESIS_EPOCH - if epoch == 0: - check_finality(spec, state, prev_state, False, False, False) - # justification/finalization skipped at GENESIS_EPOCH + 1 - elif epoch == 1: - check_finality(spec, state, prev_state, False, False, False) - elif epoch == 2: - check_finality(spec, state, prev_state, True, False, False) - elif epoch >= 3: - # rule 4 of finality - check_finality(spec, state, prev_state, True, True, True) - assert state.finalized_epoch == prev_state.current_justified_epoch - assert state.finalized_root == prev_state.current_justified_root +# # justification/finalization skipped at GENESIS_EPOCH +# if epoch == 0: +# check_finality(spec, state, prev_state, False, False, False) +# # justification/finalization skipped at GENESIS_EPOCH + 1 +# elif epoch == 1: +# check_finality(spec, state, prev_state, False, False, False) +# elif epoch == 2: +# check_finality(spec, state, prev_state, True, False, False) +# elif epoch >= 3: +# # rule 4 of finality +# check_finality(spec, state, prev_state, True, True, True) +# assert state.finalized_epoch == prev_state.current_justified_epoch +# assert state.finalized_root == prev_state.current_justified_root - yield 'blocks', blocks, List[spec.BeaconBlock] - yield 'post', state +# yield 'blocks', blocks, List[spec.BeaconBlock] +# yield 'post', state -@with_all_phases -@never_bls -@spec_state_test -def test_finality_rule_1(spec, state): - # get past first two epochs that finality does not run on - next_epoch(spec, state) - apply_empty_block(spec, state) - next_epoch(spec, state) - apply_empty_block(spec, state) +# @with_all_phases +# @never_bls +# @spec_state_test +# def test_finality_rule_1(spec, state): +# # get past first two epochs that finality does not run on +# next_epoch(spec, state) +# apply_empty_block(spec, state) +# next_epoch(spec, state) +# apply_empty_block(spec, state) - yield 'pre', state +# yield 'pre', state - blocks = [] - for epoch in range(3): - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) - blocks += new_blocks +# blocks = [] +# for epoch in range(3): +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) +# blocks += new_blocks - if epoch == 0: - check_finality(spec, state, prev_state, True, False, False) - elif epoch == 1: - check_finality(spec, state, prev_state, True, True, False) - elif epoch == 2: - # finalized by rule 1 - check_finality(spec, state, prev_state, True, True, True) - assert state.finalized_epoch == prev_state.previous_justified_epoch - assert state.finalized_root == prev_state.previous_justified_root +# if epoch == 0: +# check_finality(spec, state, prev_state, True, False, False) +# elif epoch == 1: +# check_finality(spec, state, prev_state, True, True, False) +# elif epoch == 2: +# # finalized by rule 1 +# check_finality(spec, state, prev_state, True, True, True) +# assert state.finalized_epoch == prev_state.previous_justified_epoch +# assert state.finalized_root == prev_state.previous_justified_root - yield 'blocks', blocks, List[spec.BeaconBlock] - yield 'post', state +# yield 'blocks', blocks, List[spec.BeaconBlock] +# yield 'post', state -@with_all_phases -@never_bls -@spec_state_test -def test_finality_rule_2(spec, state): - # get past first two epochs that finality does not run on - next_epoch(spec, state) - apply_empty_block(spec, state) - next_epoch(spec, state) - apply_empty_block(spec, state) +# @with_all_phases +# @never_bls +# @spec_state_test +# def test_finality_rule_2(spec, state): +# # get past first two epochs that finality does not run on +# next_epoch(spec, state) +# apply_empty_block(spec, state) +# next_epoch(spec, state) +# apply_empty_block(spec, state) - yield 'pre', state +# yield 'pre', state - blocks = [] - for epoch in range(3): - if epoch == 0: - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) - check_finality(spec, state, prev_state, True, False, False) - elif epoch == 1: - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, False) - check_finality(spec, state, prev_state, False, True, False) - elif epoch == 2: - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) - # finalized by rule 2 - check_finality(spec, state, prev_state, True, False, True) - assert state.finalized_epoch == prev_state.previous_justified_epoch - assert state.finalized_root == prev_state.previous_justified_root +# blocks = [] +# for epoch in range(3): +# if epoch == 0: +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) +# check_finality(spec, state, prev_state, True, False, False) +# elif epoch == 1: +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, False) +# check_finality(spec, state, prev_state, False, True, False) +# elif epoch == 2: +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) +# # finalized by rule 2 +# check_finality(spec, state, prev_state, True, False, True) +# assert state.finalized_epoch == prev_state.previous_justified_epoch +# assert state.finalized_root == prev_state.previous_justified_root - blocks += new_blocks +# blocks += new_blocks - yield 'blocks', blocks, List[spec.BeaconBlock] - yield 'post', state +# yield 'blocks', blocks, List[spec.BeaconBlock] +# yield 'post', state -@with_all_phases -@never_bls -@spec_state_test -def test_finality_rule_3(spec, state): - """ - Test scenario described here - https://github.com/ethereum/eth2.0-specs/issues/611#issuecomment-463612892 - """ - # get past first two epochs that finality does not run on - next_epoch(spec, state) - apply_empty_block(spec, state) - next_epoch(spec, state) - apply_empty_block(spec, state) +# @with_all_phases +# @never_bls +# @spec_state_test +# def test_finality_rule_3(spec, state): +# """ +# Test scenario described here +# https://github.com/ethereum/eth2.0-specs/issues/611#issuecomment-463612892 +# """ +# # get past first two epochs that finality does not run on +# next_epoch(spec, state) +# apply_empty_block(spec, state) +# next_epoch(spec, state) +# apply_empty_block(spec, state) - yield 'pre', state +# yield 'pre', state - blocks = [] - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) - blocks += new_blocks - check_finality(spec, state, prev_state, True, False, False) +# blocks = [] +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) +# blocks += new_blocks +# check_finality(spec, state, prev_state, True, False, False) - # In epoch N, JE is set to N, prev JE is set to N-1 - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) - blocks += new_blocks - check_finality(spec, state, prev_state, True, True, True) +# # In epoch N, JE is set to N, prev JE is set to N-1 +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, False) +# blocks += new_blocks +# check_finality(spec, state, prev_state, True, True, True) - # In epoch N+1, JE is N, prev JE is N-1, and not enough messages get in to do anything - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, False) - blocks += new_blocks - check_finality(spec, state, prev_state, False, True, False) +# # In epoch N+1, JE is N, prev JE is N-1, and not enough messages get in to do anything +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, False) +# blocks += new_blocks +# check_finality(spec, state, prev_state, False, True, False) - # In epoch N+2, JE is N, prev JE is N, and enough messages from the previous epoch get in to justify N+1. - # N+1 now becomes the JE. Not enough messages from epoch N+2 itself get in to justify N+2 - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) - blocks += new_blocks - # rule 2 - check_finality(spec, state, prev_state, True, False, True) +# # In epoch N+2, JE is N, prev JE is N, and enough messages from the previous epoch get in to justify N+1. +# # N+1 now becomes the JE. Not enough messages from epoch N+2 itself get in to justify N+2 +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, False, True) +# blocks += new_blocks +# # rule 2 +# check_finality(spec, state, prev_state, True, False, True) - # In epoch N+3, LJE is N+1, prev LJE is N, and enough messages get in to justify epochs N+2 and N+3. - prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, True) - blocks += new_blocks - # rule 3 - check_finality(spec, state, prev_state, True, True, True) - assert state.finalized_epoch == prev_state.current_justified_epoch - assert state.finalized_root == prev_state.current_justified_root +# # In epoch N+3, LJE is N+1, prev LJE is N, and enough messages get in to justify epochs N+2 and N+3. +# prev_state, new_blocks, state = next_epoch_with_attestations(spec, state, True, True) +# blocks += new_blocks +# # rule 3 +# check_finality(spec, state, prev_state, True, True, True) +# assert state.finalized_epoch == prev_state.current_justified_epoch +# assert state.finalized_root == prev_state.current_justified_root - yield 'blocks', blocks, List[spec.BeaconBlock] - yield 'post', state +# yield 'blocks', blocks, List[spec.BeaconBlock] +# yield 'post', state diff --git a/test_libs/pyspec/eth2spec/test/test_fork_choice.py b/test_libs/pyspec/eth2spec/test/test_fork_choice.py index 374466032..c1df605fe 100644 --- a/test_libs/pyspec/eth2spec/test/test_fork_choice.py +++ b/test_libs/pyspec/eth2spec/test/test_fork_choice.py @@ -58,7 +58,7 @@ def test_on_attestation(spec, state): store.latest_targets[indexed_attestation.custody_bit_0_indices[0]] == spec.Target( epoch = attestation.data.target_epoch, - root = attestation.data.target_root + root = attestation.data.target_root, ) ) diff --git a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py index 7119f2e5b..5b3500d3e 100644 --- a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py +++ b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py @@ -1,5 +1,13 @@ -from typing import List, Iterable, TypeVar, Type, NewType, Dict -from typing import Union +import copy +from typing import ( + List, + Iterable, + TypeVar, + Type, + NewType, + Dict, + Union, +) from typing_inspect import get_origin # SSZ integers @@ -123,6 +131,9 @@ class Container(object): def get_field_values(self): cls = self.__class__ return [getattr(self, field) for field in cls.get_field_names()] + + def copy(self): + return self.deepcopy(self) def __repr__(self): return repr({field: getattr(self, field) for field in self.get_field_names()}) @@ -280,32 +291,6 @@ class Vector(metaclass=VectorMeta): return self.hash_tree_root() == other.hash_tree_root() -# # Super Secret Un-documented SSZ Dict (for forkchoice) -# # ----------------------------- -class Dict(dict): - def __init__(self,*args,**kwargs) : dict.__init__(self,*args,**kwargs) - - def serialize(self): - raise NotImplementedError - - def hash_tree_root(self): - raise NotImplementedError - - def __getitem__(self, key): - return self.items[key] - - def __setitem__(self, key, value): - self.items[key] = value - - def __iter__(self): - return iter(self.items) - - def __len__(self): - return len(self.items) - - def __eq__(self, other): - raise NotImplementedError - # SSZ BytesN # -----------------------------