Ejemplo n.º 1
0
def hash_tree_root(value: Any, sedes: BaseSedes=None) -> Hash32:
    if sedes is None:
        sedes = infer_sedes(value)

    intermediate_tree_hash = sedes.intermediate_tree_hash(value)

    if len(intermediate_tree_hash) < 32:
        return Hash32(intermediate_tree_hash.ljust(32, b'\x00'))
    else:
        return Hash32(intermediate_tree_hash)
Ejemplo n.º 2
0
def get_hash_tree_root(value: Any, sedes: BaseSedes = None) -> Hash32:
    if sedes is None:
        sedes = infer_sedes(value)

    return sedes.get_hash_tree_root(value)
Ejemplo n.º 3
0
            if cls._meta.field_names[-1] != SIGNATURE_FIELD_NAME:
                raise TypeError(
                    f"Last field of signed serializable must be {SIGNATURE_FIELD_NAME}, but is "
                    f"{cls._meta.field_names[-1]}")

            signed_container_sedes = Container(
                cls._meta.container_sedes.field_sedes[:-1])
        else:
            signed_container_sedes = None

        meta = SignedMeta(
            has_fields=cls._meta.has_fields,
            fields=cls._meta.fields,
            container_sedes=cls._meta.container_sedes,
            signed_container_sedes=signed_container_sedes,
            field_names=cls._meta.field_names,
            field_attrs=cls._meta.field_attrs,
        )
        cls._meta = meta

        return cls


BaseSedes.register(MetaSignedSerializable)


class SignedSerializable(BaseSerializable, metaclass=MetaSignedSerializable):
    @property
    def signing_root(self):
        return ssz.get_hash_tree_root(self, self._meta.signed_container_sedes)
Ejemplo n.º 4
0
        deserialized_field_dict = cls._meta.container_sedes.deserialize(data)
        return cls(**deserialized_field_dict)

    def deserialize_segment(cls: Type[TSerializable], data: bytes,
                            start_index: int) -> Tuple[TSerializable, int]:
        deserialized_field_dict, continuation_index = cls._meta.container_sedes.deserialize_segment(
            data,
            start_index,
        )
        return cls(**deserialized_field_dict), continuation_index

    def consume_bytes(cls, data: bytes, start_index: int,
                      num_bytes: int) -> Tuple[bytes, int]:
        return cls._meta.container_sedes.consume_bytes(data, start_index,
                                                       num_bytes)

    def intermediate_tree_hash(cls: Type[TSerializable],
                               value: TSerializable) -> bytes:
        return cls._meta.container_sedes.intermediate_tree_hash(value)


# Make any class created with SerializableBase an instance of BaseSedes
BaseSedes.register(SerializableBase)


class Serializable(BaseSerializable, metaclass=SerializableBase):
    """
    The base class for serializable objects.
    """
    pass
Ejemplo n.º 5
0
        cls = super().__new__(mcls, name, bases, namespace)

        # check that the signature conventions are abided by
        if cls._meta is not None:
            if len(cls._meta.fields) < 2:
                raise TypeError(f"Signed containers need to have at least two fields")
            if cls._meta.fields[-1][0] != SIGNATURE_FIELD_NAME:
                raise TypeError(
                    f"Last field of signed container must be {SIGNATURE_FIELD_NAME}, but is "
                    f"{cls._meta.fields[-1][0]}"
                )

        return cls


BaseSedes.register(MetaHashableContainer)
BaseSedes.register(MetaSignedHashableContainer)


# workaround for https://github.com/python/typing/issues/449 (fixed in python 3.7)
python_version_info = sys.version_info
if python_version_info[0] <= 3 and python_version_info[1] <= 6:
    from typing import GenericMeta

    class GenericMetaHashableContainer(GenericMeta, MetaHashableContainer):
        pass

    class GenericMetaSignedHashableContainer(
        GenericMetaHashableContainer, MetaSignedHashableContainer
    ):
        pass