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)))
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, ) )
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
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
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
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)
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, ))
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, ))
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))