def _run_smoketest(): print_step('Starting Raiden') config = deepcopy(App.DEFAULT_CONFIG) if args.get('extra_config', dict()): merge_dict(config, args['extra_config']) del args['extra_config'] args['config'] = config # invoke the raiden app app = run_app(**args) raiden_api = RaidenAPI(app.raiden) rest_api = RestAPI(raiden_api) api_server = APIServer(rest_api) (api_host, api_port) = split_endpoint(args['api_address']) api_server.start(api_host, api_port) raiden_api.channel_open( registry_address=contract_addresses[ CONTRACT_TOKEN_NETWORK_REGISTRY], token_address=to_canonical_address(token.contract.address), partner_address=to_canonical_address(TEST_PARTNER_ADDRESS), ) raiden_api.set_total_channel_deposit( contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], to_canonical_address(token.contract.address), to_canonical_address(TEST_PARTNER_ADDRESS), TEST_DEPOSIT_AMOUNT, ) token_addresses = [to_checksum_address(token.contract.address)] success = False try: print_step('Running smoketest') error = run_smoketests( app.raiden, args['transport'], token_addresses, contract_addresses[CONTRACT_ENDPOINT_REGISTRY], debug=debug, ) if error is not None: append_report('Smoketest assertion error', error) else: success = True finally: app.stop() node = ethereum[0] node.send_signal(2) err, out = node.communicate() append_report('Ethereum stdout', out) append_report('Ethereum stderr', err) if success: print_step(f'Smoketest successful') else: print_step(f'Smoketest had errors', error=True) return success
def run_app( address, keystore_path, gas_price, eth_rpc_endpoint, registry_contract_address, secret_registry_contract_address, discovery_contract_address, listen_address, mapped_socket, max_unresponsive_time, api_address, rpc, sync_check, console, password_file, web_ui, datadir, transport, matrix_server, network_id, extra_config=None, **kwargs, ): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument from raiden.app import App if transport == 'udp' and not mapped_socket: raise RuntimeError('Missing socket') address_hex = to_normalized_address(address) if address else None address_hex, privatekey_bin = prompt_account(address_hex, keystore_path, password_file) address = to_canonical_address(address_hex) (listen_host, listen_port) = split_endpoint(listen_address) (api_host, api_port) = split_endpoint(api_address) if datadir is None: datadir = os.path.join(os.path.expanduser('~'), '.raiden') config = deepcopy(App.DEFAULT_CONFIG) if extra_config: merge_dict(config, extra_config) config['transport']['udp']['host'] = listen_host config['transport']['udp']['port'] = listen_port config['console'] = console config['rpc'] = rpc config['web_ui'] = rpc and web_ui config['api_host'] = api_host config['api_port'] = api_port if mapped_socket: config['socket'] = mapped_socket.socket config['transport']['udp']['external_ip'] = mapped_socket.external_ip config['transport']['udp'][ 'external_port'] = mapped_socket.external_port config['transport_type'] = transport config['transport']['matrix']['server'] = matrix_server config['transport']['udp'][ 'nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES config['transport']['udp']['nat_keepalive_timeout'] = timeout privatekey_hex = hexlify(privatekey_bin) config['privatekey_hex'] = privatekey_hex parsed_eth_rpc_endpoint = urlparse(eth_rpc_endpoint) if not parsed_eth_rpc_endpoint.scheme: eth_rpc_endpoint = f'http://{eth_rpc_endpoint}' web3 = Web3(HTTPProvider(eth_rpc_endpoint)) try: node_version = web3.version.node # pylint: disable=no-member except ConnectTimeout: raise EthNodeCommunicationError( "Couldn't connect to the ethereum node") supported, _ = is_supported_client(node_version) if not supported: print( 'You need a Byzantium enabled ethereum node. Parity >= 1.7.6 or Geth >= 1.7.2' ) sys.exit(1) rpc_client = JSONRPCClient( web3, privatekey_bin, gasprice=gas_price, ) blockchain_service = BlockChainService(privatekey_bin, rpc_client) net_id = blockchain_service.network_id if net_id != network_id: if network_id in constants.ID_TO_NETWORKNAME and net_id in constants.ID_TO_NETWORKNAME: print(( "The chosen ethereum network '{}' differs from the ethereum client '{}'. " 'Please update your settings.').format( constants.ID_TO_NETWORKNAME[network_id], constants.ID_TO_NETWORKNAME[net_id])) else: print(( "The chosen ethereum network id '{}' differs from the ethereum client '{}'. " 'Please update your settings.').format(network_id, net_id)) sys.exit(1) config['chain_id'] = network_id if sync_check: check_synced(blockchain_service) database_path = os.path.join(datadir, 'netid_%s' % net_id, address_hex[:8], 'log.db') config['database_path'] = database_path print( '\nYou are connected to the \'{}\' network and the DB path is: {}'. format( constants.ID_TO_NETWORKNAME.get(net_id) or net_id, database_path, ), ) contract_addresses_given = (registry_contract_address is not None and secret_registry_contract_address is not None and discovery_contract_address is not None) contract_addresses_known = net_id in constants.ID_TO_NETWORK_CONFIG if not contract_addresses_given and not contract_addresses_known: print(( "There are known contract addresses for network id '{}'. Please provide " 'them in the command line or the configuration file.' ).format(net_id)) sys.exit(1) contract_addresses = constants.ID_TO_NETWORK_CONFIG.get(net_id, dict()) try: token_network_registry = blockchain_service.token_network_registry( registry_contract_address or contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], ) except ContractVersionMismatch: handle_contract_version_mismatch('token network registry', registry_contract_address) except AddressWithoutCode: handle_contract_no_code('token network registry', registry_contract_address) except AddressWrongContract: handle_contract_wrong_address('token network registry', registry_contract_address) try: secret_registry = blockchain_service.secret_registry( secret_registry_contract_address or contract_addresses[CONTRACT_SECRET_REGISTRY], ) except ContractVersionMismatch: handle_contract_version_mismatch('secret registry', secret_registry_contract_address) except AddressWithoutCode: handle_contract_no_code('secret registry', secret_registry_contract_address) except AddressWrongContract: handle_contract_wrong_address('secret registry', secret_registry_contract_address) discovery = None if transport == 'udp': check_discovery_registration_gas(blockchain_service, address) try: dicovery_proxy = blockchain_service.discovery( discovery_contract_address or contract_addresses[CONTRACT_ENDPOINT_REGISTRY], ) discovery = ContractDiscovery( blockchain_service.node_address, dicovery_proxy, ) except ContractVersionMismatch: handle_contract_version_mismatch('discovery', discovery_contract_address) except AddressWithoutCode: handle_contract_no_code('discovery', discovery_contract_address) except AddressWrongContract: handle_contract_wrong_address('discovery', discovery_contract_address) throttle_policy = TokenBucket( config['transport']['udp']['throttle_capacity'], config['transport']['udp']['throttle_fill_rate'], ) transport = UDPTransport( discovery, mapped_socket.socket, throttle_policy, config['transport']['udp'], ) elif transport == 'matrix': try: transport = MatrixTransport(config['transport']['matrix']) except RaidenError as ex: click.secho(f'FATAL: {ex}', fg='red') sys.exit(1) else: raise RuntimeError(f'Unknown transport type "{transport}" given') try: chain_config = constants.ID_TO_NETWORK_CONFIG.get(net_id, {}) start_block = chain_config.get(constants.START_QUERY_BLOCK_KEY, 0) raiden_app = App( config=config, chain=blockchain_service, query_start_block=start_block, default_registry=token_network_registry, default_secret_registry=secret_registry, transport=transport, discovery=discovery, ) except RaidenError as e: click.secho(f'FATAL: {e}', fg='red') sys.exit(1) try: raiden_app.start() except filelock.Timeout: name_or_id = constants.ID_TO_NETWORKNAME.get(network_id, network_id) print( f'FATAL: Another Raiden instance already running for account {address_hex} on ' f'network id {name_or_id}', ) sys.exit(1) return raiden_app
def _start_services(self): from raiden.ui.console import Console from raiden.api.python import RaidenAPI config = deepcopy(App.DEFAULT_CONFIG) if self._options.get('extra_config', dict()): merge_dict(config, self._options['extra_config']) del self._options['extra_config'] self._options['config'] = config if self._options['showconfig']: print('Configuration Dump:') dump_config(config) dump_cmd_options(self._options) dump_module('settings', settings) dump_module('constants', constants) # this catches exceptions raised when waiting for the stalecheck to complete try: app_ = run_app(**self._options) except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except EthNodeInterfaceError as e: click.secho(str(e), fg='red') sys.exit(1) tasks = [app_.raiden] # RaidenService takes care of Transport and AlarmTask domain_list = [] if self._options['rpccorsdomain']: if ',' in self._options['rpccorsdomain']: for domain in self._options['rpccorsdomain'].split(','): domain_list.append(str(domain)) else: domain_list.append(str(self._options['rpccorsdomain'])) self._raiden_api = RaidenAPI(app_.raiden) if self._options['rpc']: rest_api = RestAPI(self._raiden_api) api_server = APIServer( rest_api, cors_domain_list=domain_list, web_ui=self._options['web_ui'], eth_rpc_endpoint=self._options['eth_rpc_endpoint'], ) (api_host, api_port) = split_endpoint(self._options['api_address']) try: api_server.start(api_host, api_port) except APIServerPortInUseError: click.secho( f'ERROR: API Address {api_host}:{api_port} is in use. ' f'Use --api-address <host:port> to specify a different port.', fg='red', ) sys.exit(1) print( 'The Raiden API RPC server is now running at http://{}:{}/.\n\n' 'See the Raiden documentation for all available endpoints at\n' 'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.format( api_host, api_port, ), ) tasks.append(api_server) if self._options['console']: console = Console(app_) console.start() tasks.append(console) # spawn a greenlet to handle the version checking version = get_system_spec()['raiden'] if version is not None: tasks.append(gevent.spawn(check_version, version)) # spawn a greenlet to handle the gas reserve check tasks.append(gevent.spawn(check_gas_reserve, app_.raiden)) self._startup_hook() # wait for interrupt event = AsyncResult() def sig_set(sig=None, _frame=None): event.set(sig) gevent.signal(signal.SIGQUIT, sig_set) gevent.signal(signal.SIGTERM, sig_set) gevent.signal(signal.SIGINT, sig_set) # quit if any task exits, successfully or not for task in tasks: task.link(event) try: event.get() print('Signal received. Shutting down ...') except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RaidenError as ex: click.secho(f'FATAL: {ex}', fg='red') except Exception as ex: with NamedTemporaryFile( 'w', prefix=f'raiden-exception-{datetime.utcnow():%Y-%m-%dT%H-%M}', suffix='.txt', delete=False, ) as traceback_file: traceback.print_exc(file=traceback_file) click.secho( f'FATAL: An unexpected exception occured. ' f'A traceback has been written to {traceback_file.name}\n' f'{ex}', fg='red', ) finally: self._shutdown_hook() def stop_task(task): try: if isinstance(task, Runnable): task.stop() else: task.kill() finally: task.get() # re-raise gevent.joinall( [gevent.spawn(stop_task, task) for task in tasks], app_.config.get('shutdown_timeout', settings.DEFAULT_SHUTDOWN_TIMEOUT), raise_error=True, ) return app_
def create_apps( chain_id: ChainID, contracts_path: str, blockchain_services: BlockchainServices, token_network_registry_address: TokenNetworkRegistryAddress, one_to_n_address: Optional[Address], secret_registry_address: SecretRegistryAddress, service_registry_address: Optional[Address], user_deposit_address: Address, monitoring_service_contract_address: Address, reveal_timeout: BlockTimeout, settle_timeout: BlockTimeout, database_basedir: str, retry_interval: float, retries_before_backoff: int, environment_type: Environment, unrecoverable_error_should_crash: bool, local_matrix_url: Optional[ParsedURL], broadcast_rooms: List[str], routing_mode: RoutingMode, blockchain_query_interval: float, resolver_ports: List[Optional[int]], ) -> List[App]: """ Create the apps.""" # pylint: disable=too-many-locals services = blockchain_services apps = [] for idx, proxy_manager in enumerate(services): database_path = database_from_privatekey(base_dir=database_basedir, app_number=idx) assert len(resolver_ports) > idx resolver_port = resolver_ports[idx] config = { "chain_id": chain_id, "environment_type": environment_type, "unrecoverable_error_should_crash": unrecoverable_error_should_crash, "reveal_timeout": reveal_timeout, "settle_timeout": settle_timeout, "contracts_path": contracts_path, "database_path": database_path, "blockchain": { "confirmation_blocks": DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS, "query_interval": blockchain_query_interval, }, "transport": {}, "rpc": True, "console": False, "mediation_fees": MediationFeeConfig(), } if local_matrix_url is not None: merge_dict( config, { "transport_type": "matrix", "transport": { "matrix": { "broadcast_rooms": broadcast_rooms, "retries_before_backoff": retries_before_backoff, "retry_interval": retry_interval, "server": local_matrix_url, "server_name": local_matrix_url.netloc, "available_servers": [], } }, }, ) if resolver_port is not None: merge_dict(config, { "resolver_endpoint": "http://localhost:" + str(resolver_port) }) config_copy = deepcopy(App.DEFAULT_CONFIG) config_copy.update(config) registry = proxy_manager.token_network_registry( token_network_registry_address) secret_registry = proxy_manager.secret_registry( secret_registry_address) service_registry = None if service_registry_address: service_registry = proxy_manager.service_registry( service_registry_address) user_deposit = None if user_deposit_address: user_deposit = proxy_manager.user_deposit(user_deposit_address) transport = MatrixTransport(config["transport"]["matrix"]) raiden_event_handler = RaidenEventHandler() hold_handler = HoldRaidenEventHandler(raiden_event_handler) message_handler = WaitForMessage() app = App( config=config_copy, rpc_client=proxy_manager.client, proxy_manager=proxy_manager, query_start_block=BlockNumber(0), default_registry=registry, default_one_to_n_address=one_to_n_address, default_secret_registry=secret_registry, default_service_registry=service_registry, default_msc_address=monitoring_service_contract_address, transport=transport, raiden_event_handler=hold_handler, message_handler=message_handler, user_deposit=user_deposit, routing_mode=routing_mode, ) apps.append(app) return apps
def run_smoketest( print_step: Callable, append_report: Callable, args: Dict[str, Any], contract_addresses: List[Address], token: ContractProxy, debug: bool, ethereum_nodes: List[HTTPExecutor], ): print_step('Starting Raiden') config = deepcopy(App.DEFAULT_CONFIG) extra_config = args.pop('extra_config', None) if extra_config: merge_dict(config, extra_config) args['config'] = config # Should use basic routing in the smoke test for now # TODO: If we ever utilize a PFS in the smoke test we # need to use the deployed service registry, register the # PFS service there and then change this argument. args['routing_mode'] = RoutingMode.BASIC raiden_stdout = StringIO() maybe_redirect_stdout = contextlib.redirect_stdout(raiden_stdout) if debug: maybe_redirect_stdout = contextlib.nullcontext() with maybe_redirect_stdout: success = False app = None try: app = run_app(**args) raiden_api = RaidenAPI(app.raiden) rest_api = RestAPI(raiden_api) (api_host, api_port) = split_endpoint(args['api_address']) api_server = APIServer(rest_api, config={ 'host': api_host, 'port': api_port }) api_server.start() block = app.raiden.get_block_number( ) + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS # Proxies now use the confirmed block hash to query the chain for # prerequisite checks. Wait a bit here to make sure that the confirmed # block hash contains the deployed token network or else things break wait_for_block( raiden=app.raiden, block_number=block, retry_timeout=1.0, ) raiden_api.channel_open( registry_address=contract_addresses[ CONTRACT_TOKEN_NETWORK_REGISTRY], token_address=to_canonical_address(token.contract.address), partner_address=to_canonical_address(TEST_PARTNER_ADDRESS), ) raiden_api.set_total_channel_deposit( contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], to_canonical_address(token.contract.address), to_canonical_address(TEST_PARTNER_ADDRESS), TEST_DEPOSIT_AMOUNT, ) token_addresses = [to_checksum_address(token.contract.address)] print_step('Running smoketest') error = smoketest_perform_tests( app.raiden, args['transport'], token_addresses, contract_addresses[CONTRACT_ENDPOINT_REGISTRY], ) if error is not None: append_report('Smoketest assertion error', error) else: success = True except: # noqa pylint: disable=bare-except if debug: import pdb # The pylint comment is required when pdbpp is installed pdb.post_mortem() # pylint: disable=no-member else: error = traceback.format_exc() append_report('Smoketest execution error', error) finally: if app is not None: app.stop() app.raiden.get() node_executor = ethereum_nodes[0] node = node_executor.process node.send_signal(signal.SIGINT) try: node.wait(10) except TimeoutExpired: print_step('Ethereum node shutdown unclean, check log!', error=True) node.kill() if isinstance(node_executor.stdio, tuple): logfile = node_executor.stdio[1] logfile.flush() logfile.seek(0) append_report('Ethereum Node log output', logfile.read()) append_report('Raiden Node stdout', raiden_stdout.getvalue()) if success: print_step(f'Smoketest successful') else: print_step(f'Smoketest had errors', error=True) return success
def _start_services(self): from raiden.api.python import RaidenAPI config = deepcopy(App.DEFAULT_CONFIG) if self._options.get("extra_config", dict()): merge_dict(config, self._options["extra_config"]) del self._options["extra_config"] self._options["config"] = config if self._options["showconfig"]: print("Configuration Dump:") dump_config(config) dump_cmd_options(self._options) dump_module("settings", settings) dump_module("constants", constants) # this catches exceptions raised when waiting for the stalecheck to complete try: app_ = run_app(**self._options) except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RuntimeError as e: click.secho(str(e), fg="red") sys.exit(1) except EthNodeInterfaceError as e: click.secho(str(e), fg="red") sys.exit(1) tasks = [app_.raiden ] # RaidenService takes care of Transport and AlarmTask domain_list = ['http://localhost:*/*'] self._raiden_api = RaidenAPI(app_.raiden) if self._options['discoverable']: node_address = to_checksum_address(self._raiden_api.address) rns_domain = None if self._options['rnsdomain']: rns_domain = self._options['rnsdomain'] try: rns_resolved_address = self._raiden_api.raiden.chain.get_address_from_rns( self._options['rnsdomain']) if rns_resolved_address == RNS_ADDRESS_ZERO: click.secho( 'Cannot register into the Lumino Explorer. Your RNS domain is not registered' ) sys.exit(1) elif rns_resolved_address != node_address: click.secho( 'Cannot register into the Lumino Explorer. ' 'Your RNS domain does not match with the node RSK address. ' 'The RNS domain is owned by ' + rns_resolved_address) sys.exit(1) except BadFunctionCallOutput: click.secho( "Unable to interact with RNS Public Resolver. Your node will be registered without RNS domain." ) register(self._options["explorer_endpoint"], node_address, rns_domain) else: if self._options['rnsdomain']: try: self._raiden_api.raiden.chain.get_address_from_rns( self._options['rnsdomain']) except BadFunctionCallOutput: click.secho( "Unable to interact with RNS Public Resolver. " "Please check youre interacting with the correct contract." ) sys.exit(1) if self._options["rpc"]: rest_api = RestAPI(self._raiden_api) (api_host, api_port) = split_endpoint(self._options["api_address"]) api_server = APIServer( rest_api, config={ 'host': api_host, 'port': api_port, 'rnsdomain': self._options['rnsdomain'], 'rskendpoint': self._options['eth_rpc_endpoint'], 'explorerendpoint': self._options["explorer_endpoint"], 'discoverable': self._options['discoverable'] }, cors_domain_list=domain_list, web_ui=self._options["web_ui"], eth_rpc_endpoint=self._options["eth_rpc_endpoint"], hub_mode=self._options["hub_mode"], ) try: api_server.start() except APIServerPortInUseError: click.secho( f"ERROR: API Address {api_host}:{api_port} is in use. " f"Use --api-address <host:port> to specify a different port.", fg="red", ) sys.exit(1) print( 'The Lumino API RPC server is now running at http://{}:{}/.\n\n' .format( api_host, api_port, ), ) tasks.append(api_server) if self._options["console"]: from raiden.ui.console import Console console = Console(app_) console.start() tasks.append(console) config_path = os.path.join(ROOT_DIR, 'config.json') with open(config_path) as json_data_file: config_data = json.load(json_data_file) project_data = config_data['project'] project_version = project_data['version'] # spawn a greenlet to handle the version checking tasks.append(gevent.spawn(check_version, project_version)) # spawn a greenlet to handle the gas reserve check tasks.append(gevent.spawn(check_gas_reserve, app_.raiden)) # spawn a greenlet to handle the periodic check for the network id tasks.append( gevent.spawn(check_network_id, app_.raiden.chain.network_id, app_.raiden.chain.client.web3)) spawn_user_deposit_task = app_.user_deposit and ( self._options["pathfinding_service_address"] or self._options["enable_monitoring"]) if spawn_user_deposit_task: # spawn a greenlet to handle RDN deposits check tasks.append( gevent.spawn(check_rdn_deposits, app_.raiden, app_.user_deposit)) # spawn a greenlet to handle the functions self._startup_hook() # wait for interrupt event = AsyncResult() def sig_set(sig=None, _frame=None): event.set(sig) gevent.signal(signal.SIGQUIT, sig_set) gevent.signal(signal.SIGTERM, sig_set) gevent.signal(signal.SIGINT, sig_set) # quit if any task exits, successfully or not for task in tasks: task.link(event) try: event.get() print("Signal received. Shutting down ...") except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RaidenError as ex: click.secho(f"FATAL: {ex}", fg="red") except Exception as ex: file = NamedTemporaryFile( "w", prefix=f"raiden-exception-{datetime.utcnow():%Y-%m-%dT%H-%M}", suffix=".txt", delete=False, ) with file as traceback_file: traceback.print_exc(file=traceback_file) click.secho( f"FATAL: An unexpected exception occured. " f"A traceback has been written to {traceback_file.name}\n" f"{ex}", fg="red", ) finally: self._shutdown_hook() def stop_task(task): try: if isinstance(task, Runnable): task.stop() else: task.kill() finally: task.get() # re-raise gevent.joinall( [gevent.spawn(stop_task, task) for task in tasks], app_.config.get("shutdown_timeout", settings.DEFAULT_SHUTDOWN_TIMEOUT), raise_error=True, ) return app_
def create_apps( chain_id, blockchain_services, endpoint_discovery_services, token_network_registry_address, secret_registry_address, raiden_udp_ports, reveal_timeout, settle_timeout, database_paths, retry_interval, retries_before_backoff, throttle_capacity, throttle_fill_rate, nat_invitation_timeout, nat_keepalive_retries, nat_keepalive_timeout, local_matrix_url=None, ): """ Create the apps.""" # pylint: disable=too-many-locals services = zip(blockchain_services, endpoint_discovery_services) apps = [] for idx, (blockchain, discovery) in enumerate(services): port = raiden_udp_ports[idx] private_key = blockchain.private_key host = '127.0.0.1' config = { 'chain_id': chain_id, 'privatekey_hex': hexlify(private_key), 'reveal_timeout': reveal_timeout, 'settle_timeout': settle_timeout, 'database_path': database_paths[idx], 'transport': { 'udp': { 'external_ip': host, 'external_port': port, 'host': host, 'nat_invitation_timeout': nat_invitation_timeout, 'nat_keepalive_retries': nat_keepalive_retries, 'nat_keepalive_timeout': nat_keepalive_timeout, 'port': port, 'retries_before_backoff': retries_before_backoff, 'retry_interval': retry_interval, 'throttle_capacity': throttle_capacity, 'throttle_fill_rate': throttle_fill_rate, }, }, 'rpc': True, 'console': False, } use_matrix = local_matrix_url is not None if use_matrix: merge_dict( config, { 'transport_type': 'matrix', 'transport': { 'matrix': { 'discovery_room': { 'alias_fragment': 'discovery', 'server': 'matrix.local.raiden', }, 'retries_before_backoff': retries_before_backoff, 'retry_interval': retry_interval, 'server': local_matrix_url, 'server_name': 'matrix.local.raiden', }, }, }, ) if 'TRAVIS' in environ: config['transport']['matrix']['login_retry_wait'] = 1.5 config_copy = App.DEFAULT_CONFIG.copy() config_copy.update(config) registry = blockchain.token_network_registry( token_network_registry_address) secret_registry = blockchain.secret_registry(secret_registry_address) if use_matrix: transport = MatrixTransport(config['transport']['matrix']) else: throttle_policy = TokenBucket( config['transport']['udp']['throttle_capacity'], config['transport']['udp']['throttle_fill_rate'], ) transport = UDPTransport( discovery, server._udp_socket((host, port)), # pylint: disable=protected-access throttle_policy, config['transport']['udp'], ) app = App( config=config_copy, chain=blockchain, query_start_block=0, default_registry=registry, default_secret_registry=secret_registry, transport=transport, discovery=discovery, ) apps.append(app) return apps
def app( address, keystore_path, gas_price, eth_rpc_endpoint, registry_contract_address, secret_registry_contract_address, discovery_contract_address, listen_address, rpccorsdomain, mapped_socket, log_config, log_file, log_json, max_unresponsive_time, send_ping_time, api_address, rpc, sync_check, console, password_file, web_ui, datadir, nat, transport, matrix_server, network_id, extra_config=None, ): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument from raiden.app import App from raiden.network.blockchain_service import BlockChainService if transport == 'udp' and not mapped_socket: raise RuntimeError('Missing socket') address_hex = to_normalized_address(address) if address else None address_hex, privatekey_bin = prompt_account(address_hex, keystore_path, password_file) address = to_canonical_address(address_hex) (listen_host, listen_port) = split_endpoint(listen_address) (api_host, api_port) = split_endpoint(api_address) if datadir is None: datadir = os.path.join(os.path.expanduser('~'), '.raiden') config = deepcopy(App.DEFAULT_CONFIG) if extra_config: merge_dict(config, extra_config) config['host'] = listen_host config['port'] = listen_port config['console'] = console config['rpc'] = rpc config['web_ui'] = rpc and web_ui config['api_host'] = api_host config['api_port'] = api_port if mapped_socket: config['socket'] = mapped_socket.socket config['external_ip'] = mapped_socket.external_ip config['external_port'] = mapped_socket.external_port config['transport_type'] = transport config['matrix']['server'] = matrix_server config['transport'][ 'nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES config['transport']['nat_keepalive_timeout'] = timeout privatekey_hex = hexlify(privatekey_bin) config['privatekey_hex'] = privatekey_hex endpoint = eth_rpc_endpoint # Fallback to default port if only an IP address is given rpc_port = 8545 if eth_rpc_endpoint.startswith('http://'): endpoint = eth_rpc_endpoint[len('http://'):] rpc_port = 80 elif eth_rpc_endpoint.startswith('https://'): endpoint = eth_rpc_endpoint[len('https://'):] rpc_port = 443 if ':' not in endpoint: # no port was given in url rpc_host = endpoint else: rpc_host, rpc_port = split_endpoint(endpoint) rpc_client = JSONRPCClient( rpc_host, rpc_port, privatekey_bin, gas_price, ) blockchain_service = BlockChainService( privatekey_bin, rpc_client, gas_price, ) # this assumes the eth node is already online check_json_rpc(rpc_client) net_id = blockchain_service.network_id if net_id != network_id: if network_id in ID_TO_NETWORKNAME and net_id in ID_TO_NETWORKNAME: print(( "The chosen ethereum network '{}' differs from the ethereum client '{}'. " 'Please update your settings.').format( ID_TO_NETWORKNAME[network_id], ID_TO_NETWORKNAME[net_id])) else: print(( "The chosen ethereum network id '{}' differs from the ethereum client '{}'. " 'Please update your settings.').format(network_id, net_id)) sys.exit(1) if sync_check: check_synced(blockchain_service) database_path = os.path.join(datadir, 'netid_%s' % net_id, address_hex[:8], 'log.db') config['database_path'] = database_path print( 'You are connected to the \'{}\' network and the DB path is: {}'. format( ID_TO_NETWORKNAME.get(net_id) or net_id, database_path, ), ) try: registry = blockchain_service.registry(registry_contract_address, ) except ContractVersionMismatch: print( 'Deployed registry contract version mismatch. ' 'Please update your Raiden installation.', ) sys.exit(1) try: secret_registry = blockchain_service.secret_registry( secret_registry_contract_address, ) except ContractVersionMismatch: print( 'Deployed registry contract version mismatch. ' 'Please update your Raiden installation.', ) sys.exit(1) discovery = None if transport == 'udp': check_discovery_registration_gas(blockchain_service, address) try: discovery = ContractDiscovery( blockchain_service.node_address, blockchain_service.discovery(discovery_contract_address), ) except ContractVersionMismatch: print('Deployed discovery contract version mismatch. ' 'Please update your Raiden installation.') sys.exit(1) throttle_policy = TokenBucket( config['transport']['throttle_capacity'], config['transport']['throttle_fill_rate'], ) transport = UDPTransport( discovery, mapped_socket.socket, throttle_policy, config['transport'], ) elif transport == 'matrix': transport = MatrixTransport(config['matrix']) else: raise RuntimeError(f'Unknown transport type "{transport}" given') raiden_app = App( config, blockchain_service, registry, secret_registry, transport, discovery, ) return raiden_app
def run_app( address, keystore_path, gas_price, eth_rpc_endpoint, registry_contract_address, secret_registry_contract_address, discovery_contract_address, listen_address, mapped_socket, max_unresponsive_time, api_address, rpc, sync_check, console, password_file, web_ui, datadir, transport, matrix_server, network_id, lnd_address, extra_config=None, **kwargs, ): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument from raiden.app import App if transport == 'udp' and not mapped_socket: raise RuntimeError('Missing socket') address_hex = to_normalized_address(address) if address else None address_hex, privatekey_bin = prompt_account(address_hex, keystore_path, password_file) address = to_canonical_address(address_hex) (listen_host, listen_port) = split_endpoint(listen_address) (api_host, api_port) = split_endpoint(api_address) if datadir is None: datadir = os.path.join(os.path.expanduser('~'), '.raiden') config = deepcopy(App.DEFAULT_CONFIG) if extra_config: merge_dict(config, extra_config) config['host'] = listen_host config['port'] = listen_port config['console'] = console config['rpc'] = rpc config['web_ui'] = rpc and web_ui config['api_host'] = api_host config['api_port'] = api_port if mapped_socket: config['socket'] = mapped_socket.socket config['external_ip'] = mapped_socket.external_ip config['external_port'] = mapped_socket.external_port config['transport_type'] = transport config['matrix']['server'] = matrix_server config['transport']['nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES config['transport']['nat_keepalive_timeout'] = timeout privatekey_hex = hexlify(privatekey_bin) config['privatekey_hex'] = privatekey_hex rpc_host, rpc_port = eth_endpoint_to_hostport(eth_rpc_endpoint) rpc_client = JSONRPCClient( rpc_host, rpc_port, privatekey_bin, gas_price, ) blockchain_service = BlockChainService(privatekey_bin, rpc_client) net_id = blockchain_service.network_id if net_id != network_id: if network_id in constants.ID_TO_NETWORKNAME and net_id in constants.ID_TO_NETWORKNAME: print(( "The chosen ethereum network '{}' differs from the ethereum client '{}'. " 'Please update your settings.' ).format(constants.ID_TO_NETWORKNAME[network_id], constants.ID_TO_NETWORKNAME[net_id])) else: print(( "The chosen ethereum network id '{}' differs from the ethereum client '{}'. " 'Please update your settings.' ).format(network_id, net_id)) sys.exit(1) config['chain_id'] = network_id if sync_check: check_synced(blockchain_service) database_path = os.path.join(datadir, 'netid_%s' % net_id, address_hex[:8], 'log.db') config['database_path'] = database_path print( '\nYou are connected to the \'{}\' network and the DB path is: {}'.format( constants.ID_TO_NETWORKNAME.get(net_id) or net_id, database_path, ), ) contract_addresses_given = ( registry_contract_address is not None and secret_registry_contract_address is not None and discovery_contract_address is not None ) contract_addresses_known = net_id in constants.ID_TO_NETWORK_CONFIG if not contract_addresses_given and not contract_addresses_known: print(( "There are known contract addresses for network id '{}'. Please provide " 'them in the command line or the configuration file.' ).format(net_id)) sys.exit(1) contract_addresses = constants.ID_TO_NETWORK_CONFIG.get(net_id, dict()) try: token_network_registry = blockchain_service.token_network_registry( registry_contract_address or contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], ) except ContractVersionMismatch: print( 'Deployed registry contract version mismatch. ' 'Please update your Raiden installation.', ) sys.exit(1) try: secret_registry = blockchain_service.secret_registry( secret_registry_contract_address or contract_addresses[CONTRACT_SECRET_REGISTRY], ) except ContractVersionMismatch: print( 'Deployed secret registry contract version mismatch. ' 'Please update your Raiden installation.', ) sys.exit(1) discovery = None if transport == 'udp': check_discovery_registration_gas(blockchain_service, address) try: dicovery_proxy = blockchain_service.discovery( discovery_contract_address or contract_addresses[CONTRACT_ENDPOINT_REGISTRY], ) discovery = ContractDiscovery( blockchain_service.node_address, dicovery_proxy, ) except ContractVersionMismatch: print('Deployed discovery contract version mismatch. ' 'Please update your Raiden installation.') sys.exit(1) throttle_policy = TokenBucket( config['transport']['throttle_capacity'], config['transport']['throttle_fill_rate'], ) transport = UDPTransport( discovery, mapped_socket.socket, throttle_policy, config['transport'], ) elif transport == 'matrix': # matrix gets spammed with the default retry-interval of 1s, wait a little more if config['transport']['retry_interval'] == DEFAULT_TRANSPORT_RETRY_INTERVAL: config['transport']['retry_interval'] *= 5 try: transport = MatrixTransport(config['matrix']) except RaidenError as ex: click.secho(f'FATAL: {ex}', fg='red') sys.exit(1) else: raise RuntimeError(f'Unknown transport type "{transport}" given') try: chain_config = constants.ID_TO_NETWORK_CONFIG.get(net_id, {}) start_block = chain_config.get(constants.START_QUERY_BLOCK_KEY, 0) #vincent config['lnd_address'] = lnd_address raiden_app = App( config=config, chain=blockchain_service, query_start_block=start_block, default_registry=token_network_registry, default_secret_registry=secret_registry, transport=transport, discovery=discovery, ) except RaidenError as e: click.secho(f'FATAL: {e}', fg='red') sys.exit(1) return raiden_app
def create_apps( chain_id, contracts_path, blockchain_services, endpoint_discovery_services, token_network_registry_address, one_to_n_address: Optional[Address], secret_registry_address, service_registry_address, user_deposit_address, raiden_udp_ports, reveal_timeout, settle_timeout, database_basedir, retry_interval, retries_before_backoff, throttle_capacity, throttle_fill_rate, nat_invitation_timeout, nat_keepalive_retries, nat_keepalive_timeout, environment_type, unrecoverable_error_should_crash, local_matrix_url=None, private_rooms=None, global_rooms=None, ): """ Create the apps.""" # pylint: disable=too-many-locals services = zip(blockchain_services, endpoint_discovery_services, raiden_udp_ports) apps = [] for idx, (blockchain, discovery, port) in enumerate(services): address = blockchain.client.address host = "127.0.0.1" database_path = database_from_privatekey(base_dir=database_basedir, app_number=idx) config = { "chain_id": chain_id, "environment_type": environment_type, "unrecoverable_error_should_crash": unrecoverable_error_should_crash, "reveal_timeout": reveal_timeout, "settle_timeout": settle_timeout, "contracts_path": contracts_path, "database_path": database_path, "blockchain": {"confirmation_blocks": DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS}, "transport": { "udp": { "external_ip": host, "external_port": port, "host": host, "nat_invitation_timeout": nat_invitation_timeout, "nat_keepalive_retries": nat_keepalive_retries, "nat_keepalive_timeout": nat_keepalive_timeout, "port": port, "retries_before_backoff": retries_before_backoff, "retry_interval": retry_interval, "throttle_capacity": throttle_capacity, "throttle_fill_rate": throttle_fill_rate, } }, "rpc": True, "console": False, } use_matrix = local_matrix_url is not None if use_matrix: merge_dict( config, { "transport_type": "matrix", "transport": { "matrix": { "global_rooms": global_rooms, "retries_before_backoff": retries_before_backoff, "retry_interval": retry_interval, "server": local_matrix_url, "server_name": local_matrix_url.netloc, "available_servers": [], "private_rooms": private_rooms, } }, }, ) config_copy = deepcopy(App.DEFAULT_CONFIG) config_copy.update(config) registry = blockchain.token_network_registry(token_network_registry_address) secret_registry = blockchain.secret_registry(secret_registry_address) service_registry = None if service_registry_address: service_registry = blockchain.service_registry(service_registry_address) user_deposit = None if user_deposit_address: user_deposit = blockchain.user_deposit(user_deposit_address) if use_matrix: transport = MatrixTransport(config["transport"]["matrix"]) else: throttle_policy = TokenBucket( config["transport"]["udp"]["throttle_capacity"], config["transport"]["udp"]["throttle_fill_rate"], ) transport = UDPTransport( address, discovery, server._udp_socket((host, port)), # pylint: disable=protected-access throttle_policy, config["transport"]["udp"], ) raiden_event_handler = RaidenEventHandler() hold_handler = HoldRaidenEventHandler(raiden_event_handler) message_handler = WaitForMessage() app = App( config=config_copy, chain=blockchain, query_start_block=BlockNumber(0), default_registry=registry, default_one_to_n_address=one_to_n_address, default_secret_registry=secret_registry, default_service_registry=service_registry, transport=transport, raiden_event_handler=hold_handler, message_handler=message_handler, discovery=discovery, user_deposit=user_deposit, ) apps.append(app) return apps
def _start_services(self): from raiden.ui.console import Console from raiden.api.python import RaidenAPI config = deepcopy(App.DEFAULT_CONFIG) if self._options.get('extra_config', dict()): merge_dict(config, self._options['extra_config']) del self._options['extra_config'] self._options['config'] = config if self._options['showconfig']: print('Configuration Dump:') dump_config(config) dump_cmd_options(self._options) dump_module('settings', settings) dump_module('constants', constants) # this catches exceptions raised when waiting for the stalecheck to complete try: app_ = run_app(**self._options) except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RuntimeError as e: click.secho(str(e), fg='red') sys.exit(1) except EthNodeInterfaceError as e: click.secho(str(e), fg='red') sys.exit(1) tasks = [app_.raiden] # RaidenService takes care of Transport and AlarmTask domain_list = [] if self._options['rpccorsdomain']: if ',' in self._options['rpccorsdomain']: for domain in self._options['rpccorsdomain'].split(','): domain_list.append(str(domain)) else: domain_list.append(str(self._options['rpccorsdomain'])) self._raiden_api = RaidenAPI(app_.raiden) if self._options['rpc']: rest_api = RestAPI(self._raiden_api) api_server = APIServer( rest_api, cors_domain_list=domain_list, web_ui=self._options['web_ui'], eth_rpc_endpoint=self._options['eth_rpc_endpoint'], ) (api_host, api_port) = split_endpoint(self._options['api_address']) try: api_server.start(api_host, api_port) except APIServerPortInUseError: click.secho( f'ERROR: API Address {api_host}:{api_port} is in use. ' f'Use --api-address <host:port> to specify a different port.', fg='red', ) sys.exit(1) print( 'The Raiden API RPC server is now running at http://{}:{}/.\n\n' 'See the Raiden documentation for all available endpoints at\n' 'http://raiden-network.readthedocs.io/en/stable/rest_api.html'.format( api_host, api_port, ), ) tasks.append(api_server) if self._options['console']: console = Console(app_) console.start() tasks.append(console) # spawn a greenlet to handle the version checking version = get_system_spec()['raiden'] tasks.append(gevent.spawn(check_version, version)) # spawn a greenlet to handle the gas reserve check tasks.append(gevent.spawn(check_gas_reserve, app_.raiden)) self._startup_hook() # wait for interrupt event = AsyncResult() def sig_set(sig=None, _frame=None): event.set(sig) gevent.signal(signal.SIGQUIT, sig_set) gevent.signal(signal.SIGTERM, sig_set) gevent.signal(signal.SIGINT, sig_set) # quit if any task exits, successfully or not for task in tasks: task.link(event) try: event.get() print('Signal received. Shutting down ...') except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RaidenError as ex: click.secho(f'FATAL: {ex}', fg='red') except Exception as ex: file = NamedTemporaryFile( 'w', prefix=f'raiden-exception-{datetime.utcnow():%Y-%m-%dT%H-%M}', suffix='.txt', delete=False, ) with file as traceback_file: traceback.print_exc(file=traceback_file) click.secho( f'FATAL: An unexpected exception occured. ' f'A traceback has been written to {traceback_file.name}\n' f'{ex}', fg='red', ) finally: self._shutdown_hook() def stop_task(task): try: if isinstance(task, Runnable): task.stop() else: task.kill() finally: task.get() # re-raise gevent.joinall( [gevent.spawn(stop_task, task) for task in tasks], app_.config.get('shutdown_timeout', settings.DEFAULT_SHUTDOWN_TIMEOUT), raise_error=True, ) return app_
def _start_services(self): from raiden.ui.console import Console from raiden.api.python import RaidenAPI config = deepcopy(App.DEFAULT_CONFIG) if self._options.get('extra_config', dict()): merge_dict(config, self._options['extra_config']) del self._options['extra_config'] self._options['config'] = config if self._options['showconfig']: print('Configuration Dump:') dump_config(config) dump_cmd_options(self._options) dump_module('settings', settings) dump_module('constants', constants) # this catches exceptions raised when waiting for the stalecheck to complete try: app_ = run_app(**self._options) except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RuntimeError as e: click.secho(str(e), fg='red') sys.exit(1) except EthNodeInterfaceError as e: click.secho(str(e), fg='red') sys.exit(1) tasks = [app_.raiden ] # RaidenService takes care of Transport and AlarmTask domain_list = [] if self._options['rpccorsdomain']: if ',' in self._options['rpccorsdomain']: for domain in self._options['rpccorsdomain'].split(','): domain_list.append(str(domain)) else: domain_list.append(str(self._options['rpccorsdomain'])) self._raiden_api = RaidenAPI(app_.raiden) if self._options['discoverable']: node_address = to_checksum_address(self._raiden_api.address) rns_domain = None if self._options['rnsdomain']: rns_domain = self._options['rnsdomain'] try: rns_resolved_address = self._raiden_api.raiden.chain.get_address_from_rns( self._options['rnsdomain']) if rns_resolved_address == RNS_ADDRESS_ZERO: click.secho( 'Cannot register into the Lumino Explorer. Your RNS domain is not registered' ) sys.exit(1) elif rns_resolved_address != node_address: click.secho( 'Cannot register into the Lumino Explorer. Your RNS domain does not match with the node RSK address. The RNS domain is owned by ' + rns_resolved_address) sys.exit(1) except BadFunctionCallOutput: click.secho( "Unable to interact with RNS Public Resolver. Your node will be registered without RNS domain." ) register(node_address, rns_domain) else: if self._options['rnsdomain']: try: self._raiden_api.raiden.chain.get_address_from_rns( self._options['rnsdomain']) except BadFunctionCallOutput: click.secho( "Unable to interact with RNS Public Resolver. Please check youre interacting with the correct contract." ) sys.exit(1) self._raiden_api = RaidenAPI(app_.raiden) if self._options['rpc']: rest_api = RestAPI(self._raiden_api) (api_host, api_port) = split_endpoint(self._options['api_address']) api_server = APIServer( rest_api, config={ 'host': api_host, 'port': api_port, 'rnsdomain': self._options['rnsdomain'], 'rskendpoint': self._options['eth_rpc_endpoint'] }, cors_domain_list=domain_list, web_ui=self._options['web_ui'], eth_rpc_endpoint=self._options['eth_rpc_endpoint'], ) try: api_server.start() except APIServerPortInUseError: click.secho( f'ERROR: API Address {api_host}:{api_port} is in use. ' f'Use --api-address <host:port> to specify a different port.', fg='red', ) sys.exit(1) print( 'The Lumino API RPC server is now running at http://{}:{}/.\n\n' .format( api_host, api_port, ), ) tasks.append(api_server) if self._options['console']: console = Console(app_) console.start() tasks.append(console) # spawn a greenlet to handle the version checking version = get_system_spec()['raiden'] tasks.append(gevent.spawn(check_version, version)) # spawn a greenlet to handle the gas reserve check tasks.append(gevent.spawn(check_gas_reserve, app_.raiden)) self._startup_hook() # wait for interrupt event = AsyncResult() def sig_set(sig=None, _frame=None): event.set(sig) gevent.signal(signal.SIGQUIT, sig_set) gevent.signal(signal.SIGTERM, sig_set) gevent.signal(signal.SIGINT, sig_set) # quit if any task exits, successfully or not for task in tasks: task.link(event) try: event.get() print('Signal received. Shutting down ...') except (EthNodeCommunicationError, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RaidenError as ex: click.secho(f'FATAL: {ex}', fg='red') except Exception as ex: file = NamedTemporaryFile( 'w', prefix=f'raiden-exception-{datetime.utcnow():%Y-%m-%dT%H-%M}', suffix='.txt', delete=False, ) with file as traceback_file: traceback.print_exc(file=traceback_file) click.secho( f'FATAL: An unexpected exception occured. ' f'A traceback has been written to {traceback_file.name}\n' f'{ex}', fg='red', ) finally: self._shutdown_hook() def stop_task(task): try: if isinstance(task, Runnable): task.stop() else: task.kill() finally: task.get() # re-raise gevent.joinall( [gevent.spawn(stop_task, task) for task in tasks], app_.config.get('shutdown_timeout', settings.DEFAULT_SHUTDOWN_TIMEOUT), raise_error=True, ) return app_
def app( address, keystore_path, gas_price, eth_rpc_endpoint, registry_contract_address, secret_registry_contract_address, discovery_contract_address, listen_address, rpccorsdomain, mapped_socket, log_config, log_file, log_json, max_unresponsive_time, send_ping_time, api_address, rpc, sync_check, console, password_file, web_ui, datadir, nat, transport, matrix_server, network_id, config_file, extra_config=None, ): # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument from raiden.app import App if transport == 'udp' and not mapped_socket: raise RuntimeError('Missing socket') address_hex = to_normalized_address(address) if address else None address_hex, privatekey_bin = prompt_account(address_hex, keystore_path, password_file) address = to_canonical_address(address_hex) (listen_host, listen_port) = split_endpoint(listen_address) (api_host, api_port) = split_endpoint(api_address) if datadir is None: datadir = os.path.join(os.path.expanduser('~'), '.raiden') config = deepcopy(App.DEFAULT_CONFIG) if extra_config: merge_dict(config, extra_config) config['host'] = listen_host config['port'] = listen_port config['console'] = console config['rpc'] = rpc config['web_ui'] = rpc and web_ui config['api_host'] = api_host config['api_port'] = api_port if mapped_socket: config['socket'] = mapped_socket.socket config['external_ip'] = mapped_socket.external_ip config['external_port'] = mapped_socket.external_port config['transport_type'] = transport config['matrix']['server'] = matrix_server config['transport']['nat_keepalive_retries'] = DEFAULT_NAT_KEEPALIVE_RETRIES timeout = max_unresponsive_time / DEFAULT_NAT_KEEPALIVE_RETRIES config['transport']['nat_keepalive_timeout'] = timeout privatekey_hex = hexlify(privatekey_bin) config['privatekey_hex'] = privatekey_hex rpc_host, rpc_port = eth_endpoint_to_hostport(eth_rpc_endpoint) rpc_client = JSONRPCClient( rpc_host, rpc_port, privatekey_bin, gas_price, ) blockchain_service = BlockChainService(privatekey_bin, rpc_client) net_id = blockchain_service.network_id if net_id != network_id: if network_id in constants.ID_TO_NETWORKNAME and net_id in constants.ID_TO_NETWORKNAME: print(( "The chosen ethereum network '{}' differs from the ethereum client '{}'. " 'Please update your settings.' ).format(constants.ID_TO_NETWORKNAME[network_id], constants.ID_TO_NETWORKNAME[net_id])) else: print(( "The chosen ethereum network id '{}' differs from the ethereum client '{}'. " 'Please update your settings.' ).format(network_id, net_id)) sys.exit(1) config['chain_id'] = network_id if sync_check: check_synced(blockchain_service) database_path = os.path.join(datadir, 'netid_%s' % net_id, address_hex[:8], 'log.db') config['database_path'] = database_path print( '\nYou are connected to the \'{}\' network and the DB path is: {}'.format( constants.ID_TO_NETWORKNAME.get(net_id) or net_id, database_path, ), ) try: token_network_registry = blockchain_service.token_network_registry( registry_contract_address, ) except ContractVersionMismatch: print( 'Deployed registry contract version mismatch. ' 'Please update your Raiden installation.', ) sys.exit(1) try: secret_registry = blockchain_service.secret_registry( secret_registry_contract_address, ) except ContractVersionMismatch: print( 'Deployed secret registry contract version mismatch. ' 'Please update your Raiden installation.', ) sys.exit(1) discovery = None if transport == 'udp': check_discovery_registration_gas(blockchain_service, address) try: discovery = ContractDiscovery( blockchain_service.node_address, blockchain_service.discovery(discovery_contract_address), ) except ContractVersionMismatch: print('Deployed discovery contract version mismatch. ' 'Please update your Raiden installation.') sys.exit(1) throttle_policy = TokenBucket( config['transport']['throttle_capacity'], config['transport']['throttle_fill_rate'], ) transport = UDPTransport( discovery, mapped_socket.socket, throttle_policy, config['transport'], ) elif transport == 'matrix': # matrix gets spammed with the default retry-interval of 1s, wait a little more if config['transport']['retry_interval'] == DEFAULT_TRANSPORT_RETRY_INTERVAL: config['transport']['retry_interval'] *= 5 try: transport = MatrixTransport(config['matrix']) except RaidenError as ex: click.secho(f'FATAL: {ex}', fg='red') sys.exit(1) else: raise RuntimeError(f'Unknown transport type "{transport}" given') try: raiden_app = App( config=config, chain=blockchain_service, query_start_block=constants.ID_TO_QUERY_BLOCK[net_id], default_registry=token_network_registry, default_secret_registry=secret_registry, transport=transport, discovery=discovery, ) except RaidenError as e: click.secho(f'FATAL: {e}', fg='red') sys.exit(1) return raiden_app
def create_apps( chain_id, blockchain_services, endpoint_discovery_services, token_network_registry_address, secret_registry_address, raiden_udp_ports, reveal_timeout, settle_timeout, database_paths, retry_interval, retries_before_backoff, throttle_capacity, throttle_fill_rate, nat_invitation_timeout, nat_keepalive_retries, nat_keepalive_timeout, environment_type, unrecoverable_error_should_crash, local_matrix_url=None, private_rooms=None, ): """ Create the apps.""" # pylint: disable=too-many-locals services = zip(blockchain_services, endpoint_discovery_services) apps = [] for idx, (blockchain, discovery) in enumerate(services): port = raiden_udp_ports[idx] private_key = blockchain.private_key address = privatekey_to_address(private_key) host = '127.0.0.1' config = { 'chain_id': chain_id, 'environment_type': environment_type, 'unrecoverable_error_should_crash': unrecoverable_error_should_crash, 'privatekey_hex': encode_hex(private_key), 'reveal_timeout': reveal_timeout, 'settle_timeout': settle_timeout, 'database_path': database_paths[idx], 'blockchain': { 'confirmation_blocks': DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS, }, 'transport': { 'udp': { 'external_ip': host, 'external_port': port, 'host': host, 'nat_invitation_timeout': nat_invitation_timeout, 'nat_keepalive_retries': nat_keepalive_retries, 'nat_keepalive_timeout': nat_keepalive_timeout, 'port': port, 'retries_before_backoff': retries_before_backoff, 'retry_interval': retry_interval, 'throttle_capacity': throttle_capacity, 'throttle_fill_rate': throttle_fill_rate, }, }, 'rpc': True, 'console': False, } use_matrix = local_matrix_url is not None if use_matrix: merge_dict( config, { 'transport_type': 'matrix', 'transport': { 'matrix': { 'discovery_room': 'discovery', 'retries_before_backoff': retries_before_backoff, 'retry_interval': retry_interval, 'server': local_matrix_url, 'server_name': local_matrix_url.netloc, 'available_servers': [], 'private_rooms': private_rooms, }, }, }, ) config_copy = App.DEFAULT_CONFIG.copy() config_copy.update(config) registry = blockchain.token_network_registry(token_network_registry_address) secret_registry = blockchain.secret_registry(secret_registry_address) if use_matrix: transport = MatrixTransport(config['transport']['matrix']) else: throttle_policy = TokenBucket( config['transport']['udp']['throttle_capacity'], config['transport']['udp']['throttle_fill_rate'], ) transport = UDPTransport( address, discovery, server._udp_socket((host, port)), # pylint: disable=protected-access throttle_policy, config['transport']['udp'], ) raiden_event_handler = RaidenEventHandler() message_handler = MessageHandler() app = App( config=config_copy, chain=blockchain, query_start_block=0, default_registry=registry, default_secret_registry=secret_registry, transport=transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=discovery, ) apps.append(app) return apps
def create_apps( chain_id, blockchain_services, endpoint_discovery_services, token_network_registry_address, secret_registry_address, raiden_udp_ports, reveal_timeout, settle_timeout, database_paths, retry_interval, retries_before_backoff, throttle_capacity, throttle_fill_rate, nat_invitation_timeout, nat_keepalive_retries, nat_keepalive_timeout, environment_type, unrecoverable_error_should_crash, local_matrix_url=None, private_rooms=None, ): """ Create the apps.""" # pylint: disable=too-many-locals services = zip(blockchain_services, endpoint_discovery_services) apps = [] for idx, (blockchain, discovery) in enumerate(services): port = raiden_udp_ports[idx] private_key = blockchain.private_key address = privatekey_to_address(private_key) host = '127.0.0.1' config = { 'chain_id': chain_id, 'environment_type': environment_type, 'unrecoverable_error_should_crash': unrecoverable_error_should_crash, 'privatekey_hex': encode_hex(private_key), 'reveal_timeout': reveal_timeout, 'settle_timeout': settle_timeout, 'database_path': database_paths[idx], 'blockchain': { 'confirmation_blocks': DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS, }, 'transport': { 'udp': { 'external_ip': host, 'external_port': port, 'host': host, 'nat_invitation_timeout': nat_invitation_timeout, 'nat_keepalive_retries': nat_keepalive_retries, 'nat_keepalive_timeout': nat_keepalive_timeout, 'port': port, 'retries_before_backoff': retries_before_backoff, 'retry_interval': retry_interval, 'throttle_capacity': throttle_capacity, 'throttle_fill_rate': throttle_fill_rate, }, }, 'rpc': True, 'console': False, } use_matrix = local_matrix_url is not None if use_matrix: merge_dict( config, { 'transport_type': 'matrix', 'transport': { 'matrix': { 'discovery_room': 'discovery', 'retries_before_backoff': retries_before_backoff, 'retry_interval': retry_interval, 'server': local_matrix_url, 'server_name': local_matrix_url.netloc, 'available_servers': [], 'private_rooms': private_rooms, }, }, }, ) config_copy = App.DEFAULT_CONFIG.copy() config_copy.update(config) registry = blockchain.token_network_registry( token_network_registry_address) secret_registry = blockchain.secret_registry(secret_registry_address) if use_matrix: transport = MatrixTransport(config['transport']['matrix']) else: throttle_policy = TokenBucket( config['transport']['udp']['throttle_capacity'], config['transport']['udp']['throttle_fill_rate'], ) transport = UDPTransport( address, discovery, server._udp_socket((host, port)), # pylint: disable=protected-access throttle_policy, config['transport']['udp'], ) raiden_event_handler = RaidenEventHandler() message_handler = MessageHandler() app = App( config=config_copy, chain=blockchain, query_start_block=0, default_registry=registry, default_secret_registry=secret_registry, transport=transport, raiden_event_handler=raiden_event_handler, message_handler=message_handler, discovery=discovery, ) apps.append(app) return apps
def _run_smoketest(): print_step('Starting Raiden') config = deepcopy(App.DEFAULT_CONFIG) if args.get('extra_config', dict()): merge_dict(config, args['extra_config']) del args['extra_config'] args['config'] = config raiden_stdout = StringIO() with contextlib.redirect_stdout(raiden_stdout): app = run_app(**args) try: raiden_api = RaidenAPI(app.raiden) rest_api = RestAPI(raiden_api) (api_host, api_port) = split_endpoint(args['api_address']) api_server = APIServer(rest_api, config={ 'host': api_host, 'port': api_port }) api_server.start() block = app.raiden.get_block_number( ) + DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS # Proxies now use the confirmed block hash to query the chain for # prerequisite checks. Wait a bit here to make sure that the confirmed # block hash contains the deployed token network or else things break wait_for_block( raiden=app.raiden, block_number=block, retry_timeout=1.0, ) raiden_api.channel_open( registry_address=contract_addresses[ CONTRACT_TOKEN_NETWORK_REGISTRY], token_address=to_canonical_address(token.contract.address), partner_address=to_canonical_address(TEST_PARTNER_ADDRESS), ) raiden_api.set_total_channel_deposit( contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], to_canonical_address(token.contract.address), to_canonical_address(TEST_PARTNER_ADDRESS), TEST_DEPOSIT_AMOUNT, ) token_addresses = [to_checksum_address(token.contract.address)] success = False print_step('Running smoketest') error = run_smoketests( app.raiden, args['transport'], token_addresses, contract_addresses[CONTRACT_ENDPOINT_REGISTRY], debug=debug, orig_stdout=stdout, ) if error is not None: append_report('Smoketest assertion error', error) else: success = True finally: app.stop() app.raiden.get() node = ethereum[0] node.send_signal(2) err, out = node.communicate() append_report('Ethereum stdout', out) append_report('Ethereum stderr', err) append_report('Raiden Node stdout', raiden_stdout.getvalue()) if success: print_step(f'Smoketest successful') else: print_step(f'Smoketest had errors', error=True) return success
def _start_services(self): from raiden.api.python import RaidenAPI config = deepcopy(App.DEFAULT_CONFIG) config["reveal_timeout"] = self._options["default_reveal_timeout"] config["settle_timeout"] = self._options["default_settle_timeout"] if self._options.get("extra_config", dict()): merge_dict(config, self._options["extra_config"]) del self._options["extra_config"] self._options["config"] = config if self._options["showconfig"]: print("Configuration Dump:") dump_config(config) dump_cmd_options(self._options) dump_module("settings", settings) dump_module("constants", constants) # this catches exceptions raised when waiting for the stalecheck to complete try: app_ = run_app(**self._options) except (ConnectionError, ConnectTimeout, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RuntimeError as e: click.secho(str(e), fg="red") sys.exit(1) except EthNodeInterfaceError as e: click.secho(str(e), fg="red") sys.exit(1) tasks = [app_.raiden] # RaidenService takes care of Transport and AlarmTask domain_list = [] if self._options["rpccorsdomain"]: if "," in self._options["rpccorsdomain"]: for domain in self._options["rpccorsdomain"].split(","): domain_list.append(str(domain)) else: domain_list.append(str(self._options["rpccorsdomain"])) self._raiden_api = RaidenAPI(app_.raiden) if self._options["rpc"]: rest_api = RestAPI(self._raiden_api) (api_host, api_port) = split_endpoint(self._options["api_address"]) if not api_port: api_port = Port(settings.DEFAULT_HTTP_SERVER_PORT) api_server = APIServer( rest_api, config={"host": api_host, "port": api_port}, cors_domain_list=domain_list, web_ui=self._options["web_ui"], eth_rpc_endpoint=self._options["eth_rpc_endpoint"], ) try: api_server.start() except APIServerPortInUseError: click.secho( f"ERROR: API Address {api_host}:{api_port} is in use. " f"Use --api-address <host:port> to specify a different port.", fg="red", ) sys.exit(1) print( "The Raiden API RPC server is now running at http://{}:{}/.\n\n" "See the Raiden documentation for all available endpoints at\n" "http://raiden-network.readthedocs.io/en/stable/rest_api.html".format( api_host, api_port ) ) tasks.append(api_server) if self._options["console"]: from raiden.ui.console import Console console = Console(app_) console.start() tasks.append(console) # spawn a greenlet to handle the version checking version = get_system_spec()["raiden"] tasks.append(gevent.spawn(check_version, version)) # spawn a greenlet to handle the gas reserve check tasks.append(gevent.spawn(check_gas_reserve, app_.raiden)) # spawn a greenlet to handle the periodic check for the network id tasks.append( gevent.spawn( check_network_id, app_.raiden.rpc_client.chain_id, app_.raiden.rpc_client.web3 ) ) spawn_user_deposit_task = app_.user_deposit and ( self._options["pathfinding_service_address"] or self._options["enable_monitoring"] ) if spawn_user_deposit_task: # spawn a greenlet to handle RDN deposits check tasks.append(gevent.spawn(check_rdn_deposits, app_.raiden, app_.user_deposit)) # spawn a greenlet to handle the functions self._startup_hook() # wait for interrupt event: "AsyncResult[None]" = AsyncResult() def sig_set(sig=None, _frame=None): event.set(sig) gevent.signal(signal.SIGQUIT, sig_set) gevent.signal(signal.SIGTERM, sig_set) gevent.signal(signal.SIGINT, sig_set) # quit if any task exits, successfully or not for task in tasks: task.link(event) try: event.get() print("Signal received. Shutting down ...") except (ConnectionError, ConnectTimeout, RequestsConnectionError): print(ETHEREUM_NODE_COMMUNICATION_ERROR) sys.exit(1) except RaidenError as ex: click.secho(f"FATAL: {ex}", fg="red") except Exception as ex: file = NamedTemporaryFile( "w", prefix=f"raiden-exception-{datetime.utcnow():%Y-%m-%dT%H-%M}", suffix=".txt", delete=False, ) with file as traceback_file: traceback.print_exc(file=traceback_file) click.secho( f"FATAL: An unexpected exception occured. " f"A traceback has been written to {traceback_file.name}\n" f"{ex}", fg="red", ) finally: self._shutdown_hook() app_.stop() def stop_task(task): try: if isinstance(task, Runnable): task.stop() else: task.kill() finally: task.get() # re-raise gevent.joinall( [gevent.spawn(stop_task, task) for task in tasks], app_.config.get("shutdown_timeout", settings.DEFAULT_SHUTDOWN_TIMEOUT), raise_error=True, ) return app_
def _run_smoketest(): print_step('Starting Raiden') config = deepcopy(App.DEFAULT_CONFIG) if args.get('extra_config', dict()): merge_dict(config, args['extra_config']) del args['extra_config'] args['config'] = config raiden_stdout = StringIO() with contextlib.redirect_stdout(raiden_stdout): try: # invoke the raiden app app = run_app(**args) raiden_api = RaidenAPI(app.raiden) rest_api = RestAPI(raiden_api) api_server = APIServer(rest_api) (api_host, api_port) = split_endpoint(args['api_address']) api_server.start(api_host, api_port) raiden_api.channel_open( registry_address=contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], token_address=to_canonical_address(token.contract.address), partner_address=to_canonical_address(TEST_PARTNER_ADDRESS), ) raiden_api.set_total_channel_deposit( contract_addresses[CONTRACT_TOKEN_NETWORK_REGISTRY], to_canonical_address(token.contract.address), to_canonical_address(TEST_PARTNER_ADDRESS), TEST_DEPOSIT_AMOUNT, ) token_addresses = [to_checksum_address(token.contract.address)] success = False print_step('Running smoketest') error = run_smoketests( app.raiden, args['transport'], token_addresses, contract_addresses[CONTRACT_ENDPOINT_REGISTRY], debug=debug, ) if error is not None: append_report('Smoketest assertion error', error) else: success = True finally: app.stop() app.raiden.get() node = ethereum[0] node.send_signal(2) err, out = node.communicate() append_report('Ethereum stdout', out) append_report('Ethereum stderr', err) append_report('Raiden Node stdout', raiden_stdout.getvalue()) if success: print_step(f'Smoketest successful') else: print_step(f'Smoketest had errors', error=True) return success