def get_existing_states(
    state_dir: pathlib.Path,
    condense_duplicates: bool = False,
    validate_states: bool = False,
) -> typing.Tuple[typing.Dict[bytes, uint16], uint16]:
    """Reads all files in the provided state directory.
    :returns: a tuple containing a mapping of SHA1 bytes of the states to filenames/state_ids, and the next available state_id
    :raises AssertionError: if directory contains unexpected filenames (that aren't a uint16).
    """
    if condense_duplicates:
        raise NotImplementedError
    highest_id = -1
    state_mapping: typing.Dict[bytes, int] = {}
    for state_f in state_dir.iterdir():
        if not state_f.is_file():
            logging.warning("Unexpected entry: %s, ignored", state_f)
            continue
        try:
            state_id = uint16(int(state_f.name))
        except ValueError as e:
            raise AssertionError from e

        if validate_states:
            raise NotImplementedError

        d = hashlib.sha1(state_f.read_bytes()).digest()
        assert d not in state_mapping
        # TODO condense existing duplicate states?
        state_mapping[d] = state_id
        highest_id = max(highest_id, state_id)
    return state_mapping, uint16(highest_id + 1)
Ejemplo n.º 2
0
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 spec_ssz.is_uint_type(typ):
        size = spec_ssz.uint_byte_size(typ)
        if size == 1:
            return spec_ssz.uint8(value)
        elif size == 2:
            return spec_ssz.uint16(value)
        elif size == 4:
            return spec_ssz.uint32(value)
        elif size == 8:
            # uint64 is default (TODO this is changing soon)
            return value
        elif size == 16:
            return spec_ssz.uint128(value)
        elif size == 32:
            return spec_ssz.uint256(value)
        else:
            raise TypeError("invalid uint size")
    elif spec_ssz.is_list_type(typ):
        elem_typ = spec_ssz.read_elem_type(typ)
        return [translate_value(elem, elem_typ) for elem in value]
    elif spec_ssz.is_bool_type(typ):
        return value
    elif spec_ssz.is_vector_type(typ):
        elem_typ = spec_ssz.read_elem_type(typ)
        return typ(*(translate_value(elem, elem_typ) for elem in value))
    elif spec_ssz.is_bytesn_type(typ):
        return typ(value)
    elif spec_ssz.is_bytes_type(typ):
        return value
    elif spec_ssz.is_container_type(typ):
        return typ(
            **{
                f_name: translate_value(f_val, f_typ)
                for (f_name, f_val, f_typ) in zip(typ.get_field_names(), value,
                                                  typ.get_field_types())
            })
    else:
        raise TypeError("Type not supported: {}".format(typ))
Ejemplo n.º 3
0
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))