Esempio n. 1
0
def main_entry(trinity_boot: BootFn, plugins: Iterable[BasePlugin],
               sub_configs: Iterable[Type[BaseAppConfig]]) -> None:
    event_bus = EventBus(ctx)
    main_endpoint = event_bus.create_endpoint(MAIN_EVENTBUS_ENDPOINT)
    main_endpoint.connect_no_wait()

    plugin_manager = setup_plugins(
        MainAndIsolatedProcessScope(event_bus, main_endpoint), plugins)
    plugin_manager.amend_argparser_config(parser, subparser)
    args = parser.parse_args()

    if args.network_id not in PRECONFIGURED_NETWORKS:
        raise NotImplementedError(
            f"Unsupported network id: {args.network_id}.  Only the ropsten and mainnet "
            "networks are supported.")

    has_ambigous_logging_config = (args.log_levels is not None
                                   and None in args.log_levels
                                   and args.stderr_log_level is not None)
    if has_ambigous_logging_config:
        parser.error(
            "\n"
            "Ambiguous logging configuration: The logging level for stderr was "
            "configured with both `--stderr-log-level` and `--log-level`. "
            "Please remove one of these flags", )

    if is_prerelease():
        # this modifies the asyncio logger, but will be overridden by any custom settings below
        enable_warnings_by_default()

    stderr_logger, formatter, handler_stream = setup_trinity_stderr_logging(
        args.stderr_log_level
        or (args.log_levels and args.log_levels.get(None)))

    if args.log_levels:
        setup_log_levels(args.log_levels)

    try:
        trinity_config = TrinityConfig.from_parser_args(args, sub_configs)
    except AmbigiousFileSystem:
        parser.error(TRINITY_AMBIGIOUS_FILESYSTEM_INFO)

    if not is_data_dir_initialized(trinity_config):
        # TODO: this will only work as is for chains with known genesis
        # parameters.  Need to flesh out how genesis parameters for custom
        # chains are defined and passed around.
        try:
            initialize_data_dir(trinity_config)
        except AmbigiousFileSystem:
            parser.error(TRINITY_AMBIGIOUS_FILESYSTEM_INFO)
        except MissingPath as e:
            parser.error(
                "\n"
                f"It appears that {e.path} does not exist. "
                "Trinity does not attempt to create directories outside of its root path. "
                "Either manually create the path or ensure you are using a data directory "
                "inside the XDG_TRINITY_ROOT path")

    file_logger, log_queue, listener = setup_trinity_file_and_queue_logging(
        stderr_logger,
        formatter,
        handler_stream,
        trinity_config.logfile_path,
        args.file_log_level,
    )

    display_launch_logs(trinity_config)

    # compute the minimum configured log level across all configured loggers.
    min_configured_log_level = min(stderr_logger.level, file_logger.level,
                                   *(args.log_levels or {}).values())

    extra_kwargs = {
        'log_queue': log_queue,
        'log_level': min_configured_log_level,
        'profile': args.profile,
    }

    # Plugins can provide a subcommand with a `func` which does then control
    # the entire process from here.
    if hasattr(args, 'func'):
        args.func(args, trinity_config)
    else:
        trinity_boot(
            args,
            trinity_config,
            extra_kwargs,
            plugin_manager,
            listener,
            event_bus,
            main_endpoint,
            stderr_logger,
        )
Esempio n. 2
0
def main_entry(trinity_boot: BootFn, app_identifier: str,
               components: Tuple[Type[BaseComponent], ...],
               sub_configs: Sequence[Type[BaseAppConfig]]) -> None:
    for component_type in components:
        component_type.configure_parser(parser, subparser)

    argcomplete.autocomplete(parser)

    args = parser.parse_args()

    if not args.genesis and args.network_id not in PRECONFIGURED_NETWORKS:
        raise NotImplementedError(
            f"Unsupported network id: {args.network_id}. To use a network besides "
            "mainnet or ropsten, you must supply a genesis file with a flag, like "
            "`--genesis path/to/genesis.json`, also you must specify a data "
            "directory with `--data-dir path/to/data/directory`")

    # The `common_log_level` is derived from `--log-level <Level>` / `-l <Level>` without
    # specifying any module. If present, it is used for both `stderr` and `file` logging.
    common_log_level = args.log_levels and args.log_levels.get(None)
    has_ambigous_logging_config = (
        (common_log_level is not None and args.stderr_log_level is not None)
        or (common_log_level is not None and args.file_log_level is not None))

    if has_ambigous_logging_config:
        parser.error(f"""\n
            Ambiguous logging configuration: The `--log-level (-l)` flag sets the
            log level for both file and stderr logging.
            To configure different log level for file and stderr logging,
            remove the `--log-level` flag and use `--stderr-log-level` and/or
            `--file-log-level` separately.
            Alternatively, remove the `--stderr-log-level` and/or `--file-log-level`
            flags to share one single log level across both handlers.
            """)

    if is_prerelease():
        # this modifies the asyncio logger, but will be overridden by any custom settings below
        enable_warnings_by_default()

    stderr_logger, handler_stream = setup_trinity_stderr_logging(
        args.stderr_log_level or common_log_level)

    if args.log_levels:
        setup_log_levels(args.log_levels)

    try:
        trinity_config = TrinityConfig.from_parser_args(
            args, app_identifier, sub_configs)
    except AmbigiousFileSystem:
        parser.error(TRINITY_AMBIGIOUS_FILESYSTEM_INFO)

    if not is_data_dir_initialized(trinity_config):
        # TODO: this will only work as is for chains with known genesis
        # parameters.  Need to flesh out how genesis parameters for custom
        # chains are defined and passed around.
        try:
            initialize_data_dir(trinity_config)
        except AmbigiousFileSystem:
            parser.error(TRINITY_AMBIGIOUS_FILESYSTEM_INFO)
        except MissingPath as e:
            parser.error(
                "\n"
                f"It appears that {e.path} does not exist. "
                "Trinity does not attempt to create directories outside of its root path. "
                "Either manually create the path or ensure you are using a data directory "
                "inside the XDG_TRINITY_ROOT path")

    file_logger, log_queue, listener = setup_trinity_file_and_queue_logging(
        stderr_logger,
        handler_stream,
        trinity_config.logfile_path,
        args.file_log_level or common_log_level,
    )

    display_launch_logs(trinity_config)

    # compute the minimum configured log level across all configured loggers.
    min_configured_log_level = min(stderr_logger.level, file_logger.level,
                                   *(args.log_levels or {}).values())

    extra_kwargs = {
        'log_queue': log_queue,
        'log_level': min_configured_log_level,
        'log_levels': args.log_levels if args.log_levels else {},
        'profile': args.profile,
    }

    # Components can provide a subcommand with a `func` which does then control
    # the entire process from here.
    if hasattr(args, 'func'):
        args.func(args, trinity_config)
        return

    if hasattr(args, 'munge_func'):
        args.munge_func(args, trinity_config)

    processes = trinity_boot(
        args,
        trinity_config,
        extra_kwargs,
        listener,
        stderr_logger,
    )

    def kill_trinity_with_reason(reason: str) -> None:
        kill_trinity_gracefully(trinity_config,
                                stderr_logger,
                                processes,
                                component_manager_service,
                                reason=reason)

    boot_info = TrinityBootInfo(args, trinity_config, extra_kwargs)
    component_manager_service = ComponentManagerService(
        boot_info, components, kill_trinity_with_reason)

    try:
        loop = asyncio.get_event_loop()
        asyncio.ensure_future(exit_with_services(component_manager_service))
        asyncio.ensure_future(component_manager_service.run())
        loop.add_signal_handler(signal.SIGTERM,
                                lambda: kill_trinity_with_reason("SIGTERM"))
        loop.run_forever()
        loop.close()
    except KeyboardInterrupt:
        kill_trinity_with_reason("CTRL+C / Keyboard Interrupt")
    finally:
        if trinity_config.trinity_tmp_root_dir:
            import shutil
            shutil.rmtree(trinity_config.trinity_root_dir)
Esempio n. 3
0
def main_entry(trinity_boot: BootFn, app_identifier: str,
               plugins: Iterable[Type[BasePlugin]],
               sub_configs: Iterable[Type[BaseAppConfig]]) -> None:

    main_endpoint = TrinityMainEventBusEndpoint()

    plugin_manager = PluginManager(MainAndIsolatedProcessScope(main_endpoint),
                                   plugins)
    plugin_manager.amend_argparser_config(parser, subparser)
    args = parser.parse_args()

    if not args.genesis and args.network_id not in PRECONFIGURED_NETWORKS:
        raise NotImplementedError(
            f"Unsupported network id: {args.network_id}. To use a network besides "
            "mainnet or ropsten, you must supply a genesis file with a flag, like "
            "`--genesis path/to/genesis.json`, also you must specify a data "
            "directory with `--data-dir path/to/data/directory`")

    has_ambigous_logging_config = (args.log_levels is not None
                                   and None in args.log_levels
                                   and args.stderr_log_level is not None)
    if has_ambigous_logging_config:
        parser.error(
            "\n"
            "Ambiguous logging configuration: The logging level for stderr was "
            "configured with both `--stderr-log-level` and `--log-level`. "
            "Please remove one of these flags", )

    if is_prerelease():
        # this modifies the asyncio logger, but will be overridden by any custom settings below
        enable_warnings_by_default()

    stderr_logger, formatter, handler_stream = setup_trinity_stderr_logging(
        args.stderr_log_level
        or (args.log_levels and args.log_levels.get(None)))

    if args.log_levels:
        setup_log_levels(args.log_levels)

    try:
        trinity_config = TrinityConfig.from_parser_args(
            args, app_identifier, sub_configs)
    except AmbigiousFileSystem:
        parser.error(TRINITY_AMBIGIOUS_FILESYSTEM_INFO)

    if not is_data_dir_initialized(trinity_config):
        # TODO: this will only work as is for chains with known genesis
        # parameters.  Need to flesh out how genesis parameters for custom
        # chains are defined and passed around.
        try:
            initialize_data_dir(trinity_config)
        except AmbigiousFileSystem:
            parser.error(TRINITY_AMBIGIOUS_FILESYSTEM_INFO)
        except MissingPath as e:
            parser.error(
                "\n"
                f"It appears that {e.path} does not exist. "
                "Trinity does not attempt to create directories outside of its root path. "
                "Either manually create the path or ensure you are using a data directory "
                "inside the XDG_TRINITY_ROOT path")

    file_logger, log_queue, listener = setup_trinity_file_and_queue_logging(
        stderr_logger,
        formatter,
        handler_stream,
        trinity_config.logfile_path,
        args.file_log_level,
    )

    display_launch_logs(trinity_config)

    # compute the minimum configured log level across all configured loggers.
    min_configured_log_level = min(stderr_logger.level, file_logger.level,
                                   *(args.log_levels or {}).values())

    extra_kwargs = {
        'log_queue': log_queue,
        'log_level': min_configured_log_level,
        'log_levels': args.log_levels if args.log_levels else {},
        'profile': args.profile,
    }

    # Plugins can provide a subcommand with a `func` which does then control
    # the entire process from here.
    if hasattr(args, 'func'):
        args.func(args, trinity_config)
        return

    processes = trinity_boot(
        args,
        trinity_config,
        extra_kwargs,
        plugin_manager,
        listener,
        main_endpoint,
        stderr_logger,
    )

    def kill_trinity_with_reason(reason: str) -> None:
        kill_trinity_gracefully(trinity_config,
                                stderr_logger,
                                processes,
                                plugin_manager,
                                main_endpoint,
                                reason=reason)

    try:
        loop = asyncio.get_event_loop()
        asyncio.ensure_future(
            trinity_boot_coro(
                kill_trinity_with_reason,
                main_endpoint,
                trinity_config,
                plugin_manager,
                args,
                extra_kwargs,
            ))
        loop.add_signal_handler(signal.SIGTERM,
                                lambda: kill_trinity_with_reason("SIGTERM"))
        loop.run_forever()
        loop.close()
    except KeyboardInterrupt:
        kill_trinity_with_reason("CTRL+C / Keyboard Interrupt")