SSZ (partially) handles Dicts
This commit is contained in:
parent
061ecf7d0a
commit
5d10cd63c7
|
@ -163,5 +163,8 @@ def on_attestation(store: Store, attestation: Attestation) -> None:
|
||||||
validate_indexed_attestation(state, indexed_attestation)
|
validate_indexed_attestation(state, indexed_attestation)
|
||||||
for i in indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices:
|
for i in indexed_attestation.custody_bit_0_indices + indexed_attestation.custody_bit_1_indices:
|
||||||
if i not in store.latest_targets or attestation.data.target_epoch > store.latest_targets[i].epoch:
|
if i not in store.latest_targets or attestation.data.target_epoch > store.latest_targets[i].epoch:
|
||||||
store.latest_targets[i] = Target(attestation.data.target_epoch, attestation.data.target_root)
|
store.latest_targets[i] = Target(
|
||||||
|
epoch = attestation.data.target_epoch,
|
||||||
|
root = attestation.data.target_root,
|
||||||
|
)
|
||||||
```
|
```
|
||||||
|
|
|
@ -10,41 +10,56 @@ from eth2spec.test.helpers.state import next_slot
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_basic(spec, state):
|
def test_basic(spec, state):
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
# Initialization
|
# Initialization
|
||||||
store = spec.get_genesis_store(state)
|
store = spec.get_genesis_store(state)
|
||||||
|
blocks = []
|
||||||
time = 100
|
time = 100
|
||||||
spec.on_tick(store, time)
|
spec.on_tick(store, time)
|
||||||
assert store.time == time
|
assert store.time == time
|
||||||
|
|
||||||
# On receiving a block of `GENESIS_SLOT + 1` slot
|
# On receiving a block of `GENESIS_SLOT + 1` slot
|
||||||
block = build_empty_block_for_next_slot(state)
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
|
blocks.append(block)
|
||||||
spec.on_block(store, block)
|
spec.on_block(store, block)
|
||||||
assert store.blocks[signing_root(block)] == block
|
assert store.blocks[signing_root(block)] == block
|
||||||
|
|
||||||
# On receiving a block of next epoch
|
# On receiving a block of next epoch
|
||||||
store.time = time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
store.time = time + spec.SECONDS_PER_SLOT * spec.SLOTS_PER_EPOCH
|
||||||
block = build_empty_block_for_next_slot(state)
|
block = build_empty_block_for_next_slot(spec, state)
|
||||||
block.slot += spec.SLOTS_PER_EPOCH
|
block.slot += spec.SLOTS_PER_EPOCH
|
||||||
|
blocks.append(block)
|
||||||
|
|
||||||
spec.on_block(store, block)
|
spec.on_block(store, block)
|
||||||
assert store.blocks[signing_root(block)] == block
|
assert store.blocks[signing_root(block)] == block
|
||||||
|
yield 'blocks', blocks, List[spec.BeaconBlock]
|
||||||
|
|
||||||
# TODO: add tests for justified_root and finalized_root
|
# TODO: add tests for justified_root and finalized_root
|
||||||
|
yield 'post', state
|
||||||
|
|
||||||
|
|
||||||
@with_all_phases
|
@with_all_phases
|
||||||
@spec_state_test
|
@spec_state_test
|
||||||
def test_on_attestation(spec, state):
|
def test_on_attestation(spec, state):
|
||||||
|
yield 'pre', state
|
||||||
|
|
||||||
store = spec.get_genesis_store(state)
|
store = spec.get_genesis_store(state)
|
||||||
time = 100
|
time = 100
|
||||||
spec.on_tick(store, time)
|
spec.on_tick(store, time)
|
||||||
|
|
||||||
next_slot(state)
|
next_slot(spec, state)
|
||||||
|
|
||||||
attestation = get_valid_attestation(state, slot=1)
|
attestation = get_valid_attestation(spec, state, slot=1)
|
||||||
|
yield 'attestation', attestation
|
||||||
indexed_attestation = spec.convert_to_indexed(state, attestation)
|
indexed_attestation = spec.convert_to_indexed(state, attestation)
|
||||||
spec.on_attestation(store, attestation)
|
spec.on_attestation(store, attestation)
|
||||||
assert (
|
assert (
|
||||||
store.latest_targets[indexed_attestation.custody_bit_0_indices[0]] ==
|
store.latest_targets[indexed_attestation.custody_bit_0_indices[0]] ==
|
||||||
spec.Target(attestation.data.target_epoch, attestation.data.target_root)
|
spec.Target(
|
||||||
|
epoch = attestation.data.target_epoch,
|
||||||
|
root = attestation.data.target_root
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
yield 'post', state
|
|
@ -1,4 +1,4 @@
|
||||||
from typing import List, Iterable, TypeVar, Type, NewType
|
from typing import List, Iterable, TypeVar, Type, NewType, Dict
|
||||||
from typing import Union
|
from typing import Union
|
||||||
from typing_inspect import get_origin
|
from typing_inspect import get_origin
|
||||||
|
|
||||||
|
@ -280,6 +280,32 @@ class Vector(metaclass=VectorMeta):
|
||||||
return self.hash_tree_root() == other.hash_tree_root()
|
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
|
# SSZ BytesN
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
|
||||||
|
@ -407,6 +433,8 @@ def get_zero_value(typ):
|
||||||
return b''
|
return b''
|
||||||
elif is_container_type(typ):
|
elif is_container_type(typ):
|
||||||
return typ(**{f: get_zero_value(t) for f, t in typ.get_fields()})
|
return typ(**{f: get_zero_value(t) for f, t in typ.get_fields()})
|
||||||
|
elif is_dict_type(typ):
|
||||||
|
return dict()
|
||||||
else:
|
else:
|
||||||
raise Exception("Type not supported: {}".format(typ))
|
raise Exception("Type not supported: {}".format(typ))
|
||||||
|
|
||||||
|
@ -498,6 +526,13 @@ def is_container_type(typ):
|
||||||
return isinstance(typ, type) and issubclass(typ, Container)
|
return isinstance(typ, type) and issubclass(typ, Container)
|
||||||
|
|
||||||
|
|
||||||
|
def is_dict_type(typ):
|
||||||
|
"""
|
||||||
|
Check of the given type is a Dict. (Which are a part of the super-secret undocumented SSZ spec)
|
||||||
|
"""
|
||||||
|
return get_origin(typ) is Dict or get_origin(typ) is dict
|
||||||
|
|
||||||
|
|
||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
L = TypeVar('L')
|
L = TypeVar('L')
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue