Skip to content

Commit

Permalink
suggestion to implement bitfield like
Browse files Browse the repository at this point in the history
  • Loading branch information
protolambda committed Jun 27, 2019
1 parent f57387c commit a5154da
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
4 changes: 3 additions & 1 deletion test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from ..merkle_minimal import merkleize_chunks
from ..hash_function import hash
from .ssz_typing import (
SSZValue, SSZType, BasicValue, BasicType, Series, Elements, boolean, Container, List, Bytes,
SSZValue, SSZType, BasicValue, BasicType, Series, Elements, Bitfield, boolean, Container, List, Bytes,
Bitlist, Bitvector, uint,
)

Expand Down Expand Up @@ -128,6 +128,8 @@ def item_length(typ: SSZType) -> int:
def chunk_count(typ: SSZType) -> int:
if isinstance(typ, BasicType):
return 1
elif issubclass(typ, Bitfield):
return (typ.length + 7) // 8 // 32
elif issubclass(typ, Elements):
return (typ.length * item_length(typ.elem_type) + 31) // 32
elif issubclass(typ, Container):
Expand Down
33 changes: 24 additions & 9 deletions test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,6 @@ class ElementsType(ParamsMeta):
length: int


class BitElementsType(ElementsType):
elem_type = boolean


class Elements(ParamsBase, metaclass=ElementsType):
pass

Expand Down Expand Up @@ -346,11 +342,16 @@ def last(self):
return self[len(self) - 1]


class BaseBitfield(BaseList, metaclass=BitElementsType):
elem_type = bool
class BitElementsType(ElementsType):
elem_type: SSZType = boolean
length: int


class Bitfield(BaseList, metaclass=BitElementsType):
pass


class Bitlist(BaseBitfield):
class Bitlist(Bitfield):
@classmethod
def is_fixed_size(cls):
return False
Expand All @@ -360,15 +361,29 @@ def default(cls):
return cls()


class Bitvector(BaseBitfield):
class Bitvector(Bitfield):

@classmethod
def extract_args(cls, *args):
if len(args) == 0:
return cls.default()
else:
return super().extract_args(*args)

@classmethod
def value_check(cls, value):
# check length limit strictly
return len(value) == cls.length and super().value_check(value)

@classmethod
def is_fixed_size(cls):
return True

@classmethod
def default(cls):
return cls(0 for _ in range(cls.length))


class List(BaseList):

@classmethod
Expand Down

0 comments on commit a5154da

Please sign in to comment.