separate type (direct) from kinds (alias incl)

This commit is contained in:
protolambda 2019-05-27 22:18:34 +02:00
parent 87b3466eae
commit c68944bd53
No known key found for this signature in database
GPG Key ID: EC89FDBB2B4C7623
2 changed files with 39 additions and 20 deletions

View File

@ -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)))

View File

@ -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):