def run(*args):
    TESTNET = args[0]
    LOGLEVEL = args[1]
    PORT = args[2]
    ALLOWIP = args[3]
    RESTPORT = args[4]
    WSPORT = args[5]
    HEARTBEATPORT = args[6]

    def start_server(keys, first_startup=False):
        # logging
        logFile = logfile.LogFile.fromFullPath(os.path.join(
            DATA_FOLDER, "debug.log"),
                                               rotateLength=15000000,
                                               maxRotatedFiles=1)
        log.addObserver(FileLogObserver(logFile, level=LOGLEVEL).emit)
        log.addObserver(FileLogObserver(level=LOGLEVEL).emit)
        logger = Logger(system="OpenBazaard")

        # NAT traversal
        p = PortMapper()
        p.add_port_mapping(PORT, PORT, "UDP")
        logger.info("Finding NAT Type...")

        response = looping_retry(stun.get_ip_info, "0.0.0.0", PORT)

        logger.info("%s on %s:%s" % (response[0], response[1], response[2]))
        ip_address = response[1]
        port = response[2]

        if response[0] == "Full Cone":
            nat_type = FULL_CONE
        elif response[0] == "Restric NAT":
            nat_type = RESTRICTED
        else:
            nat_type = SYMMETRIC

        def on_bootstrap_complete(resp):
            logger.info("bootstrap complete")
            task.LoopingCall(mserver.get_messages, mlistener).start(3600)
            task.LoopingCall(check_unfunded_for_payment, db, libbitcoin_client,
                             nlistener, TESTNET).start(600)
            task.LoopingCall(rebroadcast_unconfirmed, db, libbitcoin_client,
                             TESTNET).start(600)

        protocol = OpenBazaarProtocol(
            db, (ip_address, port),
            nat_type,
            testnet=TESTNET,
            relaying=True if nat_type == FULL_CONE else False)

        # kademlia
        SEED_URLS = SEEDS_TESTNET if TESTNET else SEEDS
        relay_node = None
        if nat_type != FULL_CONE:
            for seed in SEED_URLS:
                try:
                    relay_node = (socket.gethostbyname(seed[0].split(":")[0]),
                                  28469 if TESTNET else 18469)
                    break
                except socket.gaierror:
                    pass

        try:
            kserver = Server.loadState(
                os.path.join(DATA_FOLDER,
                             'cache.pickle'), ip_address, port, protocol, db,
                nat_type, relay_node, on_bootstrap_complete, storage)
        except Exception:
            node = Node(keys.guid, ip_address, port, keys.verify_key.encode(),
                        relay_node, nat_type,
                        Profile(db).get().vendor)
            protocol.relay_node = node.relay_node
            kserver = Server(node,
                             db,
                             keys.signing_key,
                             KSIZE,
                             ALPHA,
                             storage=storage)
            kserver.protocol.connect_multiplexer(protocol)
            kserver.bootstrap(kserver.querySeed(SEED_URLS)).addCallback(
                on_bootstrap_complete)
        kserver.saveStateRegularly(os.path.join(DATA_FOLDER, 'cache.pickle'),
                                   10)
        protocol.register_processor(kserver.protocol)

        # market
        mserver = network.Server(kserver, keys.signing_key, db)
        mserver.protocol.connect_multiplexer(protocol)
        protocol.register_processor(mserver.protocol)

        looping_retry(reactor.listenUDP, port, protocol)

        interface = "0.0.0.0" if ALLOWIP != ["127.0.0.1"] else "127.0.0.1"

        # websockets api
        authenticated_sessions = []
        ws_api = WSFactory(mserver, kserver, only_ip=ALLOWIP)
        ws_factory = AuthenticatedWebSocketFactory(ws_api)
        ws_factory.authenticated_sessions = authenticated_sessions
        ws_factory.protocol = AuthenticatedWebSocketProtocol
        if SSL:
            reactor.listenSSL(WSPORT,
                              ws_factory,
                              ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT),
                              interface=interface)
        else:
            reactor.listenTCP(WSPORT, ws_factory, interface=interface)

        # rest api
        rest_api = RestAPI(mserver,
                           kserver,
                           protocol,
                           username,
                           password,
                           authenticated_sessions,
                           only_ip=ALLOWIP)
        if SSL:
            reactor.listenSSL(RESTPORT,
                              rest_api,
                              ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT),
                              interface=interface)
        else:
            reactor.listenTCP(RESTPORT, rest_api, interface=interface)

        # blockchain
        if TESTNET:
            libbitcoin_client = LibbitcoinClient(
                LIBBITCOIN_SERVERS_TESTNET,
                log=Logger(service="LibbitcoinClient"))
        else:
            libbitcoin_client = LibbitcoinClient(
                LIBBITCOIN_SERVERS, log=Logger(service="LibbitcoinClient"))
        heartbeat_server.libbitcoin = libbitcoin_client

        # listeners
        nlistener = NotificationListenerImpl(ws_api, db)
        mserver.protocol.add_listener(nlistener)
        mlistener = MessageListenerImpl(ws_api, db)
        mserver.protocol.add_listener(mlistener)
        blistener = BroadcastListenerImpl(ws_api, db)
        mserver.protocol.add_listener(blistener)

        protocol.set_servers(ws_api, libbitcoin_client)

        if first_startup:
            heartbeat_server.push(
                json.dumps({
                    "status": "GUID generation complete",
                    "username": username,
                    "password": password
                }))

        heartbeat_server.set_status("online")

        logger.info("startup took %s seconds" %
                    str(round(time.time() - args[7], 2)))

        def shutdown():
            logger.info("shutting down server")
            for vendor in protocol.vendors.values():
                db.vendors.save_vendor(vendor.id.encode("hex"),
                                       vendor.getProto().SerializeToString())
            PortMapper().clean_my_mappings(PORT)
            protocol.shutdown()

        reactor.addSystemEventTrigger('before', 'shutdown', shutdown)

    # database
    db = Database(TESTNET)
    storage = ForgetfulStorage()

    # client authentication
    username, password = get_credentials(db)

    # heartbeat server
    interface = "0.0.0.0" if ALLOWIP != ["127.0.0.1"] else "127.0.0.1"

    heartbeat_server = HeartbeatFactory(only_ip=ALLOWIP)
    if SSL:
        reactor.listenSSL(HEARTBEATPORT,
                          WebSocketFactory(heartbeat_server),
                          ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT),
                          interface=interface)
    else:
        reactor.listenTCP(HEARTBEATPORT,
                          WebSocketFactory(heartbeat_server),
                          interface=interface)

    btcPrice = BtcPrice()
    btcPrice.start()

    # key generation
    KeyChain(db, start_server, heartbeat_server)

    reactor.run()

    btcPrice.closethread()
    btcPrice.join(1)
Exemplo n.º 2
0
def run(*args):
    TESTNET = args[0]
    LOGLEVEL = args[1]
    PORT = args[2]
    ALLOWIP = args[3]
    RESTPORT = args[4]
    WSPORT = args[5]
    HEARTBEATPORT = args[6]

    def start_server(keys, first_startup=False):
        # logging
        logFile = logfile.LogFile.fromFullPath(DATA_FOLDER + "debug.log", rotateLength=15000000, maxRotatedFiles=1)
        log.addObserver(FileLogObserver(logFile, level=LOGLEVEL).emit)
        log.addObserver(FileLogObserver(level=LOGLEVEL).emit)
        logger = Logger(system="OpenBazaard")

        # NAT traversal
        p = PortMapper()
        p.add_port_mapping(PORT, PORT, "UDP")
        logger.info("Finding NAT Type...")

        response = looping_retry(stun.get_ip_info, "0.0.0.0", PORT)

        logger.info("%s on %s:%s" % (response[0], response[1], response[2]))
        ip_address = response[1]
        port = response[2]

        if response[0] == "Full Cone":
            nat_type = FULL_CONE
        elif response[0] == "Restric NAT":
            nat_type = RESTRICTED
        else:
            nat_type = SYMMETRIC

        def on_bootstrap_complete(resp):
            logger.info("bootstrap complete")
            task.LoopingCall(mserver.get_messages, mlistener).start(3600)
            task.LoopingCall(check_unfunded_for_payment, db, libbitcoin_client, nlistener, TESTNET).start(600)

        protocol = OpenBazaarProtocol(db, (ip_address, port), nat_type, testnet=TESTNET,
                                      relaying=True if nat_type == FULL_CONE else False)

        # kademlia
        storage = ForgetfulStorage() if TESTNET else PersistentStorage(db.get_database_path())
        relay_node = None
        if nat_type != FULL_CONE:
            for seed in SEEDS:
                try:
                    relay_node = (socket.gethostbyname(seed[0].split(":")[0]),
                                  28469 if TESTNET else 18469)
                    break
                except socket.gaierror:
                    pass

        try:
            kserver = Server.loadState(DATA_FOLDER + 'cache.pickle', ip_address, port, protocol, db,
                                       nat_type, relay_node, on_bootstrap_complete, storage)
        except Exception:
            node = Node(keys.guid, ip_address, port, keys.verify_key.encode(),
                        relay_node, nat_type, Profile(db).get().vendor)
            protocol.relay_node = node.relay_node
            kserver = Server(node, db, keys.signing_key, KSIZE, ALPHA, storage=storage)
            kserver.protocol.connect_multiplexer(protocol)
            kserver.bootstrap(kserver.querySeed(SEEDS)).addCallback(on_bootstrap_complete)
        kserver.saveStateRegularly(DATA_FOLDER + 'cache.pickle', 10)
        protocol.register_processor(kserver.protocol)

        # market
        mserver = network.Server(kserver, keys.signing_key, db)
        mserver.protocol.connect_multiplexer(protocol)
        protocol.register_processor(mserver.protocol)

        looping_retry(reactor.listenUDP, port, protocol)

        interface = "0.0.0.0" if ALLOWIP not in ("127.0.0.1", "0.0.0.0") else ALLOWIP

        # websockets api
        authenticated_sessions = []
        ws_api = WSFactory(mserver, kserver, only_ip=ALLOWIP)
        ws_factory = AuthenticatedWebSocketFactory(ws_api)
        ws_factory.authenticated_sessions = authenticated_sessions
        ws_factory.protocol = AuthenticatedWebSocketProtocol
        if SSL:
            reactor.listenSSL(WSPORT, ws_factory,
                              ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT), interface=interface)
        else:
            reactor.listenTCP(WSPORT, ws_factory, interface=interface)

        # rest api
        rest_api = RestAPI(mserver, kserver, protocol, username, password,
                           authenticated_sessions, only_ip=ALLOWIP)
        if SSL:
            reactor.listenSSL(RESTPORT, rest_api,
                              ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT), interface=interface)
        else:
            reactor.listenTCP(RESTPORT, rest_api, interface=interface)

        # blockchain
        if TESTNET:
            libbitcoin_client = LibbitcoinClient(LIBBITCOIN_SERVER_TESTNET, log=Logger(service="LibbitcoinClient"))
        else:
            libbitcoin_client = LibbitcoinClient(LIBBITCOIN_SERVER, log=Logger(service="LibbitcoinClient"))
        heartbeat_server.libbitcoin = libbitcoin_client

        # listeners
        nlistener = NotificationListenerImpl(ws_api, db)
        mserver.protocol.add_listener(nlistener)
        mlistener = MessageListenerImpl(ws_api, db)
        mserver.protocol.add_listener(mlistener)
        blistener = BroadcastListenerImpl(ws_api, db)
        mserver.protocol.add_listener(blistener)

        protocol.set_servers(ws_api, libbitcoin_client)

        if first_startup:
            heartbeat_server.push(json.dumps({
                "status": "GUID generation complete",
                "username": username,
                "password": password
            }))

        heartbeat_server.set_status("online")

        logger.info("Startup took %s seconds" % str(round(time.time() - args[7], 2)))

    # database
    db = Database(TESTNET)

    # client authentication
    username, password = get_credentials(db)

    # heartbeat server
    interface = "0.0.0.0" if ALLOWIP not in ("127.0.0.1", "0.0.0.0") else ALLOWIP
    heartbeat_server = HeartbeatFactory(only_ip=ALLOWIP)
    if SSL:
        reactor.listenSSL(HEARTBEATPORT, WebSocketFactory(heartbeat_server),
                          ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT), interface=interface)
    else:
        reactor.listenTCP(HEARTBEATPORT, WebSocketFactory(heartbeat_server), interface=interface)

    # key generation
    KeyChain(db, start_server, heartbeat_server)

    reactor.run()