91 lines
3.4 KiB
Python
91 lines
3.4 KiB
Python
from eth2spec.utils.ssz import ssz_typing as spec_ssz
|
|
import ssz
|
|
|
|
|
|
def translate_typ(typ) -> ssz.BaseSedes:
|
|
"""
|
|
Translates a spec type to a Py-SSZ type description (sedes).
|
|
:param typ: The spec type, a class.
|
|
:return: The Py-SSZ equivalent.
|
|
"""
|
|
if issubclass(typ, spec_ssz.Container):
|
|
return ssz.Container(
|
|
[translate_typ(field_typ) for field_name, field_typ in typ.get_fields().items()])
|
|
elif issubclass(typ, spec_ssz.BytesN):
|
|
return ssz.ByteVector(typ.length)
|
|
elif issubclass(typ, spec_ssz.Bytes):
|
|
return ssz.ByteList()
|
|
elif issubclass(typ, spec_ssz.Vector):
|
|
return ssz.Vector(translate_typ(typ.elem_type), typ.length)
|
|
elif issubclass(typ, spec_ssz.List):
|
|
# TODO: Make py-ssz List support the new fixed length list
|
|
return ssz.List(translate_typ(typ.elem_type))
|
|
elif issubclass(typ, spec_ssz.Bitlist):
|
|
# TODO: Once Bitlist implemented in py-ssz, use appropriate type
|
|
return ssz.List(translate_typ(typ.elem_type))
|
|
elif issubclass(typ, spec_ssz.Bitvector):
|
|
# TODO: Once Bitvector implemented in py-ssz, use appropriate type
|
|
return ssz.Vector(translate_typ(typ.elem_type), typ.length)
|
|
elif issubclass(typ, spec_ssz.boolean):
|
|
return ssz.boolean
|
|
elif issubclass(typ, spec_ssz.uint):
|
|
if typ.byte_len == 1:
|
|
return ssz.uint8
|
|
elif typ.byte_len == 2:
|
|
return ssz.uint16
|
|
elif typ.byte_len == 4:
|
|
return ssz.uint32
|
|
elif typ.byte_len == 8:
|
|
return ssz.uint64
|
|
elif typ.byte_len == 16:
|
|
return ssz.uint128
|
|
elif typ.byte_len == 32:
|
|
return ssz.uint256
|
|
else:
|
|
raise TypeError("invalid uint size")
|
|
else:
|
|
raise TypeError("Type not supported: {}".format(typ))
|
|
|
|
|
|
def translate_value(value, typ):
|
|
"""
|
|
Translate a value output from Py-SSZ deserialization into the given spec type.
|
|
:param value: The PySSZ value
|
|
:param typ: The type from the spec to translate into
|
|
:return: the translated value
|
|
"""
|
|
if issubclass(typ, spec_ssz.uint):
|
|
if typ.byte_len == 1:
|
|
return spec_ssz.uint8(value)
|
|
elif typ.byte_len == 2:
|
|
return spec_ssz.uint16(value)
|
|
elif typ.byte_len == 4:
|
|
return spec_ssz.uint32(value)
|
|
elif typ.byte_len == 8:
|
|
return spec_ssz.uint64(value)
|
|
elif typ.byte_len == 16:
|
|
return spec_ssz.uint128(value)
|
|
elif typ.byte_len == 32:
|
|
return spec_ssz.uint256(value)
|
|
else:
|
|
raise TypeError("invalid uint size")
|
|
elif issubclass(typ, spec_ssz.List):
|
|
return [translate_value(elem, typ.elem_type) for elem in value]
|
|
elif issubclass(typ, spec_ssz.boolean):
|
|
return value
|
|
elif issubclass(typ, spec_ssz.Vector):
|
|
return typ(*(translate_value(elem, typ.elem_type) for elem in value))
|
|
elif issubclass(typ, spec_ssz.Bitlist):
|
|
return typ(value)
|
|
elif issubclass(typ, spec_ssz.Bitvector):
|
|
return typ(value)
|
|
elif issubclass(typ, spec_ssz.BytesN):
|
|
return typ(value)
|
|
elif issubclass(typ, spec_ssz.Bytes):
|
|
return value
|
|
if issubclass(typ, spec_ssz.Container):
|
|
return typ(**{f_name: translate_value(f_val, f_typ) for (f_val, (f_name, f_typ))
|
|
in zip(value, typ.get_fields().items())})
|
|
else:
|
|
raise TypeError("Type not supported: {}".format(typ))
|