Beispiel #1
0
def run(ctx, external_listen_address, **kwargs):
    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.

    if not external_listen_address:
        # notify('if you are behind a NAT, you should set
        # `external_listen_address` and configure port forwarding on your router')
        external_listen_address = kwargs['listen_address']

    ctx.params.pop('external_listen_address')
    app_ = ctx.invoke(app, **kwargs)

    app_.discovery.register(
        app_.raiden.address,
        *split_endpoint(external_listen_address)
    )

    app_.raiden.register_registry(app_.raiden.chain.default_registry)

    console = Console(app_)
    console.start()

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #2
0
def run(ctx, **kwargs):
    from raiden.api.python import RaidenAPI
    from raiden.ui.console import Console

    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.
    (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
    with socket_factory(listen_host, listen_port) as mapped_socket:
        kwargs['socket'] = mapped_socket.socket

        app_ = ctx.invoke(app, **kwargs)

        # spawn address registration to avoid block while waiting for the next block
        registry_event = gevent.spawn(
            app_.discovery.register,
            app_.raiden.address,
            mapped_socket.external_ip,
            mapped_socket.external_port,
        )
        app_.raiden.register_registry(
            app_.raiden.chain.default_registry.address)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(rest_api, cors_domain_list=domain_list)

            Greenlet.spawn(api_server.run,
                           ctx.params['api_port'],
                           debug=False,
                           use_evalex=False)

            print(
                "The RPC server is now running at http://localhost:{}/.\n\n"
                "See the Raiden documentation for all available endpoints at\n"
                "https://github.com/raiden-network/raiden/blob/master/docs/Rest-Api.rst"
                .format(ctx.params['api_port'], ))

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        registry_event.join()
        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)
        event.wait()

        app_.stop(graceful=True)
Beispiel #3
0
def run(ctx, external_listen_address, **kwargs):
    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.

    if not external_listen_address:
        # notify('if you are behind a NAT, you should set
        # `external_listen_address` and configure port forwarding on your router')
        external_listen_address = kwargs['listen_address']

    ctx.params.pop('external_listen_address')
    app_ = ctx.invoke(app, **kwargs)

    app_.discovery.register(app_.raiden.address,
                            *split_endpoint(external_listen_address))

    app_.raiden.register_registry(app_.raiden.chain.default_registry)

    console = Console(app_)
    console.start()

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app.stop()
Beispiel #4
0
def run(ctx, **kwargs):
    if ctx.invoked_subcommand is None:
        from raiden.api.python import RaidenAPI
        from raiden.ui.console import Console

        slogging.configure(kwargs['logging'], log_file=kwargs['logfile'])

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        with socket_factory(listen_host, listen_port) as mapped_socket:
            kwargs['mapped_socket'] = mapped_socket

            app_ = ctx.invoke(app, **kwargs)

            domain_list = []
            if kwargs['rpccorsdomain']:
                if ',' in kwargs['rpccorsdomain']:
                    for domain in kwargs['rpccorsdomain'].split(','):
                        domain_list.append(str(domain))
                else:
                    domain_list.append(str(kwargs['rpccorsdomain']))

            http_server = None
            if ctx.params['rpc']:
                raiden_api = RaidenAPI(app_.raiden)
                rest_api = RestAPI(raiden_api)
                api_server = APIServer(rest_api, cors_domain_list=domain_list)
                (api_host, api_port) = split_endpoint(kwargs["api_address"])

                http_server = WSGIServer((api_host, api_port),
                                         api_server.flask_app,
                                         log=slogging.getLogger('flask'))
                http_server.start()

                print(
                    "The Raiden API RPC server is now running at http://{}:{}/.\n\n"
                    "See the Raiden documentation for all available endpoints at\n"
                    "https://github.com/raiden-network/raiden/blob/master"
                    "/docs/Rest-Api.rst".format(
                        api_host,
                        api_port,
                    ))

            if ctx.params['console']:
                console = Console(app_)
                console.start()

            # wait for interrupt
            event = gevent.event.Event()
            gevent.signal(signal.SIGQUIT, event.set)
            gevent.signal(signal.SIGTERM, event.set)
            gevent.signal(signal.SIGINT, event.set)
            event.wait()

        if http_server:
            http_server.stop(5)
        app_.stop(leave_channels=False)
Beispiel #5
0
    def _run_app():
        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = ctx.invoke(app, **kwargs)
        except EthNodeCommunicationError as err:
            sys.exit(1)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        api_server = None
        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=ctx.params['web_ui'],
                eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(kwargs['api_address'])
            api_server.start(api_host, api_port)

            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,
                ))

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
        gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

        event.wait()
        print('Signal received. Shutting down ...')
        if api_server:
            api_server.stop()

        return app_
Beispiel #6
0
def run(ctx, external_listen_address, **kwargs):
    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.

    if not external_listen_address:
        # notify('if you are behind a NAT, you should set
        # `external_listen_address` and configure port forwarding on your router')
        external_listen_address = kwargs['listen_address']

    ctx.params.pop('external_listen_address')
    app_ = ctx.invoke(app, **kwargs)

    app_.discovery.register(
        app_.raiden.address,
        *split_endpoint(external_listen_address)
    )

    app_.raiden.register_registry(app_.raiden.chain.default_registry.address)

    if ctx.params['rpc']:
        # instance of the raiden-api
        raiden_api = app_.raiden.api
        # wrap the raiden-api with rest-logic and encoding
        rest_api = RestAPI(raiden_api)
        # create the server and link the api-endpoints with flask / flask-restful middleware
        api_server = APIServer(rest_api)
        # run the server
        Greenlet.spawn(api_server.run, ctx.params['api_port'], debug=False, use_evalex=False)
        print(
            "The RPC server is now running",
            "at http://localhost:{0}/.".format(ctx.params['api_port'])
        )
        print(
            "See the Raiden documentation for all available endpoints at",
            "https://github.com/raiden-network/raiden/blob/master/docs/api.rst"
        )

    if ctx.params['console']:
        console = Console(app_)
        console.start()

    # wait for interrupt
    event = gevent.event.Event()
    gevent.signal(signal.SIGQUIT, event.set)
    gevent.signal(signal.SIGTERM, event.set)
    gevent.signal(signal.SIGINT, event.set)
    event.wait()

    app_.stop()
Beispiel #7
0
def run(ctx, **kwargs):
    # TODO:
    # - Ask for confirmation to quit if there are any locked transfers that did
    # not timeout.
    (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
    with socket_factory(listen_host, listen_port) as mapped_socket:
        kwargs['socket'] = mapped_socket.socket

        app_ = ctx.invoke(app, **kwargs)

        app_.discovery.register(
            app_.raiden.address,
            mapped_socket.external_ip,
            mapped_socket.external_port,
        )

        app_.raiden.register_registry(
            app_.raiden.chain.default_registry.address)

        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(rest_api)

            Greenlet.spawn(api_server.run,
                           ctx.params['api_port'],
                           debug=False,
                           use_evalex=False)

            print(
                "The RPC server is now running at http://localhost:{}/.\n\n"
                "See the Raiden documentation for all available endpoints at\n"
                "https://github.com/raiden-network/raiden/blob/master/docs/api.rst"
                .format(ctx.params['api_port'], ))

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)
        event.wait()

        app_.stop()
Beispiel #8
0
def run(ctx, **kwargs):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    if ctx.invoked_subcommand is None:
        print('Welcome to Raiden, version {}!'.format(
            get_system_spec()['raiden']))
        from raiden.ui.console import Console
        from raiden.api.python import RaidenAPI

        slogging.configure(kwargs['logging'],
                           log_json=kwargs['log_json'],
                           log_file=kwargs['logfile'])
        if kwargs['logfile']:
            # Disable stream logging
            root = slogging.getLogger()
            for handler in root.handlers:
                if isinstance(handler, slogging.logging.StreamHandler):
                    root.handlers.remove(handler)
                    break

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        try:
            with SocketFactory(listen_host,
                               listen_port,
                               strategy=kwargs['nat']) as mapped_socket:
                kwargs['mapped_socket'] = mapped_socket

                app_ = ctx.invoke(app, **kwargs)

                domain_list = []
                if kwargs['rpccorsdomain']:
                    if ',' in kwargs['rpccorsdomain']:
                        for domain in kwargs['rpccorsdomain'].split(','):
                            domain_list.append(str(domain))
                    else:
                        domain_list.append(str(kwargs['rpccorsdomain']))

                if ctx.params['rpc']:
                    raiden_api = RaidenAPI(app_.raiden)
                    rest_api = RestAPI(raiden_api)
                    api_server = APIServer(
                        rest_api,
                        cors_domain_list=domain_list,
                        web_ui=ctx.params['web_ui'],
                        eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
                    )
                    (api_host,
                     api_port) = split_endpoint(kwargs['api_address'])
                    api_server.start(api_host, api_port)

                    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,
                        ))

                if ctx.params['console']:
                    console = Console(app_)
                    console.start()

                # wait for interrupt
                event = gevent.event.Event()
                gevent.signal(signal.SIGQUIT, event.set)
                gevent.signal(signal.SIGTERM, event.set)
                gevent.signal(signal.SIGINT, event.set)

                gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
                gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

                event.wait()
                print('Signal received. Shutting down ...')
                try:
                    api_server.stop()
                except NameError:
                    pass
        except socket.error as v:
            if v.args[0] == errno.EADDRINUSE:
                print(
                    'ERROR: Address %s:%s is in use. '
                    'Use --listen-address <host:port> to specify port to listen on.'
                    % (listen_host, listen_port))
                sys.exit(1)
            raise
        app_.stop(leave_channels=False)
    else:
        # Pass parsed args on to subcommands.
        ctx.obj = kwargs
Beispiel #9
0
def run(ctx, **kwargs):
    if ctx.invoked_subcommand is None:
        from raiden.api.python import RaidenAPI
        from raiden.ui.console import Console

        slogging.configure(
            kwargs['logging'],
            log_json=kwargs['log_json'],
            log_file=kwargs['logfile']
        )

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        try:
            with socket_factory(listen_host, listen_port) as mapped_socket:
                kwargs['mapped_socket'] = mapped_socket

                app_ = ctx.invoke(app, **kwargs)

                domain_list = []
                if kwargs['rpccorsdomain']:
                    if ',' in kwargs['rpccorsdomain']:
                        for domain in kwargs['rpccorsdomain'].split(','):
                            domain_list.append(str(domain))
                    else:
                        domain_list.append(str(kwargs['rpccorsdomain']))

                if ctx.params['rpc']:
                    raiden_api = RaidenAPI(app_.raiden)
                    rest_api = RestAPI(raiden_api)
                    api_server = APIServer(
                        rest_api,
                        cors_domain_list=domain_list,
                        web_ui=ctx.params['web_ui'],
                    )
                    (api_host, api_port) = split_endpoint(kwargs["api_address"])
                    api_server.start(api_host, api_port)

                    print(
                        "The Raiden API RPC server is now running at http://{}:{}/.\n\n"
                        "See the Raiden documentation for all available endpoints at\n"
                        "https://github.com/raiden-network/raiden/blob/master"
                        "/docs/Rest-Api.rst".format(
                            api_host,
                            api_port,
                        )
                    )

                if ctx.params['console']:
                    console = Console(app_)
                    console.start()

                # wait for interrupt
                event = gevent.event.Event()
                gevent.signal(signal.SIGQUIT, event.set)
                gevent.signal(signal.SIGTERM, event.set)
                gevent.signal(signal.SIGINT, event.set)

                gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
                gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

                event.wait()

                try:
                    api_server.stop()
                except NameError:
                    pass
        except socket.error as v:
            if v.args[0] == errno.EADDRINUSE:
                print("ERROR: Address %s:%s is in use. "
                      "Use --listen-address <host:port> to specify port to listen on." %
                      (listen_host, listen_port))
                sys.exit(1)
            raise
        app_.stop(leave_channels=False)
    else:
        # Pass parsed args on to subcommands.
        ctx.obj = kwargs
Beispiel #10
0
    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_
Beispiel #11
0
    def _run_app():
        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = ctx.invoke(app, **kwargs)
        except EthNodeCommunicationError:
            sys.exit(1)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        api_server = None
        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=ctx.params['web_ui'],
                eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(kwargs['api_address'])

            try:
                api_server.start(api_host, api_port)
            except APIServerPortInUseError:
                print(
                    'ERROR: API Address %s:%s is in use. '
                    'Use --api-address <host:port> to specify port to listen on.' %
                    (api_host, api_port),
                )
                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,
                ),
            )

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # spawning a thread to handle the version checking
        gevent.spawn(check_version)

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        try:
            event.wait()
            print('Signal received. Shutting down ...')
        except RaidenError as ex:
            click.secho(f'FATAL: {ex}', fg='red')
        except Exception as ex:
            with NamedTemporaryFile(
                'w',
                prefix='raiden-exception',
                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',
                )

        if api_server:
            api_server.stop()

        return app_
Beispiel #12
0
    def _run_app(self):
        from raiden.ui.console import Console
        from raiden.api.python import RaidenAPI

        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = run_app(**self._options)
        except EthNodeCommunicationError:
            print(
                '\n'
                'Could not contact the ethereum node through JSON-RPC.\n'
                'Please make sure that JSON-RPC is enabled for these interfaces:\n'
                '\n'
                '    eth_*, net_*, web3_*\n'
                '\n'
                'geth: https://github.com/ethereum/go-ethereum/wiki/Management-APIs\n',
            )
            sys.exit(1)

        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)

        api_server = None
        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:
                print(
                    'ERROR: API Address %s:%s is in use. '
                    'Use --api-address <host:port> to specify port to listen on.'
                    % (api_host, api_port), )
                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,
                ), )

        if self._options['console']:
            console = Console(app_)
            console.start()

        # spawn a greenlet to handle the version checking
        gevent.spawn(check_version)
        # spawn a greenlet to handle the gas reserve check
        gevent.spawn(check_gas_reserve, app_.raiden)

        self._startup_hook()

        # wait for interrupt
        event = RaidenGreenletEvent()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        try:
            event.wait()
            print('Signal received. Shutting down ...')
        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()
            if api_server:
                api_server.stop()

        return app_
Beispiel #13
0
    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_
Beispiel #14
0
    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_
Beispiel #15
0
def run_services(options: Dict[str, Any]) -> None:
    if options["config_file"]:
        log.debug("Using config file", config_file=options["config_file"])

    app = run_app(**options)

    gevent_tasks: List[gevent.Greenlet] = list()

    if options["console"]:
        from raiden.ui.console import Console

        console = Console(app)
        console.start()

        gevent_tasks.append(console)

    gevent_tasks.append(spawn_named("check_version", check_version, get_system_spec()["raiden"]))
    gevent_tasks.append(spawn_named("check_gas_reserve", check_gas_reserve, app.raiden))
    gevent_tasks.append(
        spawn_named(
            "check_network_id",
            check_network_id,
            app.raiden.rpc_client.chain_id,
            app.raiden.rpc_client.web3,
        )
    )

    spawn_user_deposit_task = app.user_deposit and (
        options["pathfinding_service_address"] or options["enable_monitoring"]
    )
    if spawn_user_deposit_task:
        gevent_tasks.append(
            spawn_named("check_rdn_deposits", check_rdn_deposits, app.raiden, app.user_deposit)
        )

    stop_event: AsyncResult[Optional[signal.Signals]]  # pylint: disable=no-member
    stop_event = AsyncResult()

    def sig_set(sig: int, _frame: Any = None) -> None:
        stop_event.set(signal.Signals(sig))  # pylint: disable=no-member

    gevent.signal.signal(signal.SIGQUIT, sig_set)  # pylint: disable=no-member
    gevent.signal.signal(signal.SIGTERM, sig_set)  # pylint: disable=no-member
    gevent.signal.signal(signal.SIGINT, sig_set)  # pylint: disable=no-member

    # The SIGPIPE handler should not be installed. It is handled by the python
    # runtime, and an exception will be raised at the call site that triggered
    # the error.
    #
    # The default SIGPIPE handler set by the libc will terminate the process
    # [4]. However, the CPython interpreter changes the handler to IGN [3].
    # This allows for error reporting by the system calls that write to files.
    # Because of this, calling `send` to a closed socket will return an `EPIPE`
    # error [2], the error is then converted to an exception [5,6].
    #
    # 1 - https://github.com/python/cpython/blob/3.8/Modules/socketmodule.c#L4088
    # 2 - http://man7.org/linux/man-pages/man2/send.2.html
    # 3 - https://github.com/python/cpython/blob/3.8/Python/pylifecycle.c#L2306-L2307
    # 4 - https://www.gnu.org/software/libc/manual/html_node/Operation-Error-Signals.html
    # 5 - https://github.com/python/cpython/blob/3.8/Modules/socketmodule.c#L836-L838
    # 6 - https://github.com/python/cpython/blob/3.8/Modules/socketmodule.c#L627-L628
    # 7 - https://docs.python.org/3/library/signal.html#note-on-sigpipe
    #
    # gevent.signal.signal(signal.SIGPIPE, sig_set)  # pylint: disable=no-member

    # quit if any task exits, successfully or not
    app.raiden.greenlet.link(stop_event)
    for task in gevent_tasks:
        task.link(stop_event)

    try:
        signal_received = stop_event.get()
        if signal_received:
            print("\r", end="")  # Reset cursor to overwrite a possibly printed "^C"
            log.info("Signal received. Shutting down.", signal=signal_received)
    finally:
        for task in gevent_tasks:
            task.kill()

        app.raiden.stop()

        gevent.joinall(
            set(gevent_tasks + [app.raiden]), app.config.shutdown_timeout, raise_error=True
        )

        app.stop()
Beispiel #16
0
def run(ctx, **kwargs):
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements

    if ctx.invoked_subcommand is None:
        print('Welcome to Raiden, version {}!'.format(get_system_spec()['raiden']))
        from raiden.ui.console import Console
        from raiden.api.python import RaidenAPI

        slogging.configure(
            kwargs['logging'],
            log_json=kwargs['log_json'],
            log_file=kwargs['logfile']
        )
        if kwargs['logfile']:
            # Disable stream logging
            root = slogging.getLogger()
            for handler in root.handlers:
                if isinstance(handler, slogging.logging.StreamHandler):
                    root.handlers.remove(handler)
                    break

        # TODO:
        # - Ask for confirmation to quit if there are any locked transfers that did
        # not timeout.
        (listen_host, listen_port) = split_endpoint(kwargs['listen_address'])
        try:
            with SocketFactory(listen_host, listen_port, strategy=kwargs['nat']) as mapped_socket:
                kwargs['mapped_socket'] = mapped_socket

                app_ = ctx.invoke(app, **kwargs)

                domain_list = []
                if kwargs['rpccorsdomain']:
                    if ',' in kwargs['rpccorsdomain']:
                        for domain in kwargs['rpccorsdomain'].split(','):
                            domain_list.append(str(domain))
                    else:
                        domain_list.append(str(kwargs['rpccorsdomain']))

                if ctx.params['rpc']:
                    raiden_api = RaidenAPI(app_.raiden)
                    rest_api = RestAPI(raiden_api)
                    api_server = APIServer(
                        rest_api,
                        cors_domain_list=domain_list,
                        web_ui=ctx.params['web_ui'],
                        eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
                    )
                    (api_host, api_port) = split_endpoint(kwargs['api_address'])
                    api_server.start(api_host, api_port)

                    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,
                        )
                    )

                if ctx.params['console']:
                    console = Console(app_)
                    console.start()

                # wait for interrupt
                event = gevent.event.Event()
                gevent.signal(signal.SIGQUIT, event.set)
                gevent.signal(signal.SIGTERM, event.set)
                gevent.signal(signal.SIGINT, event.set)

                gevent.signal(signal.SIGUSR1, toogle_cpu_profiler)
                gevent.signal(signal.SIGUSR2, toggle_trace_profiler)

                event.wait()
                print('Signal received. Shutting down ...')
                try:
                    api_server.stop()
                except NameError:
                    pass
        except socket.error as v:
            if v.args[0] == errno.EADDRINUSE:
                print('ERROR: Address %s:%s is in use. '
                      'Use --listen-address <host:port> to specify port to listen on.' %
                      (listen_host, listen_port))
                sys.exit(1)
            raise
        app_.stop(leave_channels=False)
    else:
        # Pass parsed args on to subcommands.
        ctx.obj = kwargs
Beispiel #17
0
    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_
Beispiel #18
0
    def _run_app():
        # this catches exceptions raised when waiting for the stalecheck to complete
        try:
            app_ = ctx.invoke(app, **kwargs)
        except EthNodeCommunicationError:
            print(
                '\n'
                'Could not contact the ethereum node through JSON-RPC.\n'
                'Please make sure that JSON-RPC is enabled for these interfaces:\n'
                '\n'
                '    eth_*, net_*, web3_*\n'
                '\n'
                'geth: https://github.com/ethereum/go-ethereum/wiki/Management-APIs\n',
            )
            sys.exit(1)

        domain_list = []
        if kwargs['rpccorsdomain']:
            if ',' in kwargs['rpccorsdomain']:
                for domain in kwargs['rpccorsdomain'].split(','):
                    domain_list.append(str(domain))
            else:
                domain_list.append(str(kwargs['rpccorsdomain']))

        api_server = None
        if ctx.params['rpc']:
            raiden_api = RaidenAPI(app_.raiden)
            rest_api = RestAPI(raiden_api)
            api_server = APIServer(
                rest_api,
                cors_domain_list=domain_list,
                web_ui=ctx.params['web_ui'],
                eth_rpc_endpoint=ctx.params['eth_rpc_endpoint'],
            )
            (api_host, api_port) = split_endpoint(kwargs['api_address'])

            try:
                api_server.start(api_host, api_port)
            except APIServerPortInUseError:
                print(
                    'ERROR: API Address %s:%s is in use. '
                    'Use --api-address <host:port> to specify port to listen on.' %
                    (api_host, api_port),
                )
                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,
                ),
            )

        if ctx.params['console']:
            console = Console(app_)
            console.start()

        # spawning a thread to handle the version checking
        gevent.spawn(check_version)

        # wait for interrupt
        event = gevent.event.Event()
        gevent.signal(signal.SIGQUIT, event.set)
        gevent.signal(signal.SIGTERM, event.set)
        gevent.signal(signal.SIGINT, event.set)

        try:
            event.wait()
            print('Signal received. Shutting down ...')
        except RaidenError as ex:
            click.secho(f'FATAL: {ex}', fg='red')
        except Exception as ex:
            with NamedTemporaryFile(
                'w',
                prefix='raiden-exception',
                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',
                )

        if api_server:
            api_server.stop()

        return app_
Beispiel #19
0
    def _start_services(self) -> None:
        if self._options["showconfig"]:
            print("Configuration Dump:")
            dump_cmd_options(self._options)
            dump_module("settings", settings)
            dump_module("constants", constants)

        app = run_app(**self._options)

        gevent_tasks: List[gevent.Greenlet] = list()
        runnable_tasks: List[Runnable] = list()

        runnable_tasks.append(app.raiden)

        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"],
            )
            api_server.start()

            url = f"http://{api_host}:{api_port}/"
            print(
                f"The Raiden API RPC server is now running at {url}.\n\n See "
                f"the Raiden documentation for all available endpoints at\n "
                f"{DOC_URL}"
            )
            runnable_tasks.append(api_server)

        if self._options["console"]:
            from raiden.ui.console import Console

            console = Console(app)
            console.start()

            gevent_tasks.append(console)

        gevent_tasks.append(gevent.spawn(check_version, get_system_spec()["raiden"]))
        gevent_tasks.append(gevent.spawn(check_gas_reserve, app.raiden))
        gevent_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:
            gevent_tasks.append(gevent.spawn(check_rdn_deposits, app.raiden, app.user_deposit))

        self._startup_hook()

        stop_event: AsyncResult[None] = AsyncResult()

        def sig_set(sig: Any = None, _frame: Any = None) -> None:
            stop_event.set(sig)

        gevent.signal(signal.SIGQUIT, sig_set)
        gevent.signal(signal.SIGTERM, sig_set)
        gevent.signal(signal.SIGINT, sig_set)

        # Make sure RaidenService is the last service in the list.
        runnable_tasks.reverse()

        # quit if any task exits, successfully or not
        for runnable in runnable_tasks:
            runnable.greenlet.link(stop_event)

        for task in gevent_tasks:
            task.link(stop_event)

        msg = (
            "The RaidenService must be last service to stop, since the other "
            "services depend on it to run. Without this it is not possible to have a "
            "clean shutdown, e.g. the RestAPI must be stopped before "
            "RaidenService, otherwise it is possible for a request to be "
            "processed after the RaidenService was stopped and it will cause a "
            "crash."
        )
        assert isinstance(runnable_tasks[-1], RaidenService), msg

        try:
            stop_event.get()
            print("Signal received. Shutting down ...")
        finally:
            self._shutdown_hook()

            for task in gevent_tasks:
                task.kill()

            for task in runnable_tasks:
                task.stop()

            gevent.joinall(
                set(gevent_tasks + runnable_tasks), app.config.shutdown_timeout, raise_error=True
            )

            app.stop()
Beispiel #20
0
    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_