def deep_merge_dicts(*dicts): for key in set(itertools.chain(*(_dict.keys() for _dict in dicts))): values = tuple((_dict[key] for _dict in dicts if key in _dict)) if is_dict(values[-1]): yield key, deep_merge_dicts(*( _dict[key] for _dict in dicts if is_dict(_dict.get(key)) )) else: yield key, values[-1]
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 generate_cache_key(value): """ Generates a cache key for the *args and **kwargs """ if is_bytes(value): return hashlib.md5(value).hexdigest() elif is_text(value): return generate_cache_key(force_bytes(value)) elif is_boolean(value) or is_null(value) or is_number(value): return generate_cache_key(repr(value)) elif is_dict(value): return generate_cache_key(( (key, value[key]) for key in sorted(value.keys()) )) elif is_list_like(value) or isinstance(value, Generator): return generate_cache_key("".join(( generate_cache_key(item) for item in value ))) else: raise TypeError("Cannot generate cache key for value {0} of type {1}".format( value, type(value), ))
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_getTransactionReceipt_mined(self, web3, block_with_txn, mined_txn_hash): receipt = web3.eth.getTransactionReceipt(mined_txn_hash) assert is_dict(receipt) assert receipt['blockNumber'] == block_with_txn['number'] assert receipt['blockHash'] == block_with_txn['hash'] assert receipt['transactionIndex'] == 0 assert receipt['transactionHash'] == HexBytes(mined_txn_hash)
def test_fixture_middleware(method, params, expected): middleware = construct_fixture_middleware(FIXTURES)(_make_request, None) actual = middleware(method, params) assert is_dict(actual) assert 'result' in actual assert actual['result'] == expected
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 validate_abi(abi): """ Helper function for validating an ABI """ if not is_list_like(abi): raise ValueError("'abi' is not a list") for e in abi: if not is_dict(e): raise ValueError("The elements of 'abi' are not all dictionaries")
def decrypt(keyfile_json, password): if isinstance(keyfile_json, str): keyfile = json.loads(keyfile_json) elif is_dict(keyfile_json): keyfile = keyfile_json else: raise TypeError("The keyfile should be supplied as a JSON string, or a dictionary.") password_bytes = text_if_str(to_bytes, password) return decode_keyfile_json(keyfile, password_bytes)
def middleware(method, params): response = make_request(method, params) if 'result' in response: result = response['result'] if is_dict(result) and not isinstance(result, AttributeDict): return assoc(response, 'result', AttributeDict.recursive(result)) else: return response else: return response
def request_blocking(self, method, params): """ Make a synchronous request using the provider """ response_raw = self.provider.make_request(method, params) if is_string(response_raw): response = json.loads(force_text(response_raw)) elif is_dict(response_raw): response = response_raw if "error" in response: raise ValueError(response["error"]) return response['result']
def test_eth_getTransactionReceipt_with_log_entry(self, web3, block_with_txn_with_log, emitter_contract, txn_hash_with_log): receipt = web3.eth.getTransactionReceipt(txn_hash_with_log) assert is_dict(receipt) assert receipt['blockNumber'] == block_with_txn_with_log['number'] assert receipt['blockHash'] == block_with_txn_with_log['hash'] assert receipt['transactionIndex'] == 0 assert receipt['transactionHash'] == HexBytes(txn_hash_with_log) assert len(receipt['logs']) == 1 log_entry = receipt['logs'][0] assert log_entry['blockNumber'] == block_with_txn_with_log['number'] assert log_entry['blockHash'] == block_with_txn_with_log['hash'] assert log_entry['logIndex'] == 0 assert is_same_address(log_entry['address'], emitter_contract.address) assert log_entry['transactionIndex'] == 0 assert log_entry['transactionHash'] == HexBytes(txn_hash_with_log)
def validate_abi(abi: ABI) -> None: """ Helper function for validating an ABI """ if not is_list_like(abi): raise ValueError("'abi' is not a list") if not all(is_dict(e) for e in abi): raise ValueError("'abi' is not a list of dictionaries") functions = filter_by_type('function', abi) selectors = groupby( compose(encode_hex, function_abi_to_4byte_selector), functions ) duplicates = valfilter(lambda funcs: len(funcs) > 1, selectors) if duplicates: raise ValueError( 'Abi contains functions with colliding selectors. ' 'Functions {0}'.format(_prepare_selector_collision_msg(duplicates)) )
def validate_abi(abi): """ Helper function for validating an ABI """ if not is_list_like(abi): raise ValueError("'abi' is not a list") if not all(is_dict(e) for e in abi): raise ValueError("'abi' is not a list of dictionaries") functions = filter_by_type('function', abi) selectors = groupby( compose(encode_hex, function_abi_to_4byte_selector), functions ) duplicates = valfilter(lambda funcs: len(funcs) > 1, selectors) if duplicates: raise ValueError( 'Abi contains functions with colliding selectors. ' 'Functions {0}'.format(_prepare_selector_collision_msg(duplicates)) )
def is_rpc_structured_access_list(val): """Returns true if 'val' is a valid JSON-RPC structured access list.""" if not is_list_like(val): return False for d in val: if not is_dict(d): return False if len(d) != 2: return False address = d.get('address') storage_keys = d.get('storageKeys') if any(_ is None for _ in (address, storage_keys)): return False if not is_address(address): return False if not is_list_like(storage_keys): return False for storage_key in storage_keys: if not is_int_or_prefixed_hexstr(storage_key): return False return True
def _validate_inbound_access_list(access_list): """ Validates the structure of an inbound access list. This is similar to the JSON-RPC structure for an access list only with `under_score` keys rather than `camelCase`. >>> _access_list = ( ... { ... 'address': '0xde0b295669a9fd93d5f28d9ec85e40f4cb697bae', ... 'storage_keys': ( ... '0x0000000000000000000000000000000000000000000000000000000000000003', ... '0x0000000000000000000000000000000000000000000000000000000000000007', ... ) ... }, ... { ... 'address': '0xbb9bc244d798123fde783fcc1c72d3bb8c189413', ... 'storage_keys': () ... }, ... ) """ if not is_list_like(access_list): raise ValidationError('access_list is not list-like') for entry in access_list: if not is_dict(entry) and len(entry) != 2: raise ValidationError( f'access_list entry not properly formatted: {entry}') address = entry.get('address') storage_keys = entry.get('storage_keys') if not is_hex_address(address): raise ValidationError( f'access_list address must be a hexadecimal address: {address}' ) if not is_list_like(storage_keys): raise ValidationError( f'access_list storage keys are not list-like: {storage_keys}') if len(storage_keys) > 0 and not all( is_32byte_hex_string(k) for k in storage_keys): raise ValidationError( f'one or more access list storage keys not formatted properly: {storage_keys}' )
def generate_cache_key(value): """ Generates a cache key for the *args and **kwargs """ if is_bytes(value): return hashlib.md5(value).hexdigest() elif is_text(value): return generate_cache_key(to_bytes(text=value)) elif is_boolean(value) or is_null(value) or is_number(value): return generate_cache_key(repr(value)) elif is_dict(value): return generate_cache_key( ((key, value[key]) for key in sorted(value.keys()))) elif is_list_like(value) or isinstance(value, Generator): return generate_cache_key("".join( (generate_cache_key(item) for item in value))) else: raise TypeError( "Cannot generate cache key for value {0} of type {1}".format( value, type(value), ))
def flatten_mapping(config, base_prefix=None): """ An `.items()` implementation for nested configuration dictionaries. It flattens out the entire keyspace returning an interable of 2-tuples. >>> flatten_mapping({'a': {'b': {'c': 1}, 'd': 2}, 'e': 3}) ( ('a.b.c', 1), ('a.d', 2), ('e': 3), ) """ if base_prefix is None: base_prefix = tuple() for key, value in config.items(): prefix = base_prefix + (key, ) if is_dict(value): for sub_key, sub_value in flatten_mapping(value, prefix): yield sub_key, sub_value else: yield '.'.join(prefix), value
def flatten_mapping(config, base_prefix=None): """ An `.items()` implementation for nested configuration dictionaries. It flattens out the entire keyspace returning an interable of 2-tuples. >>> flatten_mapping({'a': {'b': {'c': 1}, 'd': 2}, 'e': 3}) ( ('a.b.c', 1), ('a.d', 2), ('e': 3), ) """ if base_prefix is None: base_prefix = tuple() for key, value in config.items(): prefix = base_prefix + (key,) if is_dict(value): for sub_key, sub_value in flatten_mapping(value, prefix): yield sub_key, sub_value else: yield '.'.join(prefix), value
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 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 trim_hex(hexstr) 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): padded = encode_hex(value) return trim_hex(padded) elif is_string(value): return to_hex(text=value) if is_integer(value): # python2 longs end up with an `L` hanging off the end of their hexidecimal # representation. return hex(value).rstrip('L') raise TypeError( "Unsupported type: '{0}'. Must be one of Boolean, Dictionary, String, " "or Integer.".format(repr(type(value))) )
def block_with_txn(web3, geth_fixture_data): block = web3.eth.getBlock(geth_fixture_data['block_with_txn_hash']) assert is_dict(block) return block
def validate_transaction(value, txn_type): if txn_type not in ALLOWED_TRANSACTION_TYPES: raise TypeError( "the `txn_type` parameter must be one of send/call/estimate") if not is_dict(value): raise ValidationError( "Transaction must be a dictionary. Got: {0}".format(type(value))) unknown_keys = tuple( sorted( set(value.keys()).difference(TRANSACTION_TYPE_INFO[txn_type], ))) if unknown_keys: raise ValidationError( "Only the keys '{0}' are allowed. Got extra keys: '{1}'".format( "/".join(tuple(sorted(TRANSACTION_TYPE_INFO[txn_type]))), "/".join(unknown_keys), )) if txn_type == 'send': required_keys = {'from', 'gas'} elif txn_type == 'send_signed': required_keys = {'from', 'gas'} | SIGNED_TRANSACTION_KEYS elif txn_type in {'estimate', 'call'}: required_keys = set(['from']) else: raise Exception("Invariant: code path should be unreachable") missing_required_keys = tuple( sorted(required_keys.difference(value.keys()))) if missing_required_keys: raise ValidationError( "Transaction is missing the required keys: '{0}'".format( "/".join(missing_required_keys), )) if 'from' in value: validate_account(value['from']) if 'to' in value and value['to'] != '': validate_account(value['to']) elif 'to' in value and value['to'] == '': validate_text(value['to']) if 'gas' in value: validate_uint256(value['gas']) if 'gas_price' in value: validate_uint256(value['gas_price']) if 'value' in value: validate_uint256(value['value']) if 'nonce' in value: validate_uint256(value['nonce']) if 'data' in value: bad_data_message = ( "Transaction data must be a hexidecimal encoded string. Got: " "{0}".format(value['data'])) if not is_text(value['data']): raise ValidationError(bad_data_message) elif not remove_0x_prefix(value['data']): pass elif not is_hex(value['data']): raise ValidationError(bad_data_message) try: decode_hex(value['data']) except (binascii.Error, TypeError): # TypeError is for python2 # binascii.Error is for python3 raise ValidationError(bad_data_message) if txn_type == 'send_signed': validate_uint256(value['r']) validate_uint256(value['s']) validate_uint8(value['v'])
def test_eth_getTransactionByBlockHashAndIndex( self, web3: "Web3", block_with_txn: BlockData, mined_txn_hash: HexStr) -> None: transaction = web3.eth.getTransactionByBlock(block_with_txn['hash'], 0) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def test_eth_getTransactionByHash_contract_creation( self, web3: "Web3", math_contract_deploy_txn_hash: HexStr) -> None: transaction = web3.eth.getTransaction(math_contract_deploy_txn_hash) assert is_dict(transaction) assert transaction['to'] is None, "to field is %r" % transaction['to']
def test_eth_getTransactionByBlockNumberAndIndex(self, web3, block_with_txn, mined_txn_hash): transaction = web3.eth.getTransactionFromBlock(block_with_txn['number'], 0) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def empty_block(web3, parity_fixture_data): block = web3.eth.getBlock(parity_fixture_data['empty_block_hash']) assert is_dict(block) return block
def test_eth_getTransactionByBlockNumberAndIndex(self, web3, block_with_txn, mined_txn_hash): transaction = web3.eth.getTransactionFromBlock(block_with_txn['number'], 0) assert is_dict(transaction) assert transaction['hash'] == mined_txn_hash
def test_eth_getTransactionByHash(self, webu, mined_txn_hash): transaction = webu.eth.getTransaction(mined_txn_hash) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def setup_chain_state(web3): coinbase = web3.eth.coinbase assert is_same_address(coinbase, COINBASE) # # Math Contract # math_contract_factory = web3.eth.contract( abi=MATH_ABI, bytecode=MATH_BYTECODE, ) math_deploy_receipt = deploy_contract(web3, 'math', math_contract_factory) assert is_dict(math_deploy_receipt) # # Emitter Contract # emitter_contract_factory = web3.eth.contract( abi=EMITTER_ABI, bytecode=EMITTER_BYTECODE, ) emitter_deploy_receipt = deploy_contract(web3, 'emitter', emitter_contract_factory) emitter_contract = emitter_contract_factory( emitter_deploy_receipt['contractAddress']) txn_hash_with_log = emitter_contract.transact({ 'from': web3.eth.coinbase, }).logDouble(which=EMITTER_ENUM['LogDoubleWithIndex'], arg0=12345, arg1=54321) print('TXN_HASH_WITH_LOG:', txn_hash_with_log) txn_receipt_with_log = mine_transaction_hash(web3, txn_hash_with_log) block_with_log = web3.eth.getBlock(txn_receipt_with_log['blockHash']) print('BLOCK_HASH_WITH_LOG:', block_with_log['hash']) # # Empty Block # empty_block_number = mine_block(web3) print('MINED_EMPTY_BLOCK') empty_block = web3.eth.getBlock(empty_block_number) assert is_dict(empty_block) assert not empty_block['transactions'] print('EMPTY_BLOCK_HASH:', empty_block['hash']) # # Block with Transaction # web3.personal.unlockAccount(coinbase, KEYFILE_PW) web3.miner.start(1) mined_txn_hash = web3.eth.sendTransaction({ 'from': coinbase, 'to': coinbase, 'value': 1, 'gas': 21000, 'gas_price': web3.eth.gasPrice, }) mined_txn_receipt = mine_transaction_hash(web3, mined_txn_hash) print('MINED_TXN_HASH:', mined_txn_hash) block_with_txn = web3.eth.getBlock(mined_txn_receipt['blockHash']) print('BLOCK_WITH_TXN_HASH:', block_with_txn['hash']) geth_fixture = { 'math_deploy_txn_hash': math_deploy_receipt['transactionHash'], 'math_address': math_deploy_receipt['contractAddress'], 'emitter_deploy_txn_hash': emitter_deploy_receipt['transactionHash'], 'emitter_address': emitter_deploy_receipt['contractAddress'], 'txn_hash_with_log': txn_hash_with_log, 'block_hash_with_log': block_with_log['hash'], 'empty_block_hash': empty_block['hash'], 'mined_txn_hash': mined_txn_hash, 'block_with_txn_hash': block_with_txn['hash'], } return geth_fixture
def test_eth_getTransactionByHash_contract_creation(self, web3, math_contract_deploy_txn_hash): transaction = web3.eth.getTransaction(math_contract_deploy_txn_hash) assert is_dict(transaction) assert transaction['to'] is None
def upgrade_v4_to_v5(v4_config): """ Upgrade a v4 config file to a v5 config file. """ errors = get_validation_errors(v4_config, version=V4) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), ) ) v4_default_config = load_default_config(version=V4) v5_default_config = load_default_config(version=V5) if v4_config == v4_default_config: return v5_default_config upgraded_v4_config = copy.deepcopy(v4_config) # new configuration values whos keys were not present in the previous # configuration. for key_path in NEW_V5_PATHS: if has_nested_key(upgraded_v4_config, key_path): continue set_nested_key( upgraded_v4_config, key_path, get_nested_key(v5_default_config, key_path), ) # keys in the new configuration that were relocated. for old_path, new_path in MOVED_V4_PATHS.items(): default_value = get_nested_key(v5_default_config, new_path) if has_nested_key(upgraded_v4_config, old_path): existing_value = pop_nested_key(upgraded_v4_config, old_path) if is_dict(default_value) and is_dict(existing_value): merged_value = deep_merge_dicts(default_value, existing_value) elif is_list_like(default_value) and is_list_like(existing_value): merged_value = list(set(itertools.chain(default_value, existing_value))) else: raise ValueError( "Unable to merge {0} with {1}".format( type(default_value), type(existing_value), ) ) set_nested_key( upgraded_v4_config, new_path, merged_value, ) else: set_nested_key( upgraded_v4_config, new_path, default_value, ) # keys from the previous configuration that were changed. for key_path in MODIFIED_V4_PATHS: new_default = get_nested_key(v5_default_config, key_path) if key_path not in upgraded_v4_config: set_nested_key( upgraded_v4_config, key_path, new_default, ) else: current_value = get_nested_key(upgraded_v4_config, key_path) old_default = get_nested_key(v4_default_config, key_path) if current_value == old_default: set_nested_key( upgraded_v4_config, key_path, new_default, ) # bump the version set_nested_key(upgraded_v4_config, 'version', V5) errors = get_validation_errors(upgraded_v4_config, version=V5) if errors: raise ValueError( "Upgraded configuration did not pass validation:\n\n" "\n=============Original-Configuration============\n" "{0}" "\n=============Upgraded-Configuration============\n" "{1}" "\n=============Validation-Errors============\n" "{2}".format( pprint.pformat(dict(v4_config)), pprint.pformat(dict(upgraded_v4_config)), format_errors(errors), ) ) return upgraded_v4_config
def block_with_txn(webu, parity_fixture_data): block = webu.eth.getBlock(parity_fixture_data['block_with_txn_hash']) assert is_dict(block) return block
def test_eth_getTransactionByHash(self, web3, mined_txn_hash): transaction = web3.eth.getTransaction(mined_txn_hash) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def math_contract(web3, math_contract_factory, math_contract_deploy_txn_hash): deploy_receipt = web3.eth.waitForTransactionReceipt(math_contract_deploy_txn_hash) assert is_dict(deploy_receipt) contract_address = deploy_receipt['contractAddress'] assert is_checksum_address(contract_address) return math_contract_factory(contract_address)
def test_eth_getTransactionReceipt_mined(self, web3, block_with_txn, mined_txn_hash): receipt = web3.eth.getTransactionReceipt(mined_txn_hash) assert is_dict(receipt) assert receipt['blockNumber'] == block_with_txn['number'] assert receipt['blockHash'] == block_with_txn['hash'] assert receipt['transactionIndex'] == 0
def test_eth_getTransactionByHash(self, web3: "Web3", mined_txn_hash: HexStr) -> None: transaction = web3.eth.getTransaction(mined_txn_hash) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def block_with_txn_with_log(web3, parity_fixture_data): block = web3.eth.getBlock(parity_fixture_data['block_hash_with_log']) assert is_dict(block) return block
def emitter_contract(web3, emitter_contract_factory, emitter_contract_deploy_txn_hash): deploy_receipt = web3.eth.getTransactionReceipt(emitter_contract_deploy_txn_hash) assert is_dict(deploy_receipt) contract_address = deploy_receipt['contractAddress'] assert is_checksum_address(contract_address) return emitter_contract_factory(contract_address)
def emitter_contract(w3, emitter_contract_factory, emitter_contract_deploy_txn_hash): deploy_receipt = w3.eth.wait_for_transaction_receipt(emitter_contract_deploy_txn_hash) assert is_dict(deploy_receipt) contract_address = deploy_receipt['contractAddress'] assert is_checksum_address(contract_address) return emitter_contract_factory(contract_address)
def upgrade_v3_to_v4(v3_config): """ Upgrade a v3 config file to a v4 config file. """ errors = get_validation_errors(v3_config, version=V3) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), ) ) v3_default_config = load_default_config(version=V3) v4_default_config = load_default_config(version=V4) if v3_config == v3_default_config: return v4_default_config upgraded_v3_config = copy.deepcopy(v3_config) for key_path in NEW_V4_PATHS: if has_nested_key(upgraded_v3_config, key_path): continue set_nested_key( upgraded_v3_config, key_path, get_nested_key(v4_default_config, key_path), ) for old_path, new_path in MOVED_V3_PATHS.items(): default_value = get_nested_key(v4_default_config, new_path) if has_nested_key(upgraded_v3_config, old_path): existing_value = pop_nested_key(upgraded_v3_config, old_path) if is_dict(default_value) and is_dict(existing_value): merged_value = deep_merge_dicts(default_value, existing_value) elif is_list_like(default_value) and is_list_like(existing_value): merged_value = list(set(itertools.chain(default_value, existing_value))) else: raise ValueError( "Unable to merge {0} with {1}".format( type(default_value), type(existing_value), ) ) set_nested_key( upgraded_v3_config, new_path, merged_value, ) else: set_nested_key( upgraded_v3_config, new_path, default_value, ) # bump the version set_nested_key(upgraded_v3_config, 'version', V4) errors = get_validation_errors(upgraded_v3_config, version=V4) if errors: raise ValueError( "Upgraded configuration did not pass validation:\n\n" "\n=============Original-Configuration============\n" "{0}" "\n=============Upgraded-Configuration============\n" "{1}" "\n=============Validation-Errors============\n" "{2}".format( pprint.pformat(dict(v3_config)), pprint.pformat(dict(upgraded_v3_config)), format_errors(errors), ) ) return upgraded_v3_config
def is_array_of_dicts(value): if not is_list_like(value): return False return all((is_dict(item) for item in value))
def test_vns_getTransactionByHash(self, web3, mined_txn_hash): transaction = web3.vns.getTransaction(mined_txn_hash) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def test_eth_getTransactionByHash_contract_creation( self, web3, math_contract_deploy_txn_hash): transaction = web3.eth.getTransaction(math_contract_deploy_txn_hash) assert is_dict(transaction) assert transaction['to'] is None
def test_vns_getTransactionByBlockNumberAndIndex(self, web3, block_with_txn, mined_txn_hash): transaction = web3.vns.getTransactionByBlock(block_with_txn['number'], 0) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def _castAttributeDict(self, maybe_dict): """Return an AttributeDict as is provided by web3 middleware.""" if is_dict(maybe_dict) and not isinstance(maybe_dict, AttributeDict): return AttributeDict.recursive(maybe_dict) else: return maybe_dict
def test_eth_getTransactionByBlockHashAndIndex(self, webu, block_with_txn, mined_txn_hash): transaction = webu.eth.getTransactionFromBlock(block_with_txn['hash'], 0) assert is_dict(transaction) assert transaction['hash'] == HexBytes(mined_txn_hash)
def setup_chain_state(web3): coinbase = web3.eth.coinbase assert is_same_address(coinbase, common.COINBASE) # # Math Contract # math_contract_factory = web3.eth.contract( abi=MATH_ABI, bytecode=MATH_BYTECODE, ) math_deploy_receipt = common.deploy_contract(web3, 'math', math_contract_factory) assert is_dict(math_deploy_receipt) # # Emitter Contract # emitter_contract_factory = web3.eth.contract( abi=EMITTER_ABI, bytecode=EMITTER_BYTECODE, ) emitter_deploy_receipt = common.deploy_contract(web3, 'emitter', emitter_contract_factory) emitter_contract = emitter_contract_factory(emitter_deploy_receipt['contractAddress']) txn_hash_with_log = emitter_contract.functions.logDouble( which=EMITTER_ENUM['LogDoubleWithIndex'], arg0=12345, arg1=54321, ).transact({ 'from': web3.eth.coinbase, }) print('TXN_HASH_WITH_LOG:', txn_hash_with_log) txn_receipt_with_log = common.mine_transaction_hash(web3, txn_hash_with_log) block_with_log = web3.eth.getBlock(txn_receipt_with_log['blockHash']) print('BLOCK_HASH_WITH_LOG:', block_with_log['hash']) # # Empty Block # empty_block_number = common.mine_block(web3) print('MINED_EMPTY_BLOCK') empty_block = web3.eth.getBlock(empty_block_number) assert is_dict(empty_block) assert not empty_block['transactions'] print('EMPTY_BLOCK_HASH:', empty_block['hash']) # # Block with Transaction # web3.personal.unlockAccount(coinbase, common.KEYFILE_PW) web3.miner.start(1) mined_txn_hash = web3.eth.sendTransaction({ 'from': coinbase, 'to': coinbase, 'value': 1, 'gas': 21000, 'gas_price': web3.eth.gasPrice, }) mined_txn_receipt = common.mine_transaction_hash(web3, mined_txn_hash) print('MINED_TXN_HASH:', mined_txn_hash) block_with_txn = web3.eth.getBlock(mined_txn_receipt['blockHash']) print('BLOCK_WITH_TXN_HASH:', block_with_txn['hash']) geth_fixture = { 'math_deploy_txn_hash': math_deploy_receipt['transactionHash'], 'math_address': math_deploy_receipt['contractAddress'], 'emitter_deploy_txn_hash': emitter_deploy_receipt['transactionHash'], 'emitter_address': emitter_deploy_receipt['contractAddress'], 'txn_hash_with_log': txn_hash_with_log, 'block_hash_with_log': block_with_log['hash'], 'empty_block_hash': empty_block['hash'], 'mined_txn_hash': mined_txn_hash, 'block_with_txn_hash': block_with_txn['hash'], } return geth_fixture
def test_vns_getTransactionByHash_contract_creation(self, web3, math_contract_deploy_txn_hash): transaction = web3.vns.getTransaction(math_contract_deploy_txn_hash) assert is_dict(transaction) assert transaction['to'] is None, "to field is %r" % transaction['to']
def math_contract(web3, math_contract_factory, math_contract_deploy_txn_hash): deploy_receipt = web3.eth.getTransactionReceipt(math_contract_deploy_txn_hash) assert is_dict(deploy_receipt) contract_address = deploy_receipt['contractAddress'] assert is_address(contract_address) return math_contract_factory(contract_address)
def upgrade_v3_to_v4(v3_config): """ Upgrade a v3 config file to a v4 config file. """ errors = get_validation_errors(v3_config, version=V3) if errors: raise ValueError( "Cannot upgrade invalid config. Please ensure that your current " "configuration file is valid:\n\n{0}".format( format_errors(errors), )) v3_default_config = load_default_config(version=V3) v4_default_config = load_default_config(version=V4) if v3_config == v3_default_config: return v4_default_config upgraded_v3_config = copy.deepcopy(v3_config) for key_path in NEW_V4_PATHS: if has_nested_key(upgraded_v3_config, key_path): continue set_nested_key( upgraded_v3_config, key_path, get_nested_key(v4_default_config, key_path), ) for old_path, new_path in MOVED_V3_PATHS.items(): default_value = get_nested_key(v4_default_config, new_path) if has_nested_key(upgraded_v3_config, old_path): existing_value = pop_nested_key(upgraded_v3_config, old_path) if is_dict(default_value) and is_dict(existing_value): merged_value = deep_merge_dicts(default_value, existing_value) elif is_list_like(default_value) and is_list_like(existing_value): merged_value = list( set(itertools.chain(default_value, existing_value))) else: raise ValueError("Unable to merge {0} with {1}".format( type(default_value), type(existing_value), )) set_nested_key( upgraded_v3_config, new_path, merged_value, ) else: set_nested_key( upgraded_v3_config, new_path, default_value, ) # bump the version set_nested_key(upgraded_v3_config, 'version', V4) errors = get_validation_errors(upgraded_v3_config, version=V4) if errors: raise ValueError("Upgraded configuration did not pass validation:\n\n" "\n=============Original-Configuration============\n" "{0}" "\n=============Upgraded-Configuration============\n" "{1}" "\n=============Validation-Errors============\n" "{2}".format( pprint.pformat(dict(v3_config)), pprint.pformat(dict(upgraded_v3_config)), format_errors(errors), )) return upgraded_v3_config
def validate_is_dict(value): if not is_dict(value): raise ValidationError("Value must be a dictionary. Got: {}".format( type(value)))