示例#1
0
文件: uint32.py 项目: mDuo13/xrpl-py
    def from_value(cls: Type[UInt32], value: Union[str, int]) -> UInt32:
        """
        Construct a new UInt32 type from a number.

        Args:
            value: The number to construct a UInt32 from.

        Returns:
            The UInt32 constructed from value.

        Raises:
            XRPLBinaryCodecException: If a UInt32 could not be constructed from value.
        """
        if not isinstance(value, (str, int)):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a UInt32: expected str or int,"
                " received {value.__class__.__name__}.")

        if isinstance(value, int):
            value_bytes = (value).to_bytes(_WIDTH,
                                           byteorder="big",
                                           signed=False)
            return cls(value_bytes)

        if isinstance(value, str) and value.isdigit():
            value_bytes = (int(value)).to_bytes(_WIDTH,
                                                byteorder="big",
                                                signed=False)
            return cls(value_bytes)

        raise XRPLBinaryCodecException(
            "Cannot construct UInt32 from given value")
示例#2
0
文件: amount.py 项目: legleux/xrpl-py
def verify_xrp_value(xrp_value: str) -> None:
    """
    Validates the format of an XRP amount.
    Raises if value is invalid.

    Args:
        xrp_value: A string representing an amount of XRP.

    Returns:
        None, but raises if xrp_value is not a valid XRP amount.

    Raises:
        XRPLBinaryCodecException: If xrp_value is not a valid XRP amount.
    """
    # Contains no decimal point
    if not _contains_decimal(xrp_value):
        raise XRPLBinaryCodecException(
            f"{xrp_value} is an invalid XRP amount.")

    # Within valid range
    decimal = Decimal(xrp_value)
    # Zero is less than both the min and max XRP amounts but is valid.
    if decimal.is_zero():
        return
    if (decimal.compare(_MIN_XRP) == -1) or (decimal.compare(_MAX_DROPS) == 1):
        raise XRPLBinaryCodecException(
            f"{xrp_value} is an invalid XRP amount.")
示例#3
0
    def from_value(cls: Type[SerializedList],
                   value: List[Any]) -> SerializedList:
        """
        Create a SerializedList object from a dictionary.

        Args:
            value: The dictionary to construct a SerializedList from.

        Returns:
            The SerializedList object constructed from value.

        Raises:
            XRPLBinaryCodecException: If the provided value isn't a list or contains
                non-dict elements.
        """
        if not isinstance(value, list):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a SerializedList:"
                " expected list, received {value.__class__.__name__}.")

        if len(value) > 0 and not isinstance(value[0], dict):
            raise XRPLBinaryCodecException(
                ("Cannot construct SerializedList from a list of non-dict"
                 " objects"))

        bytestring = b""
        for obj in value:
            transaction = SerializedDict.from_value(obj)
            bytestring += bytes(transaction)
        bytestring += _ARRAY_END_MARKER
        return SerializedList(bytestring)
示例#4
0
    def from_value(cls: Type[PathSet], value: List[List[Dict[str, str]]]) -> PathSet:
        """
        Construct a PathSet from a List of Lists representing paths.

        Args:
            value: The List to construct a PathSet object from.

        Returns:
            The PathSet constructed from value.

        Raises:
            XRPLBinaryCodecException: If the PathSet representation is invalid.
        """
        if not isinstance(value, list):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a PathSet: expected list,"
                f" received {value.__class__.__name__}."
            )

        if _is_path_set(value):
            buffer: List[bytes] = []
            for path_dict in value:
                path = Path.from_value(path_dict)
                buffer.append(bytes(path))
                buffer.append(bytes([_PATH_SEPARATOR_BYTE]))

            buffer[-1] = bytes([_PATHSET_END_BYTE])
            return PathSet(b"".join(buffer))

        raise XRPLBinaryCodecException("Cannot construct PathSet from given value")
示例#5
0
文件: uint16.py 项目: mDuo13/xrpl-py
    def from_value(cls: Type[UInt16], value: int) -> UInt16:
        """
        Construct a new UInt16 type from a number.

        Args:
            value: The value to consutrct a UInt16 from.

        Returns:
            The UInt16 constructed from value.

        Raises:
            XRPLBinaryCodecException: If a UInt16 can't be constructed from value.
        """
        if not isinstance(value, int):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a UInt16: expected int, "
                "received {value.__class__.__name__}.")

        if isinstance(value, int):
            value_bytes = (value).to_bytes(_WIDTH,
                                           byteorder="big",
                                           signed=False)
            return cls(value_bytes)

        raise XRPLBinaryCodecException(
            "Cannot construct UInt16 from given value")
示例#6
0
    def read_field_header(self: BinaryParser) -> FieldHeader:
        """
        Reads field ID from BinaryParser and returns as a FieldHeader object.

        Returns:
            The field header.

        Raises:
            XRPLBinaryCodecException: If the field ID cannot be read.
        """
        type_code = self.read_uint8()
        field_code = type_code & 15
        type_code >>= 4

        if type_code == 0:
            type_code = self.read_uint8()
            if type_code == 0 or type_code < 16:
                raise XRPLBinaryCodecException(
                    "Cannot read field ID, type_code out of range."
                )

        if field_code == 0:
            field_code = self.read_uint8()
            if field_code == 0 or field_code < 16:
                raise XRPLBinaryCodecException(
                    "Cannot read field ID, field_code out of range."
                )
        return FieldHeader(type_code, field_code)
示例#7
0
文件: amount.py 项目: legleux/xrpl-py
    def from_value(cls: Type[Amount], value: Union[str, Dict[str,
                                                             str]]) -> Amount:
        """
        Construct an Amount from an issued currency amount or (for XRP),
        a string amount.

        See `Amount Fields <https://xrpl.org/serialization.html#amount-fields>`_

        Args:
            value: The value from which to construct an Amount.

        Returns:
            An Amount object.

        Raises:
            XRPLBinaryCodecException: if an Amount cannot be constructed.
        """
        if isinstance(value, str):
            return cls(_serialize_xrp_amount(value))
        if IssuedCurrencyAmount.is_dict_of_model(value):
            return cls(_serialize_issued_currency_amount(value))

        raise XRPLBinaryCodecException(
            "Invalid type to construct an Amount: expected str or dict,"
            f" received {value.__class__.__name__}.")
示例#8
0
    def _read_length_prefix(self: BinaryParser) -> int:
        """
        Reads a variable length encoding prefix and returns the encoded length.

        The formula for decoding a length prefix is described in:
        `Length Prefixing <https://xrpl.org/serialization.html#length-prefixing>`_
        """
        byte1 = self.read_uint8()
        # If the field contains 0 to 192 bytes of data, the first byte defines
        # the length of the contents
        if byte1 <= _MAX_SINGLE_BYTE_LENGTH:
            return byte1
        # If the field contains 193 to 12480 bytes of data, the first two bytes
        # indicate the length of the field with the following formula:
        #    193 + ((byte1 - 193) * 256) + byte2
        if byte1 <= _MAX_SECOND_BYTE_VALUE:
            byte2 = self.read_uint8()
            return ((_MAX_SINGLE_BYTE_LENGTH + 1) +
                    ((byte1 -
                      (_MAX_SINGLE_BYTE_LENGTH + 1)) * _MAX_BYTE_VALUE) +
                    byte2)
        # If the field contains 12481 to 918744 bytes of data, the first three
        # bytes indicate the length of the field with the following formula:
        #    12481 + ((byte1 - 241) * 65536) + (byte2 * 256) + byte3
        if byte1 <= 254:
            byte2 = self.read_uint8()
            byte3 = self.read_uint8()
            return (_MAX_DOUBLE_BYTE_LENGTH +
                    ((byte1 -
                      (_MAX_SECOND_BYTE_VALUE + 1)) * _MAX_DOUBLE_BYTE_VALUE) +
                    (byte2 * _MAX_BYTE_VALUE) + byte3)
        raise XRPLBinaryCodecException(
            "Length prefix must contain between 1 and 3 bytes.")
示例#9
0
def _decode_field_id(field_id: str) -> FieldHeader:
    """
    Returns a FieldHeader object representing the type code and field code of
    a decoded field ID.
    """
    byte_array = bytes.fromhex(field_id)
    if len(byte_array) == 1:
        high_bits = byte_array[0] >> 4
        low_bits = byte_array[0] & 0x0F
        return FieldHeader(high_bits, low_bits)
    if len(byte_array) == 2:
        first_byte = byte_array[0]
        second_byte = byte_array[1]
        first_byte_high_bits = first_byte >> 4
        first_byte_low_bits = first_byte & 0x0F
        if (first_byte_high_bits == 0
            ):  # next 4 bits are field code, second byte is type code
            return FieldHeader(second_byte, first_byte_low_bits)
        # Otherwise, next 4 bits are type code, second byte is field code
        return FieldHeader(first_byte_high_bits, second_byte)
    if len(byte_array) == 3:
        return FieldHeader(byte_array[1], byte_array[2])

    raise XRPLBinaryCodecException(
        "Field ID must be between 1 and 3 bytes. "
        f"This field ID contained {len(byte_array)} bytes.")
示例#10
0
文件: amount.py 项目: legleux/xrpl-py
def verify_iou_value(issued_currency_value: str) -> None:
    """
    Validates the format of an issued currency amount value.
    Raises if value is invalid.

    Args:
        issued_currency_value: A string representing the "value"
                               field of an issued currency amount.

    Returns:
        None, but raises if issued_currency_value is not valid.

    Raises:
        XRPLBinaryCodecException: If issued_currency_value is invalid.
    """
    decimal_value = Decimal(issued_currency_value)
    if decimal_value.is_zero():
        return
    exponent = decimal_value.as_tuple().exponent
    if ((_calculate_precision(issued_currency_value) > _MAX_IOU_PRECISION)
            or (exponent > _MAX_IOU_EXPONENT)
            or (exponent < _MIN_IOU_EXPONENT)):
        raise XRPLBinaryCodecException(
            "Decimal precision out of range for issued currency value.")
    _verify_no_decimal(decimal_value)
示例#11
0
    def from_value(cls: Type[PathStep], value: Dict[str, str]) -> PathStep:
        """
        Construct a PathStep object from a dictionary.

        Args:
            value: The dictionary to construct a PathStep object from.

        Returns:
            The PathStep constructed from value.

        Raises:
            XRPLBinaryCodecException: If the supplied value is of the wrong type.
        """
        if not isinstance(value, dict):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a PathStep: expected dict,"
                f" received {value.__class__.__name__}."
            )

        data_type = 0x00
        buffer = b""
        if "account" in value:
            account_id = AccountID.from_value(value["account"])
            buffer += bytes(account_id)
            data_type |= _TYPE_ACCOUNT
        if "currency" in value:
            currency = Currency.from_value(value["currency"])
            buffer += bytes(currency)
            data_type |= _TYPE_CURRENCY
        if "issuer" in value:
            issuer = AccountID.from_value(value["issuer"])
            buffer += bytes(issuer)
            data_type |= _TYPE_ISSUER

        return PathStep(bytes([data_type]) + buffer)
示例#12
0
文件: uint.py 项目: mDuo13/xrpl-py
 def __ge__(self: UInt, other: object) -> bool:
     """Determine whether one UInt object is greater than or equal to another."""
     if isinstance(other, int):
         return self.value >= other
     if isinstance(other, UInt):
         return self.value >= other.value
     raise XRPLBinaryCodecException(
         f"Cannot compare UInt and {type(other)}")
示例#13
0
文件: uint.py 项目: mDuo13/xrpl-py
 def __ne__(self: UInt, other: object) -> bool:
     """Determine whether two UInt objects are unequal."""
     if isinstance(other, int):
         return self.value != other
     if isinstance(other, UInt):
         return self.value != other.value
     raise XRPLBinaryCodecException(
         f"Cannot compare UInt and {type(other)}")
示例#14
0
文件: currency.py 项目: XRPLF/xrpl-py
def _iso_code_from_hex(value: bytes) -> Optional[str]:
    candidate_iso = value.decode("ascii")
    if candidate_iso == "XRP":
        raise XRPLBinaryCodecException(
            "Disallowed currency code: to indicate the currency "
            "XRP you must use 20 bytes of 0s")
    if _is_iso_code(candidate_iso):
        return candidate_iso
    return None
示例#15
0
文件: amount.py 项目: legleux/xrpl-py
def _serialize_issued_currency_value(value: str) -> bytes:
    """
    Serializes the value field of an issued currency amount to its bytes representation.

    :param value: The value to serialize, as a string.
    :return: A bytes object encoding the serialized value.
    """
    verify_iou_value(value)
    decimal_value = Decimal(value)
    if decimal_value.is_zero():
        return _ZERO_CURRENCY_AMOUNT_HEX.to_bytes(8, byteorder="big")

    # Convert components to integers ---------------------------------------
    sign, digits, exp = decimal_value.as_tuple()
    mantissa = int("".join([str(d) for d in digits]))

    # Canonicalize to expected range ---------------------------------------
    while mantissa < _MIN_MANTISSA and exp > _MIN_IOU_EXPONENT:
        mantissa *= 10
        exp -= 1

    while mantissa > _MAX_MANTISSA:
        if exp >= _MAX_IOU_EXPONENT:
            raise XRPLBinaryCodecException(
                f"Amount overflow in issued currency value {str(value)}")
        mantissa //= 10
        exp += 1

    if exp < _MIN_IOU_EXPONENT or mantissa < _MIN_MANTISSA:
        # Round to zero
        _ZERO_CURRENCY_AMOUNT_HEX.to_bytes(8, byteorder="big", signed=False)

    if exp > _MAX_IOU_EXPONENT or mantissa > _MAX_MANTISSA:
        raise XRPLBinaryCodecException(
            f"Amount overflow in issued currency value {str(value)}")

    # Convert to bytes -----------------------------------------------------
    serial = _ZERO_CURRENCY_AMOUNT_HEX  # "Not XRP" bit set
    if sign == 0:
        serial |= _POS_SIGN_BIT_MASK  # "Is positive" bit set
    serial |= (exp + 97) << 54  # next 8 bits are exponents
    serial |= mantissa  # last 54 bits are mantissa

    return serial.to_bytes(8, byteorder="big", signed=False)
示例#16
0
文件: hash.py 项目: mDuo13/xrpl-py
    def __init__(self: Hash, buffer: Optional[bytes]) -> None:
        """
        Construct a Hash.

        Args:
            buffer: The byte buffer that will be used to store the serialized
                encoding of this field.
        """
        buffer = buffer if buffer is not None else bytes(self._get_length())

        if len(buffer) != self._get_length():
            raise XRPLBinaryCodecException("Invalid hash length {len(buffer)}")
        super().__init__(buffer)
示例#17
0
文件: blob.py 项目: mDuo13/xrpl-py
    def from_value(cls: Type[Blob], value: str) -> Blob:
        """
        Create a Blob object from a hex-string.

        Args:
            value: The hex-encoded string to construct a Blob from.

        Returns:
            The Blob constructed from value.

        Raises:
            XRPLBinaryCodecException: If the Blob can't be constructed from value.
        """
        if not isinstance(value, str):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a Blob: expected str, received "
                f"{value.__class__.__name__}.")

        if isinstance(value, str):
            return cls(bytes.fromhex(value))

        raise XRPLBinaryCodecException(
            "Cannot construct Blob from value given")
示例#18
0
文件: uint64.py 项目: legleux/xrpl-py
    def from_value(cls: Type[UInt64], value: Union[str, int]) -> UInt64:
        """
        Construct a new UInt64 type from a number.

        Args:
            value: The number to construct a UInt64 from.

        Returns:
            The UInt64 constructed from value.

        Raises:
            XRPLBinaryCodecException: If a UInt64 could not be constructed from value.
        """
        if not isinstance(value, (str, int)):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a UInt64: expected str or int,"
                " received {value.__class__.__name__}.")

        if isinstance(value, int):
            if value < 0:
                raise XRPLBinaryCodecException(
                    "{value} must be an unsigned integer")
            value_bytes = (value).to_bytes(_WIDTH,
                                           byteorder="big",
                                           signed=False)
            return cls(value_bytes)

        if isinstance(value, str):
            if not _HEX_REGEX.fullmatch(value):
                raise XRPLBinaryCodecException(
                    "{value} is not a valid hex string")
            value = value.rjust(16, "0")
            value_bytes = bytes.fromhex(value)
            return cls(value_bytes)

        raise XRPLBinaryCodecException(
            "Cannot construct UInt64 from given value {value}")
示例#19
0
    def skip(self: BinaryParser, n: int) -> None:
        """
        Consume the first n bytes of the BinaryParser.

        Args:
            n: The number of bytes to consume.

        Raises:
            XRPLBinaryCodecException: If n bytes can't be skipped.
        """
        if n > len(self.bytes):
            raise XRPLBinaryCodecException(
                f"BinaryParser can't skip {n} bytes, only contains {len(self.bytes)}."
            )
        self.bytes = self.bytes[n:]
示例#20
0
文件: currency.py 项目: XRPLF/xrpl-py
    def from_value(cls: Type[Currency], value: str) -> Currency:
        """
        Construct a Currency object from a string representation of a currency.

        Args:
            value: The string to construct a Currency object from.

        Returns:
            A Currency object constructed from value.

        Raises:
            XRPLBinaryCodecException: If the Currency representation is invalid.
        """
        if not isinstance(value, str):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a Currency: expected str,"
                f" received {value.__class__.__name__}.")

        if _is_iso_code(value):
            return Currency(_iso_to_bytes(value))
        if _is_hex(value):
            return cls(bytes.fromhex(value))
        raise XRPLBinaryCodecException(
            "Unsupported Currency representation: {value}")
示例#21
0
文件: amount.py 项目: legleux/xrpl-py
def _verify_no_decimal(decimal: Decimal) -> None:
    """
    Ensure that the value after being multiplied by the exponent
    does not contain a decimal.

    :param decimal: A Decimal object.
    """
    actual_exponent = decimal.as_tuple().exponent
    exponent = Decimal("1e" + str(-(int(actual_exponent) - 15)))
    if actual_exponent == 0:
        int_number_string = "".join(
            [str(d) for d in decimal.as_tuple().digits])
    else:
        # str(Decimal) uses sci notation by default... get around w/ string format
        int_number_string = "{:f}".format(decimal * exponent)
    if not _contains_decimal(int_number_string):
        raise XRPLBinaryCodecException("Decimal place found in int_number_str")
示例#22
0
文件: hash.py 项目: mDuo13/xrpl-py
    def from_value(cls: Type[Hash], value: str) -> Hash:
        """
        Construct a Hash object from a hex string.

        Args:
            value: The value to construct a Hash from.

        Returns:
            The Hash object constructed from value.

        Raises:
            XRPLBinaryCodecException: If the supplied value is of the wrong type.
        """
        if not isinstance(value, str):
            raise XRPLBinaryCodecException(
                f"Invalid type to construct a {cls.__name__}: expected str,"
                f" received {value.__class__.__name__}."
            )

        return cls(bytes.fromhex(value))
示例#23
0
def get_field_type_code(field_name: str) -> int:
    """
    Returns the type code associated with the given field.
    `Serialization Type Codes <https://xrpl.org/serialization.html#type-codes>`_

    Args:
        field_name: The name of the field get a type code for.

    Returns:
        The type code associated with the given field name.

    Raises:
        XRPLBinaryCodecException: If definitions.json is invalid.
    """
    field_type_name = get_field_type_name(field_name)
    field_type_code = _TYPE_ORDINAL_MAP[field_type_name]
    if not isinstance(field_type_code, int):
        raise XRPLBinaryCodecException(
            "Field type codes in definitions.json must be ints.")

    return field_type_code
示例#24
0
def _encode_field_id(field_header: FieldHeader) -> bytes:
    """
    Returns the unique field ID for a given field header.
    This field ID consists of the type code and field code, in 1 to 3 bytes
    depending on whether those values are "common" (<16) or "uncommon" (>=16)
    """
    type_code = field_header.type_code
    field_code = field_header.field_code

    if not 0 < field_code <= 255 or not 0 < type_code <= 255:
        raise XRPLBinaryCodecException(
            "Codes must be nonzero and fit in 1 byte.")

    if type_code < 16 and field_code < 16:
        # high 4 bits is the type_code
        # low 4 bits is the field code
        combined_code = (type_code << 4) | field_code
        return _uint8_to_bytes(combined_code)
    if type_code >= 16 and field_code < 16:
        # first 4 bits are zeroes
        # next 4 bits is field code
        # next byte is type code
        byte1 = _uint8_to_bytes(field_code)
        byte2 = _uint8_to_bytes(type_code)
        return byte1 + byte2
    if type_code < 16 and field_code >= 16:
        # first 4 bits is type code
        # next 4 bits are zeroes
        # next byte is field code
        byte1 = _uint8_to_bytes(type_code << 4)
        byte2 = _uint8_to_bytes(field_code)
        return byte1 + byte2
    else:  # both are >= 16
        # first byte is all zeroes
        # second byte is type code
        # third byte is field code
        byte2 = _uint8_to_bytes(type_code)
        byte3 = _uint8_to_bytes(field_code)
        return bytes(1) + byte2 + byte3
示例#25
0
    def read_field_value(self: BinaryParser, field: FieldInstance) -> SerializedType:
        """
        Read value of the type specified by field from the BinaryParser.

        Args:
            field: The FieldInstance specifying the field to read.

        Returns:
            A SerializedType read from the BinaryParser.

        Raises:
            XRPLBinaryCodecException: If a parser cannot be constructed from field.
        """
        field_type = field.associated_type
        if field.is_variable_length_encoded:
            size_hint = self._read_length_prefix()
            value = field_type.from_parser(self, size_hint)
        else:
            value = field_type.from_parser(self, None)
        if value is None:
            raise XRPLBinaryCodecException(
                f"from_parser for {field.name}, {field.type} returned None."
            )
        return value
示例#26
0
    def from_value(cls: Type[Path], value: List[Dict[str, str]]) -> Path:
        """
        Construct a Path from an array of dictionaries describing PathSteps.

        Args:
            value: The array to construct a Path object from.

        Returns:
            The Path constructed from value.

        Raises:
            XRPLBinaryCodecException: If the supplied value is of the wrong type.
        """
        if not isinstance(value, list):
            raise XRPLBinaryCodecException(
                "Invalid type to construct a Path: expected list, "
                f"received {value.__class__.__name__}."
            )

        buffer: bytes = b""
        for PathStep_dict in value:
            pathstep = PathStep.from_value(PathStep_dict)
            buffer += bytes(pathstep)
        return Path(buffer)
示例#27
0
文件: currency.py 项目: XRPLF/xrpl-py
def _iso_to_bytes(iso: str) -> bytes:
    """
    Convert an ISO code to a 160-bit (20 byte) encoded representation.

    See "Currency codes" subheading in
    `Amount Fields <https://xrpl.org/serialization.html#amount-fields>`_
    """
    if not _is_iso_code(iso):
        raise XRPLBinaryCodecException(f"Invalid ISO code: {iso}")

    if iso == "XRP":
        # This code (160 bit all zeroes) is used to indicate XRP in
        # rare cases where a field must specify a currency code for XRP.
        return bytes(_CURRENCY_CODE_LENGTH)

    iso_bytes = iso.encode("ASCII")
    # Currency Codes: https://xrpl.org/currency-formats.html#standard-currency-codes
    # 160 total bits:
    #   8 bits type code (0x00)
    #   88 bits reserved (0's)
    #   24 bits ASCII
    #   16 bits version (0x00)
    #   24 bits reserved (0's)
    return bytes(12) + iso_bytes + bytes(5)
示例#28
0
def _handle_xaddress(field: str, xaddress: str) -> Dict[str, Union[str, int]]:
    """Break down an X-Address into a classic address and a tag.

    Args:
        field: Name of field
        xaddress: X-Address corresponding to the field

    Returns:
        A dictionary representing the classic address and tag.

    Raises:
        XRPLBinaryCodecException: field-tag combo is invalid.
    """
    (classic_address, tag, is_test_network) = xaddress_to_classic_address(xaddress)
    if field == _DESTINATION:
        tag_name = _DEST_TAG
    elif field == _ACCOUNT:
        tag_name = _SOURCE_TAG
    elif tag is not None:
        raise XRPLBinaryCodecException(f"{field} cannot have an associated tag")

    if tag is not None:
        return {field: classic_address, tag_name: tag}
    return {field: classic_address}
示例#29
0
    for field in _DEFINITIONS["FIELDS"]:
        field_entry = _DEFINITIONS["FIELDS"][field]
        field_info = FieldInfo(
            field_entry["nth"],
            field_entry["isVLEncoded"],
            field_entry["isSerialized"],
            field_entry["isSigningField"],
            field_entry["type"],
        )
        header = FieldHeader(_TYPE_ORDINAL_MAP[field_entry["type"]],
                             field_entry["nth"])
        _FIELD_INFO_MAP[field] = field_info
        _FIELD_HEADER_NAME_MAP[header] = field
except KeyError as e:
    raise XRPLBinaryCodecException(
        f"Malformed definitions.json file. (Original exception: KeyError: {e})"
    )


def get_field_type_name(field_name: str) -> str:
    """
    Returns the serialization data type for the given field name.
    `Serialization Type List <https://xrpl.org/serialization.html#type-list>`_

    Args:
        field_name: The name of the field to get the serialization data type for.

    Returns:
        The serialization data type for the given field name.
    """
    return _FIELD_INFO_MAP[field_name].type
示例#30
0
    def from_value(
        cls: Type[SerializedDict], value: Dict[str, Any], only_signing: bool = False
    ) -> SerializedDict:
        """
        Create a SerializedDict object from a dictionary.

        Args:
            value: The dictionary to construct a SerializedDict from.
            only_signing: whether only the signing fields should be included.

        Returns:
            The SerializedDict object constructed from value.

        Raises:
            XRPLBinaryCodecException: If the SerializedDict can't be constructed
                from value.
        """
        from xrpl.core.binarycodec.binary_wrappers.binary_serializer import (
            BinarySerializer,
        )

        serializer = BinarySerializer()

        xaddress_decoded = {}
        for (k, v) in value.items():
            if isinstance(v, str) and is_valid_xaddress(v):
                handled = _handle_xaddress(k, v)
                if (
                    _SOURCE_TAG in handled
                    and handled[_SOURCE_TAG] is not None
                    and _SOURCE_TAG in value
                    and value[_SOURCE_TAG] is not None
                ):
                    raise XRPLBinaryCodecException(
                        "Cannot have Account X-Address and SourceTag"
                    )
                if (
                    _DEST_TAG in handled
                    and handled[_DEST_TAG] is not None
                    and _DEST_TAG in value
                    and value[_DEST_TAG] is not None
                ):
                    raise XRPLBinaryCodecException(
                        "Cannot have Destination X-Address and DestinationTag"
                    )
                xaddress_decoded.update(handled)
            else:
                xaddress_decoded[k] = _str_to_enum(k, v)

        sorted_keys: List[FieldInstance] = []
        for field_name in xaddress_decoded:
            field_instance = get_field_instance(field_name)
            if (
                field_instance is not None
                and xaddress_decoded[field_instance.name] is not None
                and field_instance.is_serialized
            ):
                sorted_keys.append(field_instance)
        sorted_keys.sort(key=lambda x: x.ordinal)

        if only_signing:
            sorted_keys = list(filter(lambda x: x.is_signing, sorted_keys))

        for field in sorted_keys:
            try:
                associated_value = field.associated_type.from_value(
                    xaddress_decoded[field.name]
                )
            except XRPLBinaryCodecException as e:
                # mildly hacky way to get more context in the error
                # provides the field name and not just the type it's expecting
                # keeps the original stack trace
                e.args = (f"Error processing {field.name}: {e.args[0]}",) + e.args[1:]
                raise
            serializer.write_field_and_value(field, associated_value)
            if field.type == _SERIALIZED_DICT:
                serializer.append(_OBJECT_END_MARKER_BYTE)

        return SerializedDict(bytes(serializer))