def is_encodable(_type, value): try: base, sub, arrlist = _type except ValueError: base, sub, arrlist = process_type(_type) if arrlist: if not is_list_like(value): return False if arrlist[-1] and len(value) != arrlist[-1][0]: return False sub_type = (base, sub, arrlist[:-1]) return all(is_encodable(sub_type, sub_value) for sub_value in value) elif base == 'bool': return is_boolean(value) elif base == 'uint': if not is_integer(value): return False exp = int(sub) if value < 0 or value >= 2**exp: return False return True elif base == 'int': if not is_integer(value): return False exp = int(sub) if value <= -1 * 2**(exp - 1) or value >= 2**(exp - 1): return False return True elif base == 'string': if not is_string(value): return False return True elif base == 'bytes': if not is_string(value): return False if not sub: return True max_length = int(sub) if isinstance(value, str): decodable = is_hex(value) and len(value) % 2 == 0 return decodable and len(decode_hex(value)) <= max_length elif isinstance(value, bytes): return len(value) <= max_length else: False elif base == 'address': if is_ens_name(value): return True elif is_address(value): return True else: return False else: raise ValueError("Unsupported type")
def validate_abi_value(abi_type, value): """ Helper function for validating a value against the expected abi_type Note: abi_type 'bytes' must either be python3 'bytes' object or '' """ if is_array_type(abi_type) and is_list_like(value): # validate length specified_length = length_of_array_type(abi_type) if specified_length is not None: if specified_length < 1: raise TypeError( "Invalid abi-type: {abi_type}. Length of fixed sized arrays" "must be greater than 0." .format(abi_type=abi_type) ) if specified_length != len(value): raise TypeError( "The following array length does not the length specified" "by the abi-type, {abi_type}: {value}" .format(abi_type=abi_type, value=value) ) # validate sub_types sub_type = sub_type_of_array_type(abi_type) for v in value: validate_abi_value(sub_type, v) return elif is_bool_type(abi_type) and is_boolean(value): return elif is_uint_type(abi_type) and is_integer(value) and value >= 0: return elif is_int_type(abi_type) and is_integer(value): return elif is_address_type(abi_type): validate_address(value) return elif is_bytes_type(abi_type): if sys.version_info.major >= 3 and is_bytes(value): return elif is_string(value): if is_0x_prefixed(value): return else: raise TypeError( "ABI values of abi-type 'bytes' must be either" "a python3 'bytes' object or an '0x' prefixed string." ) elif is_string_type(abi_type) and is_string(value): return raise TypeError( "The following abi value is not a '{abi_type}': {value}" .format(abi_type=abi_type, value=value) )
def test_eth_syncing(self, web3): syncing = web3.eth.syncing assert is_boolean(syncing) or is_dict(syncing) if is_boolean(syncing): assert syncing is False elif is_dict(syncing): assert 'startingBlock' in syncing assert 'currentBlock' in syncing assert 'highestBlock' in syncing assert is_integer(syncing['startingBlock']) assert is_integer(syncing['currentBlock']) assert is_integer(syncing['highestBlock'])
def is_by_hash(at_block): if is_string(at_block) and is_hex(at_block) and len(at_block) == 66: return True elif is_integer(at_block) or at_block in ('latest', 'earliest', 'pending'): return False else: raise ValueError("Unrecognized 'at_block' value: %r" % at_block)
def to_hex(value=None, hexstr=None, text=None): """ Auto converts any supported value into it's hex representation. Trims leading zeros, as defined in: https://github.com/ethereum/wiki/wiki/JSON-RPC#hex-value-encoding """ assert_one_val(value, hexstr=hexstr, text=text) if hexstr is not None: return add_0x_prefix(hexstr.lower()) if text is not None: return encode_hex(text.encode('utf-8')) if is_boolean(value): return "0x1" if value else "0x0" if is_dict(value): return encode_hex(json.dumps(value, sort_keys=True)) if isinstance(value, bytes): return encode_hex(value) elif is_string(value): return to_hex(text=value) if is_integer(value): return hex(value) raise TypeError( "Unsupported type: '{0}'. Must be one of Boolean, Dictionary, String, " "or Integer.".format(repr(type(value))) )
def test_encode_unsigned_integer(integer_value, value_bit_size, data_byte_size): if value_bit_size > data_byte_size * 8: with pytest.raises(ValueError) as exception_info: UnsignedIntegerEncoder( value_bit_size=value_bit_size, data_byte_size=data_byte_size, ) return encoder = UnsignedIntegerEncoder( value_bit_size=value_bit_size, data_byte_size=data_byte_size, ) lower_bound, upper_bound = compute_unsigned_integer_bounds(value_bit_size) if not is_integer(integer_value): with pytest.raises(EncodingTypeError) as exception_info: encoder(integer_value) assert 'UnsignedInteger' in str(exception_info.value) return elif integer_value < lower_bound or integer_value > upper_bound: with pytest.raises(ValueOutOfBounds): encoder(integer_value) return if integer_value >= 0: expected_value = zpad(int_to_big_endian(integer_value), data_byte_size) else: expected_value = fpad(int_to_big_endian(integer_value), data_byte_size) encoded_value = encoder(integer_value) assert encoded_value == expected_value
def getStorageAt(self, address, position, at_block): if not is_integer(position) or position < 0: raise TypeError("Position of storage must be a whole number, but was: %r" % position) with state_at_block(self._chain, at_block) as state: stored_val = state.get_storage(address, position) return encode_hex(int_to_big_endian(stored_val))
def input_block_identifier_formatter(block_identifier): if is_predefined_block_number(block_identifier): return block_identifier elif is_integer(block_identifier): return hex(block_identifier) else: return block_identifier
def inject(self, element, name=None, layer=None): ''' Inject a named element to an arbitrary layer in the onion. The current implementation only supports insertion at the innermost layer, or at the outermost layer. Note that inserting to the outermost is equivalent to calling :meth:`add` . ''' if not is_integer(layer): raise TypeError("The layer for insertion must be an int.") elif layer != 0 and layer != len(self._queue): raise NotImplementedError( "You can only insert to the beginning or end of a %s, currently. " "You tried to insert to %d, but only 0 and %d are permitted. " % ( type(self), layer, len(self._queue), ) ) self.add(element, name=name) if layer == 0: if name is None: name = element self._queue.move_to_end(name, last=False) elif layer == len(self._queue): return else: raise AssertionError("Impossible to reach: earlier validation raises an error")
def get_block_at_number(chain, at_block): if is_integer(at_block) and at_block >= 0: # optimization to avoid requesting block, then header, then block again return chain.get_canonical_block_by_number(at_block) else: at_header = get_header(chain, at_block) return chain.get_block_by_header(at_header)
def to_hex(value): """ Auto converts any supported value into it's hex representation. """ if is_boolean(value): return "0x1" if value else "0x0" if is_dict(value): return encode_hex(json.dumps(value, sort_keys=True)) if is_string(value): if is_prefixed(value, '-0x'): return from_decimal(value) elif is_0x_prefixed(value): return value else: return encode_hex(value) if is_integer(value): return from_decimal(value) raise TypeError( "Unsupported type: '{0}'. Must be one of Boolean, Dictionary, String, " "or Integer.".format(repr(type(value))) )
def test_eth_getTransactionCount(self, web3): coinbase = web3.eth.coinbase transaction_count = web3.eth.getTransactionCount(coinbase) with pytest.raises(InvalidAddress): web3.eth.getTransactionCount(coinbase.lower()) assert is_integer(transaction_count) assert transaction_count >= 0
def test_eth_estimateGas(self, web3): coinbase = web3.eth.coinbase gas_estimate = web3.eth.estimateGas({ 'from': coinbase, 'to': coinbase, 'value': 1, }) assert is_integer(gas_estimate) assert gas_estimate > 0
def test_eth_getBalance(self, web3): coinbase = web3.eth.coinbase with pytest.raises(InvalidAddress): web3.eth.getBalance(coinbase.lower()) balance = web3.eth.getBalance(coinbase) assert is_integer(balance) assert balance >= 0
def get_header(chain, at_block): if at_block == 'pending': at_header = chain.header elif at_block == 'latest': at_header = chain.get_canonical_head() elif at_block == 'earliest': # TODO find if genesis block can be non-zero. Why does 'earliest' option even exist? at_header = chain.get_canonical_block_by_number(0).header elif is_integer(at_block) and at_block >= 0: at_header = chain.get_canonical_block_by_number(at_block).header else: raise TypeError("Unrecognized block reference: %r" % at_block) return at_header
def is_predefined_block_number(value): if is_text(value): value_text = value elif is_bytes(value): # `value` could either be random bytes or the utf-8 encoding of # one of the words in: {"latest", "pending", "earliest"} # We cannot decode the bytes as utf8, because random bytes likely won't be valid. # So we speculatively decode as 'latin-1', which cannot fail. value_text = value.decode('latin-1') elif is_integer(value): return False else: raise TypeError("unrecognized block reference: %r" % value) return value_text in {"latest", "pending", "earliest"}
def select_method_for_block_identifier(value, if_hash, if_number, if_predefined): if is_predefined_block_number(value): return if_predefined elif isinstance(value, bytes): return if_hash elif is_hex_encoded_block_hash(value): return if_hash elif is_integer(value) and (0 <= value < 2**256): return if_number elif is_hex_encoded_block_number(value): return if_number else: raise ValueError( "Value did not match any of the recognized block identifiers: {0}".format(value) )
def to_text(primitive=None, hexstr=None, text=None): assert_one_val(primitive, hexstr=hexstr, text=text) if hexstr is not None: return to_bytes(hexstr=hexstr).decode('utf-8') elif text is not None: return text elif isinstance(primitive, str): return to_text(hexstr=primitive) elif isinstance(primitive, bytes): return primitive.decode('utf-8') elif is_integer(primitive): byte_encoding = int_to_big_endian(primitive) return to_text(byte_encoding) raise TypeError("Expected an int, bytes or hexstr.")
def to_bytes(primitive=None, hexstr=None, text=None): assert_one_val(primitive, hexstr=hexstr, text=text) if is_boolean(primitive): return b'\x01' if primitive else b'\x00' elif isinstance(primitive, bytes): return primitive elif is_integer(primitive): return to_bytes(hexstr=to_hex(primitive)) elif hexstr is not None: if len(hexstr) % 2: hexstr = '0x0' + remove_0x_prefix(hexstr) return decode_hex(hexstr) elif text is not None: return text.encode('utf-8') raise TypeError("expected an int in first arg, or keyword of hexstr or text")
def to_text(primitive=None, hexstr=None, text=None): if bytes is str: # must be able to tell the difference between bytes and a hexstr raise NotImplementedError("This method only works in Python 3+.") assert_one_val(primitive, hexstr=hexstr, text=text) if hexstr is not None: return to_bytes(hexstr=hexstr).decode('utf-8') elif text is not None: return text elif isinstance(primitive, str): return to_text(hexstr=primitive) elif isinstance(primitive, bytes): return primitive.decode('utf-8') elif is_integer(primitive): byte_encoding = int_to_big_endian(primitive) return to_text(byte_encoding) raise TypeError("Expected an int, bytes or hexstr.")
def _get_block_by_number(method, params, block_info=_block_info): block_id = params[0] blocks = block_info['blocks'] head_block_number = block_info['head_block_number'] if block_id == 'latest': return blocks[head_block_number] elif block_id == 'pending': if head_block_number + 1 >= len(blocks): raise ValueError("no pending block") return blocks[head_block_number + 1] elif block_id == 'earliest': return blocks[0] elif is_integer(block_id): if block_id <= head_block_number: return blocks[block_id] else: return None else: raise TypeError('Invalid type for block_id')
def test_net_peerCount(self, web3): peer_count = web3.net.peerCount assert is_integer(peer_count)
def test_eth_chain_id(self, w3): chain_id = w3.eth.chain_id assert is_integer(chain_id) assert chain_id == 131277322940537
def test_eth_blockNumber(self, web3): block_number = web3.eth.blockNumber assert is_integer(block_number) assert block_number >= 0
def test_eth_chain_id(self, w3): chain_id = w3.eth.chain_id assert is_integer(chain_id) assert chain_id == 61
def test_eth_getBalance(self, web3): coinbase = web3.eth.coinbase balance = web3.eth.getBalance(coinbase) assert is_integer(balance) assert balance >= 0
def test_eth_chainId(self, web3): chain_id = web3.eth.chainId assert is_integer(chain_id) assert chain_id == 61
def test_eth_gasPrice(self, web3): gas_price = web3.eth.gasPrice assert is_integer(gas_price) assert gas_price > 0
def test_eth_blockNumber(web3): block_number = web3.eth.blockNumber assert is_integer(block_number)
def test_platon_getBlockTransactionCountByNumber_block_with_txn(self, platon_connect, block_with_txn): transaction_count = platon_connect.getBlockTransactionCount(block_with_txn['number']) assert is_integer(transaction_count) assert transaction_count >= 1
def create_block_uri(chain_id, block_identifier): if is_integer(block_identifier): return create_BIP122_uri(chain_id, 'block', str(block_identifier)) else: return create_BIP122_uri(chain_id, 'block', remove_0x_prefix(block_identifier))
def test_platon_getBlockTransactionCountByNumber_empty_block(self, platon_connect, empty_block): transaction_count = platon_connect.getBlockTransactionCount(empty_block['number']) assert is_integer(transaction_count) assert transaction_count == 0
def test_getBlockTransactionCountByHash_empty_block(self, platon_connect, empty_block): transaction_count = platon_connect.getBlockTransactionCount(empty_block['hash']) assert is_integer(transaction_count) assert transaction_count == 0
def test_gasPrice(self, platon_connect): gas_price = platon_connect.gasPrice assert is_integer(gas_price) assert gas_price > 0
def test_eth_getBlockTransactionCountByNumber_block_with_txn(self, web3, block_with_txn): transaction_count = web3.eth.getBlockTransactionCount(block_with_txn['number']) assert is_integer(transaction_count) assert transaction_count >= 1
def test_eth_hashrate(self, web3): hashrate = web3.eth.hashrate assert is_integer(hashrate) assert hashrate >= 0
def test_get_nonce(self, eth_tester): for account in eth_tester.get_accounts(): nonce = eth_tester.get_nonce(account) assert is_integer(nonce) assert nonce >= UINT256_MIN assert nonce <= UINT256_MAX
def validate_positive_integer(value): error_message = "Value must be positive integers. Got: {}".format(value, ) if not is_integer(value) or is_boolean(value): raise ValidationError(error_message) elif value < 0: raise ValidationError(error_message)
def test_eth_getTransactionCount(self, web3): coinbase = web3.eth.coinbase transaction_count = web3.eth.getTransactionCount(coinbase) assert is_integer(transaction_count) assert transaction_count >= 0
def test_eth_blockNumber(self, web3: "Web3") -> None: block_number = web3.eth.blockNumber assert is_integer(block_number) assert block_number >= 0
def test_eth_getTransactionCount(self, web3, unlocked_account_dual_type): transaction_count = web3.eth.getTransactionCount( unlocked_account_dual_type) assert is_integer(transaction_count) assert transaction_count >= 0
def test_eth_getBlockTransactionCountByNumber_empty_block(self, web3, empty_block): transaction_count = web3.eth.getBlockTransactionCount(empty_block['number']) assert is_integer(transaction_count) assert transaction_count == 0
def _is_valid_distance(value: Any) -> bool: return is_integer(value) and 0 <= value <= 256
def test_eth_getUncleCountByBlockNumber(self, web3, empty_block): uncle_count = web3.eth.getUncleCount(empty_block['number']) assert is_integer(uncle_count) assert uncle_count == 0
def test_eth_chainId(self, w3): with pytest.warns(DeprecationWarning): chain_id = w3.eth.chainId assert is_integer(chain_id) assert chain_id == 61
def test_eth_getUncleCountByBlockNumber(self, web3: "Web3", empty_block: BlockData) -> None: uncle_count = web3.eth.getUncleCount(empty_block['number']) assert is_integer(uncle_count) assert uncle_count == 0
def test_eth_getTransactionCount( self, web3: "Web3", unlocked_account_dual_type: ChecksumAddress ) -> None: transaction_count = web3.eth.getTransactionCount(unlocked_account_dual_type) assert is_integer(transaction_count) assert transaction_count >= 0
def test_eth_hashrate(self, web3: "Web3") -> None: hashrate = web3.eth.hashrate assert is_integer(hashrate) assert hashrate >= 0
def test_eth_gasPrice(self, web3: "Web3") -> None: gas_price = web3.eth.gasPrice assert is_integer(gas_price) assert gas_price > 0
def validate_integer(value: Any) -> None: if not is_integer(value) or isinstance(value, bool): raise ValidationError("Value must be a an integer. Got: {0}".format( type(value)))
def test_get_nonce_simple_fuzzing(self, eth_tester, account): nonce = eth_tester.get_nonce(account) assert is_integer(nonce) assert nonce >= UINT256_MIN assert nonce <= UINT256_MAX
def test_get_balance_of_listed_accounts(self, eth_tester): for account in eth_tester.get_accounts(): balance = eth_tester.get_balance(account) assert is_integer(balance) assert balance >= UINT256_MIN assert balance <= UINT256_MAX