Exemplo n.º 1
0
    def validate_value(self, value):
        super().validate_value(value)

        if len(value) != self.array_size:
            raise ValueOutOfBounds(
                "Expected value with length {0}.  Provided value has {1} "
                "elements".format(self.array_size, len(value)))
Exemplo n.º 2
0
    def validate_value(self, value):
        cls = type(self)
        if not self.type_check_fn(value):
            raise EncodingTypeError(
                "Value of type {0} cannot be encoded by {1}".format(
                    type(value),
                    cls.__name__,
                )
            )

        illegal_value = (
            self.illegal_value_fn is not None and
            self.illegal_value_fn(value)
        )
        if illegal_value:
            raise IllegalValue(
                'Value {} cannot be encoded by {}'.format(repr(value), cls.__name__)
            )

        lower_bound, upper_bound = self.bounds_fn(self.value_bit_size)
        if value < lower_bound or value > upper_bound:
            raise ValueOutOfBounds(
                "Value {0} cannot be encoded in {1} bits.  Must be bounded "
                "between [{2}, {3}]".format(
                    repr(value),
                    self.value_bit_size,
                    lower_bound,
                    upper_bound,
                )
            )
Exemplo n.º 3
0
    def encode(self, values):
        if len(values) != len(self.encoders):
            raise ValueOutOfBounds(
                "Recieved {0} values to encode.  Expected {1}".format(
                    len(values),
                    len(self.encoders),
                ))

        raw_head_chunks = []
        tail_chunks = []
        for value, encoder in zip(values, self.encoders):
            if encoder.is_dynamic:
                raw_head_chunks.append(None)
                tail_chunks.append(encoder(value))
            else:
                raw_head_chunks.append(encoder(value))
                tail_chunks.append(b'')

        head_length = sum(32 if item is None else len(item)
                          for item in raw_head_chunks)
        tail_offsets = (0, ) + tuple(accumulate(map(len, tail_chunks[:-1])))
        head_chunks = tuple(
            encode_uint_256(head_length + offset) if chunk is None else chunk
            for chunk, offset in zip(raw_head_chunks, tail_offsets))

        encoded_value = b''.join(head_chunks + tuple(tail_chunks))

        return encoded_value
Exemplo n.º 4
0
 def encode(self, value):
     if len(value) != self.array_size:
         raise ValueOutOfBounds(
             "Expected value with length {0}.  Provided value has {1} "
             "elements".format(self.array_size, len(value)))
     encoded_elements = self.encode_elements(value)
     return encoded_elements
Exemplo n.º 5
0
    def encode(cls, values):
        if len(values) != len(cls.encoders):
            raise ValueOutOfBounds(
                "Recieved {0} values to encode.  Expected {1}".format(
                    len(values),
                    len(cls.encoders),
                ))
        raw_head_chunks = []
        tail_chunks = []

        for value, encoder in zip(values, cls.encoders):
            if isinstance(
                    encoder,
                (DynamicArrayEncoder, ByteStringEncoder, TextStringEncoder)):
                raw_head_chunks.append(None)
                tail_chunks.append(encoder(value))
            else:
                raw_head_chunks.append(encoder(value))
                tail_chunks.append(b'')

        head_length = sum(
            (32 if is_null(item) else len(item) for item in raw_head_chunks))
        tail_offsets = tuple((sum((len(chunk) for chunk in tail_chunks[:i]))
                              for i in range(len(tail_chunks))))
        head_chunks = tuple(
            ((encode_uint_256(head_length + tail_offsets[idx])
              if is_null(head_chunk) else head_chunk)
             for idx, head_chunk in enumerate(raw_head_chunks)))
        encoded_value = b''.join(
            tuple(itertools.chain(head_chunks, tail_chunks)))
        return encoded_value
Exemplo n.º 6
0
    def validate_value(self, value):
        if not is_list_like(value):
            raise EncodingTypeError(
                "Cannot encode value of type {0} using tuple encoder.  Must be "
                "a list-like object such as an array or tuple".format(
                    type(value), ))

        if len(value) != len(self.encoders):
            raise ValueOutOfBounds(
                "Expected value with length {0}.  Provided value has {1} "
                "elements".format(len(self.encoders), len(value)))

        for item, encoder in zip(value, self.encoders):
            encoder.validate_value(item)
Exemplo n.º 7
0
 def validate_value(self, value):
     if not is_bytes(value):
         raise EncodingTypeError(
             "Value of type {0} cannot be encoded by {1}".format(
                 type(value),
                 type(self).__name__,
             ))
     if len(value) > self.value_bit_size // 8:
         raise ValueOutOfBounds(
             "String {0} exceeds total byte size for bytes{1} encoding".
             format(
                 value,
                 self.value_bit_size // 8,
             ))
Exemplo n.º 8
0
    def validate_value(cls, value):
        if not cls.type_check_fn(value):
            raise EncodingTypeError(
                "Value of type {0} cannot be encoded by {1}".format(
                    type(value),
                    cls.__name__,
                ))

        lower_bound, upper_bound = cls.bounds_fn(cls.value_bit_size)

        if value < lower_bound or value > upper_bound:
            raise ValueOutOfBounds(
                "Value '{0}' cannot be encoded in {1} bits.  Must be bounded "
                "between [{2}, {3}]".format(
                    value,
                    cls.value_bit_size,
                    lower_bound,
                    upper_bound,
                ))
Exemplo n.º 9
0
def encode_single(typ, arg):
    try:
        base, sub, arrlist = typ
    except ValueError:
        base, sub, arrlist = process_type(typ)

    # Unsigned integers: uint<sz>
    if base == 'uint':
        sub = int(sub)
        i = decint(arg, False)

        if not 0 <= i < 2**sub:
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(i), 32)
    # bool: int<sz>
    elif base == 'bool':
        if not isinstance(arg, bool):
            raise EncodingError("Value must be a boolean")
        return zpad(encode_int(int(arg)), 32)
    # Signed integers: int<sz>
    elif base == 'int':
        sub = int(sub)
        i = decint(arg, True)
        if not -2**(sub - 1) <= i < 2**(sub - 1):
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(i % 2**sub), 32)
    # Unsigned reals: ureal<high>x<low>
    elif base == 'ureal':
        high, low = [int(x) for x in sub.split('x')]
        if not 0 <= arg < 2**high:
            raise ValueOutOfBounds(repr(arg))
        return zpad(encode_int(int(arg * 2**low)), 32)
    # Signed reals: real<high>x<low>
    elif base == 'real':
        high, low = [int(x) for x in sub.split('x')]
        if not -2**(high - 1) <= arg < 2**(high - 1):
            raise ValueOutOfBounds(repr(arg))
        i = int(arg * 2**low)
        return zpad(encode_int(i % 2**(high + low)), 32)
    # Strings
    elif base == 'string' or base == 'bytes':
        if not is_string(arg):
            raise EncodingError("Expecting string: %r" % arg)
        # Fixed length: string<sz>
        if len(sub):
            if int(sub) > 32:
                raise EncodingError(
                    "Fixed length strings must be 32 bytes or less")
            if len(arg) > int(sub):
                raise EncodingError(
                    "Value cannot exceed {0} bytes in length".format(sub))
            return arg + b'\x00' * (32 - len(arg))
        # Variable length: string
        else:
            return zpad(encode_int(len(arg)), 32) + \
                arg + \
                b'\x00' * (ceil32(len(arg)) - len(arg))
    # Hashes: hash<sz>
    elif base == 'hash':
        if not (int(sub) and int(sub) <= 32):
            raise EncodingError("too long: %r" % arg)
        if is_numeric(arg):
            return zpad(encode_int(arg), 32)
        elif len(arg) == int(sub):
            return zpad(arg, 32)
        elif len(arg) == int(sub) * 2:
            return zpad(decode_hex(arg), 32)
        else:
            raise EncodingError("Could not parse hash: %r" % arg)
    # Addresses: address (== hash160)
    elif base == 'address':
        if sub != '':
            raise EncodingError("Address type cannot specify a byte size")
        if is_numeric(arg):
            return zpad(encode_int(arg), 32)
        elif len(arg) == 20:
            return zpad(arg, 32)
        elif len(arg) == 40:
            return zpad(decode_hex(arg), 32)
        elif len(arg) == 42 and arg[:2] == '0x':
            return zpad(decode_hex(arg[2:]), 32)
        else:
            raise EncodingError("Could not parse address: %r" % arg)
    raise EncodingError("Unhandled type: %r %r" % (base, sub))