diff --git a/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py b/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py index 46d842e16..c3cc579bd 100644 --- a/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py +++ b/test_libs/pyspec/eth2spec/utils/ssz/ssz_impl.py @@ -8,11 +8,11 @@ BYTES_PER_LENGTH_OFFSET = 4 def is_basic_type(typ): - return is_uint(typ) or typ == bool + return is_uint_type(typ) or is_bool_type(typ) def serialize_basic(value, typ): - if is_uint(typ): + if is_uint_type(typ): return value.to_bytes(uint_byte_size(typ), 'little') if is_bool_type(typ): if value: @@ -24,11 +24,11 @@ def serialize_basic(value, typ): def is_fixed_size(typ): if is_basic_type(typ): return True - elif is_list_type(typ): + elif is_list_kind(typ): return False - elif is_vector_type(typ): - return is_fixed_size(read_vector_elem_typ(typ)) - elif is_container_typ(typ): + elif is_vector_kind(typ): + return is_fixed_size(read_vector_elem_type(typ)) + elif is_container_type(typ): return all(is_fixed_size(t) for t in typ.get_field_types()) else: raise Exception("Type not supported: {}".format(typ)) @@ -38,9 +38,9 @@ def is_fixed_size(typ): def serialize(obj, typ): if is_basic_type(typ): return serialize_basic(obj, typ) - elif is_list_type(typ) or is_vector_type(typ): - return encode_series(obj, [read_elem_typ(typ)]*len(obj)) - elif is_container_typ(typ): + elif is_list_kind(typ) or is_vector_kind(typ): + return encode_series(obj, [read_elem_type(typ)]*len(obj)) + elif is_container_type(typ): return encode_series(obj.get_field_values(), typ.get_field_types()) else: raise Exception("Type not supported: {}".format(typ)) @@ -103,15 +103,15 @@ def mix_in_length(root, length): def hash_tree_root(obj, typ): if is_basic_type(typ): return merkleize_chunks(chunkify(serialize_basic(obj, typ))) - elif is_list_type(typ) or is_vector_type(typ): - subtype = read_elem_typ(typ) + elif is_list_kind(typ) or is_vector_kind(typ): + subtype = read_elem_type(typ) if is_basic_type(subtype): leaves = chunkify(pack(obj, subtype)) else: leaves = [hash_tree_root(elem, subtype) for elem in obj] leaf_root = merkleize_chunks(leaves) return mix_in_length(leaf_root, len(obj)) if is_list_type(typ) else leaf_root - elif is_container_typ(typ): + elif is_container_type(typ): leaves = [hash_tree_root(elem, subtyp) for elem, subtyp in obj.get_fields()] return merkleize_chunks(chunkify(b''.join(leaves))) else: @@ -120,7 +120,7 @@ def hash_tree_root(obj, typ): @infer_input_type def signing_root(obj, typ): - assert is_container_typ(typ) + assert is_container_type(typ) leaves = [hash_tree_root(elem, subtyp) for elem, subtyp in obj.get_fields()[:-1]] return merkleize_chunks(chunkify(b''.join(leaves))) diff --git a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py index 93a272c8c..d16c66abb 100644 --- a/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py +++ b/test_libs/pyspec/eth2spec/utils/ssz/ssz_typing.py @@ -61,7 +61,7 @@ class uint256(uint): return super().__new__(cls, value) -def is_uint(typ): +def is_uint_type(typ): # All integers are uint in the scope of the spec here. # Since we default to uint64. Bounds can be checked elsewhere. return issubclass(typ, int) @@ -380,29 +380,48 @@ def is_bool_type(typ): return issubclass(typ, bool) def is_list_type(typ): + """ + Checks if the given type is a list. + """ + return (hasattr(typ, '_name') and typ._name == 'List') + +def is_bytes_type(typ): + # Do not accept subclasses of bytes here, to avoid confusion with BytesN + return typ == bytes + +def is_list_kind(typ): """ Checks if the given type is a kind of list. Can be bytes. """ - return (hasattr(typ, '_name') and typ._name == 'List') or typ == bytes + return is_list_type(typ) or is_bytes_type(typ) def is_vector_type(typ): + """ + Checks if the given type is a vector. + """ + return issubclass(typ, Vector) + +def is_bytesn_type(typ): + return issubclass(typ, BytesN) + +def is_vector_kind(typ): """ Checks if the given type is a kind of vector. Can be BytesN. """ - return issubclass(typ, Vector) or issubclass(typ, BytesN) + return is_vector_type(typ) or is_bytesn_type(typ) -def is_container_typ(typ): +def is_container_type(typ): return issubclass(typ, Container) -def read_list_elem_typ(list_typ: Type[List[T]]) -> T: +def read_list_elem_type(list_typ: Type[List[T]]) -> T: if list_typ.__args__ is None or len(list_typ.__args__) != 1: raise TypeError("Supplied list-type is invalid, no element type found.") return list_typ.__args__[0] -def read_vector_elem_typ(vector_typ: Type[Vector[T, L]]) -> T: +def read_vector_elem_type(vector_typ: Type[Vector[T, L]]) -> T: return vector_typ.elem_type -def read_elem_typ(typ): +def read_elem_type(typ): if typ == bytes: return byte elif is_list_type(typ):