def create_node_configuration(miner=True, port=30301, rpcport=8101, host='127.0.0.1', node_key_seed=0): """ Create configuration (ports, keys, etc...) for one node. :param miner: if True, setup to be a mining node :param port: the p2p port to assign :param rpcport: the port to assign :param host: the host for the node to run on :return: node configuration dict """ node = dict() if miner: node['minerthreads'] = 1 # conservative node['unlock'] = 0 node['nodekey'] = sha3('node:{}'.format(node_key_seed).encode()) node['nodekeyhex'] = encode_hex(node['nodekey']) node['pub'] = encode_hex(privtopub_enode(node['nodekey'])) node['address'] = privatekey_to_address(node['nodekey']) node['host'] = host node['port'] = port node['rpcport'] = rpcport node['enode'] = 'enode://{pub}@{host}:{port}'.format(**node) return node
def test_get_privkey(test_keystore): account_manager = AccountManager(test_keystore) assert 'f696ecb5c767263c797a035db6f6008d38d852960ed33a491a58390b003fb605' == encode_hex( account_manager.get_privkey('0d5a0e4fece4b84365b9b8dba6e6d41348c73645', '123'), ) assert 'f696ecb5c767263c797a035db6f6008d38d852960ed33a491a58390b003fb605' == encode_hex( account_manager.get_privkey( '0x0d5a0e4fece4b84365b9b8dba6e6d41348c73645', '123'), ) assert '36fa966441f259501110ba88f8212dfd7f8bacb07862a7d5cf8f31c1a64551e5' == encode_hex( account_manager.get_privkey('3593403033d18b82f7b4a0f18e1ed24623d23b20', '123'), ) assert '36fa966441f259501110ba88f8212dfd7f8bacb07862a7d5cf8f31c1a64551e5' == encode_hex( account_manager.get_privkey( '0x3593403033d18b82f7b4a0f18e1ed24623d23b20', '123'), ) # failures with pytest.raises(ValueError) as exc: account_manager.get_privkey( '0x3593403033d18b82f7b4a0f18e1ed24623d23b20', '456') assert 'MAC mismatch' in str(exc.value) with pytest.raises(ValueError) as exc: account_manager.get_privkey('a05934d3033d18b82f7b4adf18e1ed24e3d23b19', '123') assert 'Keystore file not found for a05934d3033d18b82f7b4adf18e1ed24e3d23b19' in str( exc.value)
def generate_accounts(seeds): """Create private keys and addresses for all seeds. """ return { seed: dict(privatekey=encode_hex(sha3(seed)), address=encode_hex(privatekey_to_address(sha3(seed)))) for seed in seeds }
def withdraw( self, partner: typing.Address, total_withdraw: int, partner_signature: typing.Address, signature: typing.Signature, ): log.info( 'withdraw called', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), total_withdraw=total_withdraw, ) self._check_channel_lock(partner) with releasing(self.channel_operations_lock[partner]): transaction_hash = self.proxy.transact( 'setTotalWithdraw', self.node_address, partner, total_withdraw, partner_signature, signature, ) self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout) receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: log.critical( 'withdraw failed', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), total_withdraw=total_withdraw, partner_signature=encode_hex(partner_signature), signature=encode_hex(signature), ) channel_opened = self.channel_is_opened(partner) if channel_opened is False: raise ChannelIncorrectStateError( 'Channel is not in an opened state. A withdraw cannot be made' ) raise TransactionThrew('Withdraw', receipt_or_none) log.info( 'withdraw successful', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), total_withdraw=total_withdraw, partner_signature=encode_hex(partner_signature), signature=encode_hex(signature), )
def __repr__(self): return ('<' 'LockedTransferSignedState msgid:{} id:{} token:{} lock:{}' ' target:{}' '>').format( self.message_identifier, self.payment_identifier, encode_hex(self.token), self.lock, encode_hex(self.target), )
def __repr__(self): return ('<' 'LockedTransferUnsignedState id:{} token:{} balance_proof:{} ' 'lock:{} target:{}' '>').format( self.payment_identifier, encode_hex(self.token), self.balance_proof, self.lock, encode_hex(self.target), )
def update_transfer(self, nonce, transferred_amount, locksroot, extra_hash, signature): if signature: if log.isEnabledFor(logging.INFO): log.info( 'updateTransfer called', node=pex(self.node_address), contract=pex(self.address), nonce=nonce, transferred_amount=transferred_amount, locksroot=encode_hex(locksroot), extra_hash=encode_hex(extra_hash), signature=encode_hex(signature), ) transaction_hash = estimate_and_transact( self.proxy, 'updateTransfer', nonce, transferred_amount, locksroot, extra_hash, signature, ) self.client.poll( unhexlify(transaction_hash), timeout=self.poll_timeout, ) receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: log.critical( 'updateTransfer failed', node=pex(self.node_address), contract=pex(self.address), nonce=nonce, transferred_amount=transferred_amount, locksroot=encode_hex(locksroot), extra_hash=encode_hex(extra_hash), signature=encode_hex(signature), ) self._check_exists() raise TransactionThrew('Update Transfer', receipt_or_none) if log.isEnabledFor(logging.INFO): log.info( 'updateTransfer successful', node=pex(self.node_address), contract=pex(self.address), nonce=nonce, transferred_amount=transferred_amount, locksroot=encode_hex(locksroot), extra_hash=encode_hex(extra_hash), signature=encode_hex(signature), )
def send_transaction( self, to: Address, value: int = 0, data: bytes = b'', startgas: int = None, ): """ Helper to send signed messages. This method will use the `privkey` provided in the constructor to locally sign the transaction. This requires an extended server implementation that accepts the variables v, r, and s. """ if to == to_canonical_address(NULL_ADDRESS): warnings.warn( 'For contract creation the empty string must be used.') transaction = dict( nonce=self.nonce(), gasPrice=self.gasprice(), gas=self.check_startgas(startgas), value=value, data=data, ) # add the to address if not deploying a contract if to != b'': transaction['to'] = to_checksum_address(to) signed_txn = self.web3.eth.account.signTransaction( transaction, self.privkey) result = self.web3.eth.sendRawTransaction(signed_txn.rawTransaction) encoded_result = encode_hex(result) return remove_0x_prefix(encoded_result)
def withdraw(self, unlock_proof): self._check_exists() log.info('withdraw called', contract=pex(self.address), unlock_proof=unlock_proof) if isinstance(unlock_proof.locked_encoded, messages.Lock): raise ValueError( 'unlock must be called with a lock encoded `.as_bytes`') merkleproof_encoded = ''.join(unlock_proof.merkle_proof) self.proxy.withdraw( unlock_proof.locked_encoded, merkleproof_encoded, unlock_proof.secret, ) self.tester_chain.mine(number_of_blocks=1) lock = messages.Lock.from_bytes(unlock_proof.locked_encoded) log.info( 'withdraw called', contract=pex(self.address), lock=lock, secret=encode_hex(unlock_proof.secret), )
def get_filter_events(jsonrpc_client: JSONRPCClient, contract_address: Address, topics: Optional[List[int]], from_block: Union[str, int] = 0, to_block: Union[str, int] = 'latest') -> List[Dict]: """ Get filter. This handles bad encoding from geth rpc. """ json_data = { 'fromBlock': from_block, 'toBlock': to_block, 'address': address_encoder(to_canonical_address(contract_address)), } if topics is not None: json_data['topics'] = [topic_encoder(topic) for topic in topics] filter_changes = jsonrpc_client.web3.eth.getLogs(json_data) # geth could return None if filter_changes is None: return [] result = [] for log_event in filter_changes: address = address_decoder(log_event['address']) data = data_decoder(log_event['data']) topics = [ topic_decoder(add_0x_prefix(encode_hex(topic))) for topic in log_event['topics'] ] block_number = log_event.get('blockNumber', 0) result.append({ 'topics': topics, 'data': data, 'address': address, 'block_number': block_number, 'event_data': log_event }) return result
def create_keystore_account(datadir, privkey=encode_hex(sha3(b'localhost:627'))): """ Create an account in `datadir` -- since we're not interested in the rewards, we don't care about the created address. :param datadir: the datadir in which the account is created :return: None """ with open(os.path.join(datadir, 'keyfile'), 'w') as f: f.write(privkey) create = Popen( shlex.split('geth --datadir {} account import {}'.format( datadir, os.path.join(datadir, 'keyfile'))), stdin=PIPE, universal_newlines=True ) create.stdin.write(DEFAULT_PW + os.linesep) time.sleep(.1) create.stdin.write(DEFAULT_PW + os.linesep) create.communicate() assert create.returncode == 0
def _process_filter_results(self, filter_changes: List) -> List[Dict]: # geth could return None if filter_changes is None: return [] result = list() for log_event in filter_changes: address = address_decoder(log_event['address']) data = data_decoder(log_event['data']) topics = [ topic_decoder(add_0x_prefix(encode_hex(topic))) for topic in log_event['topics'] ] block_number = log_event.get('blockNumber') result.append({ 'topics': topics, 'data': data, 'address': address, 'block_number': block_number, 'event_data': log_event }) return result
def settle( self, transferred_amount: int, locked_amount: int, locksroot: typing.Locksroot, partner: typing.Address, partner_transferred_amount: int, partner_locked_amount: int, partner_locksroot: typing.Locksroot, ): """ Settle the channel. Raises: ChannelBusyError: If the channel is busy with another operation """ log.info( 'settle called', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), transferred_amount=transferred_amount, locked_amount=locked_amount, locksroot=encode_hex(locksroot), partner_transferred_amount=partner_transferred_amount, partner_locked_amount=partner_locked_amount, partner_locksroot=encode_hex(partner_locksroot), ) self._check_channel_lock(partner) with releasing(self.channel_operations_lock[partner]): transaction_hash = self.proxy.transact( 'settleChannel', self.node_address, transferred_amount, locked_amount, locksroot, partner, partner_transferred_amount, partner_locked_amount, partner_locksroot, ) self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout) receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: log.info( 'settle failed', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), transferred_amount=transferred_amount, locked_amount=locked_amount, locksroot=encode_hex(locksroot), partner_transferred_amount=partner_transferred_amount, partner_locked_amount=partner_locked_amount, partner_locksroot=encode_hex(partner_locksroot), ) channel_closed = self.channel_is_closed(partner) if channel_closed is False: raise ChannelIncorrectStateError( 'Channel is not in a closed state. It cannot be settled', ) raise TransactionThrew('Settle', receipt_or_none) log.info( 'settle successful', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), transferred_amount=transferred_amount, locked_amount=locked_amount, locksroot=encode_hex(locksroot), partner_transferred_amount=partner_transferred_amount, partner_locked_amount=partner_locked_amount, partner_locksroot=encode_hex(partner_locksroot), )
def update_transfer( self, partner: typing.Address, nonce: typing.Nonce, balance_hash: typing.BalanceHash, additional_hash: typing.AdditionalHash, partner_signature: typing.Signature, signature: typing.Signature, ): log.info( 'updateNonClosingBalanceProof called', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), nonce=nonce, balance_hash=encode_hex(balance_hash), additional_hash=encode_hex(additional_hash), partner_signature=encode_hex(partner_signature), signature=encode_hex(signature), ) transaction_hash = self.proxy.transact( 'updateNonClosingBalanceProof', partner, self.node_address, balance_hash, nonce, additional_hash, partner_signature, signature, ) self.client.poll( unhexlify(transaction_hash), timeout=self.poll_timeout, ) receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: log.critical( 'updateNonClosingBalanceProof failed', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), nonce=nonce, balance_hash=encode_hex(balance_hash), additional_hash=encode_hex(additional_hash), partner_signature=encode_hex(partner_signature), signature=encode_hex(signature), ) channel_closed = self.channel_is_closed(partner) if channel_closed is False: raise ChannelIncorrectStateError('Channel is not in a closed state') raise TransactionThrew('Update NonClosing balance proof', receipt_or_none) log.info( 'updateNonClosingBalanceProof successful', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), nonce=nonce, balance_hash=encode_hex(balance_hash), additional_hash=encode_hex(additional_hash), partner_signature=encode_hex(partner_signature), signature=encode_hex(signature), )
def close( self, partner: typing.Address, nonce: typing.Nonce, balance_hash: typing.BalanceHash, additional_hash: typing.AdditionalHash, signature: typing.Signature, ): """ Close the channel using the provided balance proof. Raises: ChannelBusyError: If the channel is busy with another operation. """ log.info( 'close called', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), nonce=nonce, balance_hash=encode_hex(balance_hash), additional_hash=encode_hex(additional_hash), signature=encode_hex(signature), ) self._check_channel_lock(partner) with releasing(self.channel_operations_lock[partner]): transaction_hash = self.proxy.transact( 'closeChannel', partner, balance_hash, nonce, additional_hash, signature, ) self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout) receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: log.critical( 'close failed', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), nonce=nonce, balance_hash=encode_hex(balance_hash), additional_hash=encode_hex(additional_hash), signature=encode_hex(signature), ) channel_opened = self.channel_is_opened(partner) if channel_opened is False: raise ChannelIncorrectStateError( 'Channel is not in an opened state. It cannot be closed.', ) raise TransactionThrew('Close', receipt_or_none) log.info( 'close successful', token_network=pex(self.address), node=pex(self.node_address), partner=pex(partner), nonce=nonce, balance_hash=encode_hex(balance_hash), additional_hash=encode_hex(additional_hash), signature=encode_hex(signature), )
def close(self, nonce, transferred_amount, locksroot, extra_hash, signature): """ Close the channel using the provided balance proof. Raises: AddressWithoutCode: If the channel was settled prior to the call. ChannelBusyError: If the channel is busy with another operation. """ log.info( 'close called', node=pex(self.node_address), contract=pex(self.address), nonce=nonce, transferred_amount=transferred_amount, locksroot=encode_hex(locksroot), extra_hash=encode_hex(extra_hash), signature=encode_hex(signature), ) if not self.channel_operations_lock.acquire(blocking=False): raise ChannelBusyError( f'Channel with address {self.address} is ' f'busy with another ongoing operation.' ) with releasing(self.channel_operations_lock): transaction_hash = estimate_and_transact( self.proxy, 'close', nonce, transferred_amount, locksroot, extra_hash, signature, ) self.client.poll(unhexlify(transaction_hash), timeout=self.poll_timeout) receipt_or_none = check_transaction_threw(self.client, transaction_hash) if receipt_or_none: log.critical( 'close failed', node=pex(self.node_address), contract=pex(self.address), nonce=nonce, transferred_amount=transferred_amount, locksroot=encode_hex(locksroot), extra_hash=encode_hex(extra_hash), signature=encode_hex(signature), ) self._check_exists() raise TransactionThrew('Close', receipt_or_none) log.info( 'close successful', node=pex(self.node_address), contract=pex(self.address), nonce=nonce, transferred_amount=transferred_amount, locksroot=encode_hex(locksroot), extra_hash=encode_hex(extra_hash), signature=encode_hex(signature), )
def tester_deploy_contract(tester_chain, private_key, contract_name, contract_path, constructor_parameters=None): all_contracts = _solidity.compile_file(contract_path, libraries=dict()) contract_key = solidity_get_contract_key(all_contracts, contract_path, contract_name) contract = all_contracts[contract_key] contract_interface = contract['abi'] log.info('Deploying "{}" contract'.format(os.path.basename(contract_path))) dependencies = deploy_dependencies_symbols(all_contracts) deployment_order = dependencies_order_of_build(contract_key, dependencies) log.info('Deploying dependencies: {}'.format(str(deployment_order))) deployment_order.pop() # remove `contract_name` from the list libraries = dict() for deploy_contract in deployment_order: dependency_contract = all_contracts[deploy_contract] hex_bytecode = _solidity.solidity_resolve_symbols( dependency_contract['bin_hex'], libraries, ) bytecode = unhexlify(hex_bytecode) dependency_contract['bin_hex'] = hex_bytecode dependency_contract['bin'] = bytecode log.info('Creating contract {}'.format(deploy_contract)) contract_address = tester_chain.contract(bytecode, language='evm', sender=private_key) tester_chain.mine(number_of_blocks=1) if len(tester_chain.head_state.get_code(contract_address)) == 0: raise Exception('Contract code empty') libraries[deploy_contract] = encode_hex(contract_address) hex_bytecode = _solidity.solidity_resolve_symbols(contract['bin_hex'], libraries) bytecode = unhexlify(hex_bytecode) contract['bin_hex'] = hex_bytecode contract['bin'] = bytecode if constructor_parameters: translator = ContractTranslator(contract_interface) parameters = translator.encode_constructor_arguments( constructor_parameters) bytecode = contract['bin'] + parameters else: bytecode = contract['bin'] log.info('Creating contract {}'.format(contract_name)) contract_address = tester_chain.contract(bytecode, language='evm', sender=private_key) tester_chain.mine(number_of_blocks=1) if len(tester_chain.head_state.get_code(contract_address)) == 0: raise Exception('Contract code empty') return contract_address
def geth_create_blockchain(deploy_key, deploy_client, private_keys, blockchain_private_keys, rpc_ports, p2p_ports, base_datadir, verbosity, random_marker, genesis_path=None, logdirectory=None): # pylint: disable=too-many-locals,too-many-statements,too-many-arguments,too-many-branches nodes_configuration = [] key_p2p_rpc = zip(blockchain_private_keys, p2p_ports, rpc_ports) for pos, (key, p2p_port, rpc_port) in enumerate(key_p2p_rpc): config = dict() address = privatekey_to_address(key) # make the first node miner if pos == 0: config['unlock'] = 0 config['nodekey'] = key config['nodekeyhex'] = encode_hex(key) config['pub'] = encode_hex(privtopub(key)) config['address'] = address config['port'] = p2p_port config['rpcport'] = rpc_port config['enode'] = 'enode://{pub}@127.0.0.1:{port}'.format( pub=config['pub'], port=config['port'], ) nodes_configuration.append(config) for config in nodes_configuration: config['bootnodes'] = ','.join(node['enode'] for node in nodes_configuration) all_keys = set(private_keys) all_keys.add(deploy_key) all_keys = sorted(all_keys) cmds = [] for i, config in enumerate(nodes_configuration): # HACK: Use only the first 8 characters to avoid golang's issue # https://github.com/golang/go/issues/6895 (IPC bind fails with path # longer than 108 characters). # BSD (and therefore macOS) socket path length limit is 104 chars nodekey_part = config['nodekeyhex'][:8] nodedir = os.path.join(base_datadir, nodekey_part) node_genesis_path = os.path.join(nodedir, 'custom_genesis.json') assert len(nodedir + '/geth.ipc') <= 104, 'geth data path is too large' os.makedirs(nodedir) if genesis_path is None: geth_bare_genesis(node_genesis_path, all_keys, random_marker) else: shutil.copy(genesis_path, node_genesis_path) geth_init_datadir(nodedir, node_genesis_path) if 'unlock' in config: geth_create_account(nodedir, all_keys[i]) commandline = geth_to_cmd(config, nodedir, verbosity) cmds.append(commandline) # save current term settings before running geth if isinstance( sys.stdin, io.IOBase): # check that the test is running on non-capture mode term_settings = termios.tcgetattr(sys.stdin) stdout = None stderr = None processes_list = [] for pos, cmd in enumerate(cmds): if logdirectory: log_path = os.path.join(logdirectory, str(pos)) logfile = open(log_path, 'w') stdout = logfile stderr = logfile if '--unlock' in cmd: cmd.append('--mine') process = subprocess.Popen( cmd, universal_newlines=True, stdin=subprocess.PIPE, stdout=stdout, stderr=stderr, ) # --password wont work, write password to unlock process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Passphrase: process.stdin.write(DEFAULT_PASSPHRASE + os.linesep) # Repeat passphrase: else: process = subprocess.Popen( cmd, universal_newlines=True, stdout=stdout, stderr=stderr, ) processes_list.append(process) try: geth_wait_and_check(deploy_client, private_keys, random_marker) for process in processes_list: process.poll() if process.returncode is not None: raise ValueError('geth failed to start') except (ValueError, RuntimeError) as e: # If geth_wait_and_check or the above loop throw an exception make sure # we don't end up with a rogue geth process running in the background for proccess in processes_list: process.terminate() raise e finally: # reenter echo mode (disabled by geth pasphrase prompt) if isinstance(sys.stdin, io.IOBase): termios.tcsetattr(sys.stdin, termios.TCSADRAIN, term_settings) return processes_list
from raiden.utils import ( privtopub as privtopub_enode, privatekey_to_address, sha3, encode_hex, ) from raiden.settings import INITIAL_PORT # DEFAULTS NUM_GETH_NODES = 3 NUM_RAIDEN_ACCOUNTS = 10 CLUSTER_NAME = 'raiden' RAIDEN_PORT = INITIAL_PORT DEFAULT_PW = 'notsosecret' PRIVKEY_LOCALHOST_627 = encode_hex(sha3(b'localhost:627')) # default args to pass to `geth` for all calls, e.g. verbosity, ... DEFAULT_ARGS = [ '--nodiscover', '--rpc', '--networkid {}'.format(sum(ord(c) for c in CLUSTER_NAME)), ] # the node specific arguments to pass to `geth` that will be extracted from a # 'node configuration' NODE_CONFIG = [ 'nodekeyhex', 'port', 'rpcport', 'bootnodes',