Пример #1
0
def test_setup_logging():
    # Check that setup_logging creates two new logs for every prefix
    prefix = "foo"
    log_file = "var.log"

    f_log_suffix = "_file_log"
    c_log_suffix = "_console_log"

    assert len(logging.getLogger(prefix + f_log_suffix).handlers) is 0
    assert len(logging.getLogger(prefix + c_log_suffix).handlers) is 0

    setup_logging(log_file, prefix)

    assert len(logging.getLogger(prefix + f_log_suffix).handlers) is 1
    assert len(logging.getLogger(prefix + c_log_suffix).handlers) is 1

    os.remove(log_file)
Пример #2
0
def main(command_line_conf):
    global db_manager, chain_monitor

    signal(SIGINT, handle_signals)
    signal(SIGTERM, handle_signals)
    signal(SIGQUIT, handle_signals)

    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()
    setup_data_folder(DATA_DIR)
    setup_logging(config.get("LOG_FILE"), LOG_PREFIX)

    logger.info("Starting TEOS")
    db_manager = DBManager(config.get("DB_PATH"))

    bitcoind_connect_params = {
        k: v
        for k, v in config.items() if k.startswith("BTC")
    }
    bitcoind_feed_params = {
        k: v
        for k, v in config.items() if k.startswith("FEED")
    }

    if not can_connect_to_bitcoind(bitcoind_connect_params):
        logger.error("Can't connect to bitcoind. Shutting down")

    elif not in_correct_network(bitcoind_connect_params,
                                config.get("BTC_NETWORK")):
        logger.error(
            "bitcoind is running on a different network, check conf.py and bitcoin.conf. Shutting down"
        )

    else:
        try:
            secret_key_der = Cryptographer.load_key_file(
                config.get("TEOS_SECRET_KEY"))
            if not secret_key_der:
                raise IOError("TEOS private key can't be loaded")

            block_processor = BlockProcessor(bitcoind_connect_params)
            carrier = Carrier(bitcoind_connect_params)

            responder = Responder(db_manager, carrier, block_processor)
            watcher = Watcher(
                db_manager,
                block_processor,
                responder,
                secret_key_der,
                config.get("MAX_APPOINTMENTS"),
                config.get("EXPIRY_DELTA"),
            )

            # Create the chain monitor and start monitoring the chain
            chain_monitor = ChainMonitor(watcher.block_queue,
                                         watcher.responder.block_queue,
                                         block_processor, bitcoind_feed_params)

            watcher_appointments_data = db_manager.load_watcher_appointments()
            responder_trackers_data = db_manager.load_responder_trackers()

            if len(watcher_appointments_data) == 0 and len(
                    responder_trackers_data) == 0:
                logger.info("Fresh bootstrap")

                watcher.awake()
                watcher.responder.awake()

            else:
                logger.info("Bootstrapping from backed up data")

                # Update the Watcher backed up data if found.
                if len(watcher_appointments_data) != 0:
                    watcher.appointments, watcher.locator_uuid_map = Builder.build_appointments(
                        watcher_appointments_data)

                # Update the Responder with backed up data if found.
                if len(responder_trackers_data) != 0:
                    watcher.responder.trackers, watcher.responder.tx_tracker_map = Builder.build_trackers(
                        responder_trackers_data)

                # Awaking components so the states can be updated.
                watcher.awake()
                watcher.responder.awake()

                last_block_watcher = db_manager.load_last_block_hash_watcher()
                last_block_responder = db_manager.load_last_block_hash_responder(
                )

                # Populate the block queues with data if they've missed some while offline. If the blocks of both match
                # we don't perform the search twice.

                # FIXME: 32-reorgs-offline dropped txs are not used at this point.
                last_common_ancestor_watcher, dropped_txs_watcher = block_processor.find_last_common_ancestor(
                    last_block_watcher)
                missed_blocks_watcher = block_processor.get_missed_blocks(
                    last_common_ancestor_watcher)

                if last_block_watcher == last_block_responder:
                    dropped_txs_responder = dropped_txs_watcher
                    missed_blocks_responder = missed_blocks_watcher

                else:
                    last_common_ancestor_responder, dropped_txs_responder = block_processor.find_last_common_ancestor(
                        last_block_responder)
                    missed_blocks_responder = block_processor.get_missed_blocks(
                        last_common_ancestor_responder)

                # If only one of the instances needs to be updated, it can be done separately.
                if len(missed_blocks_watcher
                       ) == 0 and len(missed_blocks_responder) != 0:
                    Builder.populate_block_queue(watcher.responder.block_queue,
                                                 missed_blocks_responder)
                    watcher.responder.block_queue.join()

                elif len(missed_blocks_responder
                         ) == 0 and len(missed_blocks_watcher) != 0:
                    Builder.populate_block_queue(watcher.block_queue,
                                                 missed_blocks_watcher)
                    watcher.block_queue.join()

                # Otherwise they need to be updated at the same time, block by block
                elif len(missed_blocks_responder) != 0 and len(
                        missed_blocks_watcher) != 0:
                    Builder.update_states(watcher, missed_blocks_watcher,
                                          missed_blocks_responder)

            # Fire the API and the ChainMonitor
            # FIXME: 92-block-data-during-bootstrap-db
            chain_monitor.monitor_chain()
            API(Inspector(block_processor, config.get("MIN_TO_SELF_DELAY")),
                watcher).start()
        except Exception as e:
            logger.error("An error occurred: {}. Shutting down".format(e))
            exit(1)
Пример #3
0
def main(command, args, command_line_conf):
    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()

    setup_data_folder(DATA_DIR)
    setup_logging(config.get("LOG_FILE"), LOG_PREFIX)

    # Set the teos url
    teos_url = "{}:{}".format(config.get("API_CONNECT"),
                              config.get("API_PORT"))
    # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http.
    if not teos_url.startswith("http"):
        teos_url = "http://" + teos_url

    try:
        teos_id, user_sk, user_id = load_keys(config.get("TEOS_PUBLIC_KEY"),
                                              config.get("CLI_PRIVATE_KEY"))

        if command == "register":
            register_data = register(user_id, teos_url)
            logger.info("Registration succeeded. Available slots: {}".format(
                register_data.get("available_slots")))

        if command == "add_appointment":
            appointment_data = parse_add_appointment_args(args)
            appointment, signature = add_appointment(appointment_data, user_sk,
                                                     teos_id, teos_url)
            save_appointment_receipt(appointment.to_dict(), signature,
                                     config.get("APPOINTMENTS_FOLDER_NAME"))

        elif command == "get_appointment":
            if not args:
                logger.error("No arguments were given")

            else:
                arg_opt = args.pop(0)

                if arg_opt in ["-h", "--help"]:
                    sys.exit(help_get_appointment())

                appointment_data = get_appointment(arg_opt, user_sk, teos_id,
                                                   teos_url)
                if appointment_data:
                    print(appointment_data)

        elif command == "get_all_appointments":
            appointment_data = get_all_appointments(teos_url)
            if appointment_data:
                print(appointment_data)

        elif command == "help":
            if args:
                command = args.pop(0)

                if command == "register":
                    sys.exit(help_register())

                if command == "add_appointment":
                    sys.exit(help_add_appointment())

                elif command == "get_appointment":
                    sys.exit(help_get_appointment())

                elif command == "get_all_appointments":
                    sys.exit(help_get_all_appointments())

                else:
                    logger.error(
                        "Unknown command. Use help to check the list of available commands"
                    )

            else:
                sys.exit(show_usage())

    except (FileNotFoundError, IOError, ConnectionError, ValueError) as e:
        logger.error(str(e))
    except (InvalidKey, InvalidParameter, TowerResponseError,
            SignatureError) as e:
        logger.error(e.msg, **e.kwargs)
    except Exception as e:
        logger.error("Unknown error occurred", error=str(e))
Пример #4
0
def main(args, command_line_conf):
    # Loads config and sets up the data folder and log file
    config_loader = ConfigLoader(DATA_DIR, CONF_FILE_NAME, DEFAULT_CONF,
                                 command_line_conf)
    config = config_loader.build_config()

    setup_data_folder(DATA_DIR)
    setup_logging(config.get("LOG_FILE"), LOG_PREFIX)

    # Set the teos url
    teos_url = "{}:{}".format(config.get("TEOS_SERVER"),
                              config.get("TEOS_PORT"))
    # If an http or https prefix if found, leaves the server as is. Otherwise defaults to http.
    if not teos_url.startswith("http"):
        teos_url = "http://" + teos_url

    try:
        if args:
            command = args.pop(0)

            if command in commands:
                if command == "add_appointment":
                    add_appointment(args, teos_url, config)

                elif command == "get_appointment":
                    if not args:
                        logger.error("No arguments were given")

                    else:
                        arg_opt = args.pop(0)

                        if arg_opt in ["-h", "--help"]:
                            sys.exit(help_get_appointment())

                        get_appointment_endpoint = "{}/get_appointment".format(
                            teos_url)
                        appointment_data = get_appointment(
                            arg_opt, get_appointment_endpoint)
                        if appointment_data:
                            print(appointment_data)

                elif command == "help":
                    if args:
                        command = args.pop(0)

                        if command == "add_appointment":
                            sys.exit(help_add_appointment())

                        elif command == "get_appointment":
                            sys.exit(help_get_appointment())

                        else:
                            logger.error(
                                "Unknown command. Use help to check the list of available commands"
                            )

                    else:
                        sys.exit(show_usage())

            else:
                logger.error(
                    "Unknown command. Use help to check the list of available commands"
                )

        else:
            logger.error(
                "No command provided. Use help to check the list of available commands"
            )

    except json.JSONDecodeError:
        logger.error("Non-JSON encoded appointment passed as parameter")