예제 #1
0
    def deserialize_uleb128_as_u32(self) -> int:
        value = 0
        for shift in range(0, 32, 7):
            byte = int.from_bytes(self.read(1), "little", signed=False)
            digit = byte & 0x7F
            value |= digit << shift
            if value > MAX_U32:
                raise st.DeserializationError(
                    "Overflow while parsing uleb128-encoded uint32 value")
            if digit == byte:
                if shift > 0 and digit == 0:
                    raise st.DeserializationError(
                        "Invalid uleb128 number (unexpected zero digit)")
                return value

        raise st.DeserializationError(
            "Overflow while parsing uleb128-encoded uint32 value")
예제 #2
0
 def deserialize_bool(self) -> st.bool:
     b = int.from_bytes(self.read(1), byteorder="little", signed=False)
     if b == 0:
         return False
     elif b == 1:
         return True
     else:
         raise st.DeserializationError("Unexpected boolean value:", b)
예제 #3
0
 def check_that_key_slices_are_increasing(self, slice1: typing.Tuple[int,
                                                                     int],
                                          slice2: typing.Tuple[int, int]):
     key1 = bytes(self.input.getbuffer()[slice1[0]:slice1[1]])
     key2 = bytes(self.input.getbuffer()[slice2[0]:slice2[1]])
     if key1 >= key2:
         raise st.DeserializationError(
             "Serialized keys in a map must be ordered by increasing lexicographic order"
         )
예제 #4
0
 def bcs_deserialize(input: bytes) -> "MultiEd25519Signature":
     v, buffer = bcs.deserialize(input, MultiEd25519Signature)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #5
0
 def bcs_deserialize(input: bytes) -> "RefundReason":
     v, buffer = bcs.deserialize(input, RefundReason)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #6
0
 def increase_container_depth(self):
     if self.container_depth_budget is not None:
         if self.container_depth_budget == 0:
             raise st.DeserializationError("Exceeded maximum container depth")
         self.container_depth_budget -= 1
예제 #7
0
 def lcs_deserialize(input: bytes) -> "Module":
     v, buffer = lcs.deserialize(input, Module)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #8
0
 def bcs_deserialize(input: bytes) -> "WriteOp":
     v, buffer = bcs.deserialize(input, WriteOp)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #9
0
 def deserialize_str(self) -> str:
     content = self.deserialize_bytes()
     try:
         return content.decode()
     except UnicodeDecodeError:
         raise st.DeserializationError("Invalid unicode string:", content)
예제 #10
0
 def bcs_deserialize(input: bytes) -> "TravelRuleMetadataV0":
     v, buffer = bcs.deserialize(input, TravelRuleMetadataV0)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #11
0
 def bcs_deserialize(input: bytes) -> "ChainId":
     v, buffer = bcs.deserialize(input, ChainId)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #12
0
 def deserialize_len(self) -> int:
     value = self.deserialize_uleb128_as_u32()
     if value > MAX_LENGTH:
         raise st.DeserializationError(
             "Length exceeds the maximum supported value.")
     return value
예제 #13
0
 def bcs_deserialize(input: bytes) -> "SignedTransaction":
     v, buffer = bcs.deserialize(input, SignedTransaction)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #14
0
 def lcs_deserialize(input: bytes) -> "MultiEd25519PublicKey":
     v, buffer = lcs.deserialize(input, MultiEd25519PublicKey)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #15
0
 def lcs_deserialize(input: bytes) -> "BlockMetadata":
     v, buffer = lcs.deserialize(input, BlockMetadata)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #16
0
 def lcs_deserialize(input: bytes) -> "WriteSetPayload":
     v, buffer = lcs.deserialize(input, WriteSetPayload)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #17
0
 def lcs_deserialize(input: bytes) -> "TransactionAuthenticator":
     v, buffer = lcs.deserialize(input, TransactionAuthenticator)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #18
0
 def lcs_deserialize(input: bytes) -> "StructTag":
     v, buffer = lcs.deserialize(input, StructTag)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #19
0
 def bcs_deserialize(input: bytes) -> "TransactionPayload":
     v, buffer = bcs.deserialize(input, TransactionPayload)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #20
0
 def bcs_deserialize(input: bytes) -> "ContractEventV0":
     v, buffer = bcs.deserialize(input, ContractEventV0)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #21
0
 def bcs_deserialize(input: bytes) -> "TypeTag":
     v, buffer = bcs.deserialize(input, TypeTag)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #22
0
 def bcs_deserialize(input: bytes) -> "EventKey":
     v, buffer = bcs.deserialize(input, EventKey)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #23
0
 def bcs_deserialize(input: bytes) -> "UnstructuredBytesMetadata":
     v, buffer = bcs.deserialize(input, UnstructuredBytesMetadata)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #24
0
 def bcs_deserialize(input: bytes) -> "GeneralMetadata":
     v, buffer = bcs.deserialize(input, GeneralMetadata)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #25
0
 def read(self, length: int) -> bytes:
     value = self.input.read(length)
     if value is None or len(value) < length:
         raise st.DeserializationError("Input is too short")
     return value
예제 #26
0
 def bcs_deserialize(input: bytes) -> "HashValue":
     v, buffer = bcs.deserialize(input, HashValue)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #27
0
 def bcs_deserialize(input: bytes) -> "Identifier":
     v, buffer = bcs.deserialize(input, Identifier)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #28
0
 def bcs_deserialize(input: bytes) -> "AccountAddress":
     v, buffer = bcs.deserialize(input, AccountAddress)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v
예제 #29
0
    def deserialize_any(self, obj_type) -> typing.Any:
        if obj_type in self.primitive_type_deserializer:
            return self.primitive_type_deserializer[obj_type]()

        elif hasattr(obj_type, "__origin__"):  # Generic type
            types = getattr(obj_type, "__args__")
            if getattr(obj_type, "__origin__") == collections.abc.Sequence:  # Sequence
                assert len(types) == 1
                item_type = types[0]
                length = self.deserialize_len()
                result = []
                for i in range(0, length):
                    item = self.deserialize_any(item_type)
                    result.append(item)

                return result

            elif getattr(obj_type, "__origin__") == tuple:  # Tuple
                result = []
                for i in range(len(types)):
                    item = self.deserialize_any(types[i])
                    result.append(item)
                return tuple(result)

            elif getattr(obj_type, "__origin__") == typing.Union:  # Option
                assert len(types) == 2 and types[1] == type(None)
                tag = int.from_bytes(self.read(1), byteorder="little", signed=False)
                if tag == 0:
                    return None
                elif tag == 1:
                    return self.deserialize_any(types[0])
                else:
                    raise st.DeserializationError("Wrong tag for Option value")

            elif getattr(obj_type, "__origin__") == dict:  # Map
                assert len(types) == 2
                length = self.deserialize_len()
                result = dict()
                previous_key_slice = None
                for i in range(0, length):
                    key_start = self.get_buffer_offset()
                    key = self.deserialize_any(types[0])
                    key_end = self.get_buffer_offset()
                    value = self.deserialize_any(types[1])

                    key_slice = (key_start, key_end)
                    if previous_key_slice is not None:
                        self.check_that_key_slices_are_increasing(previous_key_slice, key_slice)
                    previous_key_slice = key_slice

                    result[key] = value

                return result

            else:
                raise st.DeserializationError("Unexpected type", obj_type)

        else:
            # handle structs
            if dataclasses.is_dataclass(obj_type):
                values = []
                fields = dataclasses.fields(obj_type)
                typing_hints = get_type_hints(obj_type)
                self.increase_container_depth()
                for field in fields:
                    field_type = typing_hints[field.name]
                    field_value = self.deserialize_any(field_type)
                    values.append(field_value)
                self.decrease_container_depth()
                return obj_type(*values)

            # handle variant
            elif hasattr(obj_type, "VARIANTS"):
                variant_index = self.deserialize_variant_index()
                if variant_index not in range(len(obj_type.VARIANTS)):
                    raise st.DeserializationError("Unexpected variant index", variant_index)
                new_type = obj_type.VARIANTS[variant_index]
                return self.deserialize_any(new_type)

            else:
                raise st.DeserializationError("Unexpected type", obj_type)
예제 #30
0
 def lcs_deserialize(input: bytes) -> "AccessPath":
     v, buffer = lcs.deserialize(input, AccessPath)
     if buffer:
         raise st.DeserializationError("Some input bytes were not read")
     return v