2019-05-27 19:46:14 +00:00
|
|
|
from eth2spec.utils.ssz.ssz_impl import hash_tree_root
|
2019-06-01 00:22:14 +00:00
|
|
|
from eth2spec.utils.ssz.ssz_typing import (
|
|
|
|
is_uint_type, is_bool_type, is_list_type, is_vector_type, is_container_type,
|
|
|
|
read_elem_type,
|
|
|
|
uint
|
|
|
|
)
|
2019-04-07 13:36:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
def encode(value, typ, include_hash_tree_roots=False):
|
2019-05-27 20:19:18 +00:00
|
|
|
if is_uint_type(typ):
|
2019-05-27 21:40:05 +00:00
|
|
|
if hasattr(typ, '__supertype__'):
|
|
|
|
typ = typ.__supertype__
|
2019-05-27 20:19:18 +00:00
|
|
|
# Larger uints are boxed and the class declares their byte length
|
2019-05-27 19:46:14 +00:00
|
|
|
if issubclass(typ, uint) and typ.byte_len > 8:
|
2019-04-18 01:37:02 +00:00
|
|
|
return str(value)
|
2019-04-07 13:36:05 +00:00
|
|
|
return value
|
2019-05-27 19:46:14 +00:00
|
|
|
elif is_bool_type(typ):
|
2019-04-07 13:36:05 +00:00
|
|
|
assert value in (True, False)
|
|
|
|
return value
|
2019-05-27 20:19:18 +00:00
|
|
|
elif is_list_type(typ) or is_vector_type(typ):
|
|
|
|
elem_typ = read_elem_type(typ)
|
2019-05-27 19:46:14 +00:00
|
|
|
return [encode(element, elem_typ, include_hash_tree_roots) for element in value]
|
2019-05-27 21:40:05 +00:00
|
|
|
elif isinstance(typ, type) and issubclass(typ, bytes): # both bytes and BytesN
|
2019-04-07 13:36:05 +00:00
|
|
|
return '0x' + value.hex()
|
2019-05-27 20:19:18 +00:00
|
|
|
elif is_container_type(typ):
|
2019-04-07 13:36:05 +00:00
|
|
|
ret = {}
|
2019-05-27 19:46:14 +00:00
|
|
|
for field, subtype in typ.get_fields():
|
|
|
|
field_value = getattr(value, field)
|
|
|
|
ret[field] = encode(field_value, subtype, include_hash_tree_roots)
|
2019-04-07 13:36:05 +00:00
|
|
|
if include_hash_tree_roots:
|
2019-05-27 19:46:14 +00:00
|
|
|
ret[field + "_hash_tree_root"] = '0x' + hash_tree_root(field_value, subtype).hex()
|
2019-04-07 13:36:05 +00:00
|
|
|
if include_hash_tree_roots:
|
|
|
|
ret["hash_tree_root"] = '0x' + hash_tree_root(value, typ).hex()
|
|
|
|
return ret
|
|
|
|
else:
|
2019-06-04 09:42:21 +00:00
|
|
|
raise Exception(f"Type not recognized: value={value}, typ={typ}")
|