def run(*args): TESTNET = args[0] LOGLEVEL = args[1] PORT = args[2] ALLOWIP = args[3] SSL = args[4] RESTPORT = args[5] WSPORT = args[6] # database db = Database(TESTNET) # key generation keys = KeyChain(db) # 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") mserver.get_messages(mlistener) task.LoopingCall(check_unfunded_for_payment, db, libbitcoin_client, nlistener, TESTNET).start(600) protocol = OpenBazaarProtocol( (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 ws_api = WSFactory(mserver, kserver, only_ip=ALLOWIP) if SSL: reactor.listenSSL(WSPORT, WebSocketFactory(ws_api), ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT), interface=interface) else: reactor.listenTCP(WSPORT, WebSocketFactory(ws_api), interface=interface) # rest api rest_api = RestAPI(mserver, kserver, protocol, 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")) # 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) logger.info("Startup took %s seconds" % str(round(time.time() - args[7], 2))) reactor.run()
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)
def run(*args): TESTNET = args[0] LOGLEVEL = args[1] PORT = args[2] ALLOWIP = args[3] SSL = args[4] RESTPORT = args[5] WSPORT = args[6] # database db = Database(TESTNET) # key generation keys = KeyChain(db) # 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() threading.Thread(target=p.add_port_mapping, args=(PORT, PORT, "UDP")).start() logger.info("Finding NAT Type...") while True: # sometimes the stun server returns a code the client # doesn't understand so we have to try again try: response = stun.get_ip_info(source_port=PORT) break except Exception: pass logger.info("%s on %s:%s" % (response[0], response[1], response[2])) nat_type = response[0] ip_address = response[1] port = response[2] # TODO: use TURN if symmetric NAT def on_bootstrap_complete(resp): logger.info("bootstrap complete") mserver.get_messages(mlistener) task.LoopingCall(check_unfunded_for_payment, db, libbitcoin_client, nlistener, TESTNET).start(600) protocol = OpenBazaarProtocol((ip_address, port), response[0], testnet=TESTNET) # kademlia node = Node(keys.guid, ip_address, port, signed_pubkey=keys.guid_signed_pubkey, vendor=Profile(db).get().vendor) storage = ForgetfulStorage() if TESTNET else PersistentStorage(db.DATABASE) try: kserver = Server.loadState(DATA_FOLDER + 'cache.pickle', ip_address, port, protocol, db, on_bootstrap_complete, storage=storage) except Exception: kserver = Server(node, db, KSIZE, ALPHA, storage=storage) kserver.protocol.connect_multiplexer(protocol) kserver.bootstrap(kserver.querySeed(SEED)).addCallback(on_bootstrap_complete) kserver.saveStateRegularly(DATA_FOLDER + 'cache.pickle', 10) protocol.register_processor(kserver.protocol) if nat_type != "Full Cone": kserver.protocol.ping(SEED_NODE_TESTNET if TESTNET else SEED_NODE) # market mserver = network.Server(kserver, keys.signing_key, db) mserver.protocol.connect_multiplexer(protocol) protocol.register_processor(mserver.protocol) reactor.listenUDP(port, protocol) class OnlyIP(Site): def __init__(self, resource, ip, timeout=60 * 60 * 1): self.ip = ip Site.__init__(self, resource, timeout=timeout) def buildProtocol(self, addr): if addr.host == self.ip: return Site.buildProtocol(self, addr) return None # websockets api if SSL: ws_factory = WSFactory("wss://127.0.0.1:" + str(WSPORT), mserver, kserver, only_ip=ALLOWIP) contextFactory = ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT) ws_factory.protocol = WSProtocol listenWS(ws_factory, contextFactory) else: ws_factory = WSFactory("ws://127.0.0.1:" + str(WSPORT), mserver, kserver, only_ip=ALLOWIP) ws_factory.protocol = WSProtocol listenWS(ws_factory) if ALLOWIP != "127.0.0.1" and ALLOWIP != "0.0.0.0": ws_interface = "0.0.0.0" else: ws_interface = ALLOWIP webdir = File(".") web = Site(webdir) reactor.listenTCP(WSPORT - 1, web, interface=ws_interface) # rest api api = OpenBazaarAPI(mserver, kserver, protocol) if ALLOWIP != "127.0.0.1" and ALLOWIP != "0.0.0.0": rest_interface = "0.0.0.0" site = OnlyIP(api, ALLOWIP, timeout=None) else: rest_interface = ALLOWIP site = Site(api, timeout=None) if SSL: reactor.listenSSL(RESTPORT, site, ChainedOpenSSLContextFactory(SSL_KEY, SSL_CERT), interface=rest_interface) else: reactor.listenTCP(RESTPORT, site, interface=rest_interface) # blockchain if TESTNET: libbitcoin_client = LibbitcoinClient(LIBBITCOIN_SERVER_TESTNET, log=Logger(service="LibbitcoinClient")) else: libbitcoin_client = LibbitcoinClient(LIBBITCOIN_SERVER, log=Logger(service="LibbitcoinClient")) # listeners nlistener = NotificationListenerImpl(ws_factory, db) mserver.protocol.add_listener(nlistener) mlistener = MessageListenerImpl(ws_factory, db) mserver.protocol.add_listener(mlistener) blistener = BroadcastListenerImpl(ws_factory, db) mserver.protocol.add_listener(blistener) protocol.set_servers(ws_factory, libbitcoin_client) logger.info("Startup took %s seconds" % str(round(time.time() - args[7], 2))) reactor.run()