def read_data_from_stream(cls, stream): data = stream.read(cls.data_byte_size) if len(data) != cls.data_byte_size: raise InsufficientDataBytes( "Tried to read {0} bytes. Only got {1} bytes".format( cls.data_byte_size, len(data), )) return data
def read_padded_data_from_stream(self, stream): """ This function exists to work around a bug in Solidity: https://github.com/ethereum/web3.py/issues/602 https://github.com/ethereum/solidity/issues/3493 Data from logs differs if the event is emitted during an external or internal solidity function call. The workaround is to pad the data until if fits the padded length. :param self: :param stream: :return: """ from eth_abi.utils.numeric import ceil32 data_length = decode_uint_256(stream) padded_length = ceil32(data_length) data = stream.read(padded_length) # Start change # Manually pad data to force it to desired length if len(data) < padded_length: data += b'\x00' * (padded_length - data_length) # End change if len(data) < padded_length: from eth_abi.exceptions import InsufficientDataBytes raise InsufficientDataBytes( "Tried to read {0} bytes. Only got {1} bytes".format( padded_length, len(data), ) ) padding_bytes = data[data_length:] if padding_bytes != b'\x00' * (padded_length - data_length): from eth_abi.exceptions import NonEmptyPaddingBytes raise NonEmptyPaddingBytes( "Padding bytes were not empty: {0}".format(repr(padding_bytes)) ) return data[:data_length]
def read_data_from_stream(cls, stream): data_length = decode_uint_256(stream) padded_length = ceil32(data_length) data = stream.read(padded_length) if len(data) < padded_length: raise InsufficientDataBytes( "Tried to read {0} bytes. Only got {1} bytes".format( padded_length, len(data), )) padding_bytes = data[data_length:] if padding_bytes != b'\x00' * (padded_length - data_length): raise NonEmptyPaddingBytes( "Padding bytes were not empty: {0}".format( repr(padding_bytes))) return data[:data_length]