Пример #1
0
def split_endpoint(endpoint: Endpoint) -> HostPort:
    match = re.match(r"(?:[a-z0-9]*:?//)?([^:/]+)(?::(\d+))?", endpoint, re.I)
    if not match:
        raise ValueError("Invalid endpoint", endpoint)
    host, port = match.groups()
    if not port:
        port = "0"
    return Host(host), Port(int(port))
Пример #2
0
def split_endpoint(endpoint: str) -> HostPort:
    match = re.match(r"(?:[a-z0-9]*:?//)?([^:/]+)(?::(\d+))?", endpoint, re.I)
    if not match:
        raise ValueError("Invalid endpoint", endpoint)
    host, port = match.groups()
    returned_port = None
    if port:
        returned_port = Port(int(port))
    return Host(host), returned_port
Пример #3
0
    def _unused_ports(initial_port: Optional[int]) -> Iterable[Port]:
        initial_port = initial_port or 27854

        for port in count(initial_port):
            connect_using_port = (conn for conn in psutil.net_connections()
                                  if hasattr(conn, "laddr") and conn.laddr[0]
                                  == LOOPBACK and conn.laddr[1] == port)

            if not any(connect_using_port):
                yield Port(port)
Пример #4
0
def main() -> None:
    tmpdir = tempfile.mkdtemp()

    geth_nodes = []
    for i in range(NUM_GETH_NODES):
        is_miner = i == 0
        node_key = PrivateKey(sha3(f"node:{i}".encode()))
        p2p_port = Port(START_PORT + i)
        rpc_port = Port(START_RPCPORT + i)

        description = EthNodeDescription(
            private_key=node_key,
            rpc_port=rpc_port,
            p2p_port=p2p_port,
            miner=is_miner,
            extra_config={},
        )

        geth_nodes.append(description)

    rpc_endpoint = f"http://127.0.0.1:{START_RPCPORT}"
    web3 = Web3(HTTPProvider(rpc_endpoint))

    random_marker = remove_0x_prefix(hex(random.getrandbits(100)))
    genesis_description = GenesisDescription(
        prefunded_accounts=DEFAULT_ACCOUNTS,
        random_marker=random_marker,
        chain_id=ChainID(NETWORKNAME_TO_ID["smoketest"]),
    )
    private_chain: ContextManager[
        List[JSONRPCExecutor]] = run_private_blockchain(
            web3=web3,
            eth_nodes=geth_nodes,
            base_datadir=tmpdir,
            log_dir=tmpdir,
            verbosity="info",
            genesis_description=genesis_description,
        )

    with private_chain:
        from IPython import embed

        embed()
Пример #5
0
    def _unused_ports(initial_port: Optional[int]) -> Iterator[Port]:
        initial_port = initial_port or 27854

        for port in count(initial_port):
            # Because it is not known which interface the socket will bind to,
            # if there is any socket in the target port it must be skiped.
            connect_using_port = (
                conn for conn in psutil.net_connections()
                if hasattr(conn, "laddr") and conn.laddr[1] == port)

            if not any(connect_using_port):
                yield Port(port)
Пример #6
0
    def _unused_ports(initial_port: Optional[int]) -> Iterator[Port]:
        socket_kind: SocketKind = SocketKind.SOCK_STREAM

        if not initial_port:
            next_port = repeat(0)
        else:
            next_port = count(start=initial_port)

        for port_candidate in next_port:
            # Don't inline the variable until
            # https://github.com/PyCQA/pylint/issues/1437 is fixed
            sock = socket.socket(socket.AF_INET, socket_kind)
            with closing(sock):
                # Force the port into TIME_WAIT mode, ensuring that it will not
                # be considered 'free' by the OS for the next 60 seconds. This
                # does however require that the process using the port sets
                # SO_REUSEADDR on it's sockets. Most 'server' applications do.
                sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
                try:
                    sock.bind((LOOPBACK, port_candidate))
                except OSError as ex:
                    if ex.errno == errno.EADDRINUSE:
                        continue
                    raise

                sock_addr = sock.getsockname()
                port = sock_addr[1]

                # Connect to the socket to force it into TIME_WAIT state (see
                # above)
                sock.listen(1)
                sock2 = socket.socket(socket.AF_INET, socket_kind)
                with closing(sock2):
                    sock2.connect(sock_addr)
                    sock.accept()

            yield Port(port)
Пример #7
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_
Пример #8
0
    List,
    NetworkTimeout,
    Optional,
    Port,
    ProportionalFeeAmount,
    TokenAddress,
    TokenAmount,
)
from raiden_contracts.contract_manager import contracts_precompiled_path

CACHE_TTL = 60
GAS_LIMIT = 10 * 10**6
GAS_LIMIT_HEX = to_hex(GAS_LIMIT)
GAS_PRICE = denoms.shannon * 20  # pylint: disable=no-member

DEFAULT_HTTP_SERVER_PORT = Port(5001)

DEFAULT_TRANSPORT_RETRIES_BEFORE_BACKOFF = 1
DEFAULT_TRANSPORT_MATRIX_RETRY_INTERVAL_INITIAL = 5.0
DEFAULT_TRANSPORT_MATRIX_RETRY_INTERVAL_MAX = 60.0
DEFAULT_TRANSPORT_MATRIX_SYNC_TIMEOUT = 60_000
# Maximum allowed time between syncs in addition to DEFAULT_TRANSPORT_MATRIX_SYNC_TIMEOUT.
# This is necessary because
# - The matrix server adds up to 10% to avoid thundering herds
# - Network latency
# - The Raiden node might not be able to process the messages immediately
DEFAULT_TRANSPORT_MATRIX_SYNC_LATENCY = 15_000
DEFAULT_MATRIX_KNOWN_SERVERS = {
    Environment.PRODUCTION:
    ("https://raw.githubusercontent.com/raiden-network/raiden-service-bundle"
     "/master/known_servers/known_servers-production-v1.2.0.json"),
Пример #9
0
def run_app(
        address: Address,
        keystore_path: str,
        gas_price: Callable,
        eth_rpc_endpoint: str,
        tokennetwork_registry_contract_address: TokenNetworkRegistryAddress,
        one_to_n_contract_address: Address,
        secret_registry_contract_address: Address,
        service_registry_contract_address: Address,
        user_deposit_contract_address: Address,
        monitoring_service_contract_address: Address,
        api_address: Endpoint,
        rpc: bool,
        sync_check: bool,
        console: bool,
        password_file: TextIO,
        web_ui: bool,
        datadir: str,
        transport: str,
        matrix_server: str,
        network_id: ChainID,
        environment_type: Environment,
        unrecoverable_error_should_crash: bool,
        pathfinding_service_address: str,
        pathfinding_max_paths: int,
        enable_monitoring: bool,
        resolver_endpoint: str,
        routing_mode: RoutingMode,
        config: Dict[str, Any],
        flat_fee: Tuple[Tuple[TokenAddress, FeeAmount], ...],
        proportional_fee: Tuple[Tuple[TokenAddress, ProportionalFeeAmount],
                                ...],
        proportional_imbalance_fee: Tuple[Tuple[TokenAddress,
                                                ProportionalFeeAmount], ...],
        blockchain_query_interval: float,
        cap_mediation_fees: bool,
        **
    kwargs: Any,  # FIXME: not used here, but still receives stuff in smoketest
) -> App:
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    token_network_registry_deployed_at: Optional[BlockNumber]
    smart_contracts_start_at: BlockNumber

    if datadir is None:
        datadir = os.path.join(os.path.expanduser("~"), ".raiden")

    account_manager = AccountManager(keystore_path)
    web3 = Web3(HTTPProvider(rpc_normalized_endpoint(eth_rpc_endpoint)))

    check_sql_version()
    check_ethereum_has_accounts(account_manager)
    check_ethereum_client_is_supported(web3)
    check_ethereum_network_id(network_id, web3)

    address, privatekey = get_account_and_private_key(account_manager, address,
                                                      password_file)

    api_host, api_port = split_endpoint(api_address)

    if not api_port:
        api_port = Port(DEFAULT_HTTP_SERVER_PORT)

    fee_config = prepare_mediation_fee_config(
        cli_token_to_flat_fee=flat_fee,
        cli_token_to_proportional_fee=proportional_fee,
        cli_token_to_proportional_imbalance_fee=proportional_imbalance_fee,
        cli_cap_mediation_fees=cap_mediation_fees,
    )

    config["console"] = console
    config["rpc"] = rpc
    config["web_ui"] = rpc and web_ui
    config["api_host"] = api_host
    config["api_port"] = api_port
    config["resolver_endpoint"] = resolver_endpoint
    config["transport_type"] = transport
    config["transport"]["matrix"]["server"] = matrix_server
    config[
        "unrecoverable_error_should_crash"] = unrecoverable_error_should_crash
    config["services"]["pathfinding_max_paths"] = pathfinding_max_paths
    config["services"]["monitoring_enabled"] = enable_monitoring
    config["chain_id"] = network_id
    config["mediation_fees"] = fee_config
    config["blockchain"]["query_interval"] = blockchain_query_interval

    setup_environment(config, environment_type)

    contracts = setup_contracts_or_exit(config, network_id)

    rpc_client = JSONRPCClient(
        web3=web3,
        privkey=privatekey,
        gas_price_strategy=gas_price,
        block_num_confirmations=DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
    )

    token_network_registry_deployed_at = None
    if "TokenNetworkRegistry" in contracts:
        token_network_registry_deployed_at = BlockNumber(
            contracts["TokenNetworkRegistry"]["block_number"])

    if token_network_registry_deployed_at is None:
        smart_contracts_start_at = get_smart_contracts_start_at(network_id)
    else:
        smart_contracts_start_at = token_network_registry_deployed_at

    proxy_manager = ProxyManager(
        rpc_client=rpc_client,
        contract_manager=ContractManager(config["contracts_path"]),
        metadata=ProxyManagerMetadata(
            token_network_registry_deployed_at=
            token_network_registry_deployed_at,
            filters_start_at=smart_contracts_start_at,
        ),
    )

    if sync_check:
        check_synced(proxy_manager)

    proxies = setup_proxies_or_exit(
        config=config,
        tokennetwork_registry_contract_address=
        tokennetwork_registry_contract_address,
        secret_registry_contract_address=secret_registry_contract_address,
        user_deposit_contract_address=user_deposit_contract_address,
        service_registry_contract_address=service_registry_contract_address,
        proxy_manager=proxy_manager,
        contracts=contracts,
        routing_mode=routing_mode,
        pathfinding_service_address=pathfinding_service_address,
    )

    check_ethereum_confirmed_block_is_not_pruned(
        jsonrpc_client=rpc_client,
        secret_registry=proxies.secret_registry,
        confirmation_blocks=config["blockchain"]["confirmation_blocks"],
    )

    database_path = os.path.join(
        datadir,
        f"node_{pex(address)}",
        f"netid_{network_id}",
        f"network_{pex(proxies.token_network_registry.address)}",
        f"v{RAIDEN_DB_VERSION}_log.db",
    )
    config["database_path"] = database_path

    print("\nYou are connected to the '{}' network and the DB path is: {}".
          format(ID_TO_NETWORKNAME.get(network_id, network_id), database_path))

    if transport == "matrix":
        matrix_transport = _setup_matrix(config, routing_mode)
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    event_handler: EventHandler = RaidenEventHandler()

    # User should be told how to set fees, if using default fee settings
    log.debug("Fee Settings", fee_settings=fee_config)
    has_default_fees = (len(fee_config.token_to_flat_fee) == 0
                        and len(fee_config.token_to_proportional_fee) == 0
                        and len(fee_config.token_to_proportional_imbalance_fee)
                        == 0)
    if has_default_fees:
        click.secho(
            "Default fee settings are used. "
            "If you want use Raiden with mediation fees - flat, proportional and imbalance fees - "
            "see https://raiden-network.readthedocs.io/en/latest/overview_and_guide.html#firing-it-up",  # noqa: E501
            fg="yellow",
        )

    monitoring_contract_required = (enable_monitoring
                                    and CONTRACT_MONITORING_SERVICE
                                    not in contracts)
    if monitoring_contract_required:
        click.secho(
            "Monitoring is enabled but the contract for this ethereum network was not found. "
            "Please provide monitoring service contract address using "
            "--monitoring-service-address.",
            fg="red",
        )
        sys.exit(1)

    # Only send feedback when PFS is used
    if routing_mode == RoutingMode.PFS:
        event_handler = PFSFeedbackEventHandler(event_handler)

    message_handler = MessageHandler()

    try:
        raiden_app = App(
            config=config,
            rpc_client=rpc_client,
            proxy_manager=proxy_manager,
            query_start_block=smart_contracts_start_at,
            default_one_to_n_address=(one_to_n_contract_address or
                                      contracts[CONTRACT_ONE_TO_N]["address"]),
            default_registry=proxies.token_network_registry,
            default_secret_registry=proxies.secret_registry,
            default_service_registry=proxies.service_registry,
            default_msc_address=(
                monitoring_service_contract_address
                or contracts[CONTRACT_MONITORING_SERVICE]["address"]),
            transport=matrix_transport,
            raiden_event_handler=event_handler,
            message_handler=message_handler,
            routing_mode=routing_mode,
            user_deposit=proxies.user_deposit,
        )
    except RaidenError as e:
        click.secho(f"FATAL: {e}", fg="red")
        sys.exit(1)

    try:
        raiden_app.start()
    except RuntimeError as e:
        click.secho(f"FATAL: {e}", fg="red")
        sys.exit(1)
    except filelock.Timeout:
        name_or_id = ID_TO_NETWORKNAME.get(network_id, network_id)
        click.secho(
            f"FATAL: Another Raiden instance already running for account "
            f"{to_checksum_address(address)} on network id {name_or_id}",
            fg="red",
        )
        sys.exit(1)

    return raiden_app
Пример #10
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()
Пример #11
0
def run_app(
        address: Address,
        keystore_path: str,
        gas_price: Callable,
        eth_rpc_endpoint: str,
        user_deposit_contract_address: Optional[UserDepositAddress],
        api_address: Endpoint,
        rpc: bool,
        sync_check: bool,
        console: bool,
        password_file: TextIO,
        web_ui: bool,
        datadir: str,
        transport: str,
        matrix_server: str,
        network_id: ChainID,
        environment_type: Environment,
        unrecoverable_error_should_crash: bool,
        pathfinding_service_address: str,
        pathfinding_max_paths: int,
        enable_monitoring: bool,
        resolver_endpoint: str,
        default_reveal_timeout: BlockTimeout,
        default_settle_timeout: BlockTimeout,
        routing_mode: RoutingMode,
        flat_fee: Tuple[Tuple[TokenAddress, FeeAmount], ...],
        proportional_fee: Tuple[Tuple[TokenAddress, ProportionalFeeAmount],
                                ...],
        proportional_imbalance_fee: Tuple[Tuple[TokenAddress,
                                                ProportionalFeeAmount], ...],
        blockchain_query_interval: float,
        cap_mediation_fees: bool,
        **
    kwargs: Any,  # FIXME: not used here, but still receives stuff in smoketest
) -> App:
    # pylint: disable=too-many-locals,too-many-branches,too-many-statements,unused-argument

    token_network_registry_deployed_at: Optional[BlockNumber]
    smart_contracts_start_at: BlockNumber

    if datadir is None:
        datadir = os.path.join(os.path.expanduser("~"), ".raiden")

    account_manager = AccountManager(keystore_path)
    web3 = Web3(HTTPProvider(rpc_normalized_endpoint(eth_rpc_endpoint)))

    check_sql_version()
    check_ethereum_has_accounts(account_manager)
    check_ethereum_client_is_supported(web3)
    check_ethereum_network_id(network_id, web3)

    address, privatekey = get_account_and_private_key(account_manager, address,
                                                      password_file)

    api_host, api_port = split_endpoint(api_address)

    if not api_port:
        api_port = Port(DEFAULT_HTTP_SERVER_PORT)

    fee_config = prepare_mediation_fee_config(
        cli_token_to_flat_fee=flat_fee,
        cli_token_to_proportional_fee=proportional_fee,
        cli_token_to_proportional_imbalance_fee=proportional_imbalance_fee,
        cli_cap_mediation_fees=cap_mediation_fees,
    )

    config = RaidenConfig(chain_id=network_id,
                          environment_type=environment_type)
    config.console = console
    config.rpc = rpc
    config.web_ui = rpc and web_ui

    config.blockchain.query_interval = blockchain_query_interval

    config.mediation_fees = fee_config

    config.services.monitoring_enabled = enable_monitoring
    config.services.pathfinding_max_paths = pathfinding_max_paths

    config.transport_type = transport
    config.transport.server = matrix_server

    config.unrecoverable_error_should_crash = unrecoverable_error_should_crash

    config.api_host = api_host
    config.api_port = api_port
    config.resolver_endpoint = resolver_endpoint

    config.reveal_timeout = default_reveal_timeout
    config.settle_timeout = default_settle_timeout

    contracts = load_deployed_contracts_data(config, network_id)

    rpc_client = JSONRPCClient(
        web3=web3,
        privkey=privatekey,
        gas_price_strategy=gas_price,
        block_num_confirmations=DEFAULT_NUMBER_OF_BLOCK_CONFIRMATIONS,
    )

    token_network_registry_deployed_at = None
    if "TokenNetworkRegistry" in contracts:
        token_network_registry_deployed_at = BlockNumber(
            contracts["TokenNetworkRegistry"]["block_number"])

    if token_network_registry_deployed_at is None:
        smart_contracts_start_at = get_smart_contracts_start_at(network_id)
    else:
        smart_contracts_start_at = token_network_registry_deployed_at

    proxy_manager = ProxyManager(
        rpc_client=rpc_client,
        contract_manager=ContractManager(config.contracts_path),
        metadata=ProxyManagerMetadata(
            token_network_registry_deployed_at=
            token_network_registry_deployed_at,
            filters_start_at=smart_contracts_start_at,
        ),
    )

    if sync_check:
        check_synced(rpc_client)

    # The user has the option to launch Raiden with a custom
    # user deposit contract address. This can be used to load
    # the addresses for the rest of the deployed contracts.
    # The steps done here make sure that if a UDC address is provided,
    # the address has to be valid and all the connected contracts
    # are configured properly.
    # If a UDC address was not provided, Raiden would fall back
    # to using the ones deployed and provided by the raiden-contracts package.
    if user_deposit_contract_address is not None:
        if not is_address(user_deposit_contract_address):
            raise RaidenError("The user deposit address is invalid")

        deployed_addresses = load_deployment_addresses_from_udc(
            proxy_manager=proxy_manager,
            user_deposit_address=user_deposit_contract_address,
            block_identifier="latest",
        )
    else:
        deployed_addresses = load_deployment_addresses_from_contracts(
            contracts=contracts)

    raiden_bundle = raiden_bundle_from_contracts_deployment(
        proxy_manager=proxy_manager,
        token_network_registry_address=deployed_addresses.
        token_network_registry_address,
        secret_registry_address=deployed_addresses.secret_registry_address,
    )

    services_bundle = services_bundle_from_contracts_deployment(
        config=config,
        deployed_addresses=deployed_addresses,
        proxy_manager=proxy_manager,
        routing_mode=routing_mode,
        pathfinding_service_address=pathfinding_service_address,
        enable_monitoring=enable_monitoring,
    )

    check_ethereum_confirmed_block_is_not_pruned(
        jsonrpc_client=rpc_client,
        secret_registry=raiden_bundle.secret_registry,
        confirmation_blocks=config.blockchain.confirmation_blocks,
    )

    database_path = Path(
        os.path.join(
            datadir,
            f"node_{pex(address)}",
            f"netid_{network_id}",
            f"network_{pex(raiden_bundle.token_network_registry.address)}",
            f"v{RAIDEN_DB_VERSION}_log.db",
        ))
    config.database_path = database_path

    print(f"Raiden is running in {environment_type.value.lower()} mode")
    print("\nYou are connected to the '{}' network and the DB path is: {}".
          format(ID_TO_NETWORKNAME.get(network_id, network_id), database_path))

    if transport == "matrix":
        matrix_transport = setup_matrix(config.transport, config.services,
                                        environment_type, routing_mode)
    else:
        raise RuntimeError(f'Unknown transport type "{transport}" given')

    event_handler: EventHandler = RaidenEventHandler()

    # User should be told how to set fees, if using default fee settings
    log.debug("Fee Settings", fee_settings=fee_config)
    has_default_fees = (len(fee_config.token_to_flat_fee) == 0
                        and len(fee_config.token_to_proportional_fee) == 0
                        and len(fee_config.token_to_proportional_imbalance_fee)
                        == 0)
    if has_default_fees:
        click.secho(
            "Default fee settings are used. "
            "If you want use Raiden with mediation fees - flat, proportional and imbalance fees - "
            "see https://raiden-network.readthedocs.io/en/latest/overview_and_guide.html#firing-it-up",  # noqa: E501
            fg="yellow",
        )

    # Only send feedback when PFS is used
    if routing_mode == RoutingMode.PFS:
        event_handler = PFSFeedbackEventHandler(event_handler)

    message_handler = MessageHandler()

    one_to_n_address = (services_bundle.one_to_n.address
                        if services_bundle.one_to_n is not None else None)
    monitoring_service_address = (services_bundle.monitoring_service.address
                                  if services_bundle.monitoring_service
                                  is not None else None)
    raiden_app = App(
        config=config,
        rpc_client=rpc_client,
        proxy_manager=proxy_manager,
        query_start_block=smart_contracts_start_at,
        default_registry=raiden_bundle.token_network_registry,
        default_secret_registry=raiden_bundle.secret_registry,
        default_one_to_n_address=one_to_n_address,
        default_service_registry=services_bundle.service_registry,
        default_msc_address=monitoring_service_address,
        transport=matrix_transport,
        raiden_event_handler=event_handler,
        message_handler=message_handler,
        routing_mode=routing_mode,
        user_deposit=services_bundle.user_deposit,
    )

    raiden_app.start()

    return raiden_app