Пример #1
0
    def setUp(self):

        self.db = Database(filepath="test.db")
        self.test_hash = "87e0555568bf5c7e4debd6645fc3f41e88df6ca8"
        self.test_hash2 = "97e0555568bf5c7e4debd6645fc3f41e88df6ca8"
        self.test_file = "Contents of test.txt"
        self.test_file2 = "Contents of test2.txt"

        self.sp = Profile()
        self.key = Profile().PublicKey()
        self.key.public_key = "Key"
        self.key.signature = "Sig"
        self.sp.name = "Test User"
        self.sp.guid_key.MergeFrom(self.key)
        self.sp.location = CountryCode.Value('UNITED_STATES')

        self.serialized_listings = Listings()
        self.lm = self.serialized_listings.ListingMetadata()
        self.lm.contract_hash = self.test_hash
        self.lm.title = "TEST CONTRACT TITLE"
        self.lm.price = 0
        self.lm.currency_code = "USD"
        self.lm.nsfw = False
        self.lm.origin = CountryCode.Value('ALL')

        self.u = Following.User()
        self.u.guid = '0000000000000000000000000000000000'
        self.u.pubkey = 'signed_pubkey'

        self.m = Metadata()
        self.m.name = 'Test User'
        self.m.handle = '@TestUser'
        self.m.avatar_hash = ''
        self.m.nsfw = False
        self.u.metadata.MergeFrom(self.m)

        self.f = Followers.Follower()
        self.f.guid = '0000000000000000000000000000000001'
        self.f.following = ''
        self.f.pubkey = ''
        self.f.metadata.MergeFrom(self.m)

        self.hm = self.db.HashMap()
        self.hm.delete_all()

        self.ps = self.db.ProfileStore()
        self.ls = self.db.ListingsStore()
        self.ks = self.db.KeyStore()
        self.fd = self.db.FollowData()
        self.ms = self.db.MessageStore()
        self.ns = self.db.NotificationStore()
        self.vs = self.db.VendorStore()
        self.bs = self.db.BroadcastStore()
        self.moderators = self.db.ModeratorStore()
        self.purchases = self.db.Purchases()
        self.sales = self.db.Sales()
        self.settings = self.db.Settings()
Пример #2
0
    def setUp(self):
        self.public_ip = '123.45.67.89'
        self.port = 12345
        self.own_addr = (self.public_ip, self.port)
        self.addr1 = ('132.54.76.98', 54321)
        self.addr2 = ('231.76.45.89', 15243)
        self.addr3 = ("193.193.111.00", 99999)

        self.clock = task.Clock()
        connection.REACTOR.callLater = self.clock.callLater

        self.proto_mock = mock.Mock(spec_set=rudp.ConnectionMultiplexer)
        self.handler_mock = mock.Mock(spec_set=connection.Handler)
        self.con = connection.Connection(self.proto_mock, self.handler_mock,
                                         self.own_addr, self.addr1)

        valid_key = "63d901c4d57cde34fc1f1e28b9af5d56ed342cae5c2fb470046d0130a4226b0c"
        self.signing_key = nacl.signing.SigningKey(
            valid_key, encoder=nacl.encoding.HexEncoder)
        verify_key = self.signing_key.verify_key
        h = nacl.hash.sha512(verify_key.encode())
        self.storage = ForgetfulStorage()
        self.node = Node(unhexlify(h[:40]), self.public_ip, self.port,
                         verify_key.encode(), None, FULL_CONE, True)
        self.db = Database(filepath="test.db")
        self.protocol = KademliaProtocol(self.node, self.storage, 20, self.db,
                                         self.signing_key)

        self.wire_protocol = OpenBazaarProtocol(self.db, self.own_addr,
                                                FULL_CONE)
        self.wire_protocol.register_processor(self.protocol)

        self.protocol.connect_multiplexer(self.wire_protocol)
        self.handler = self.wire_protocol.ConnHandler(
            [self.protocol], self.wire_protocol, None,
            self.wire_protocol.ban_score)

        transport = mock.Mock(spec_set=udp.Port)
        ret_val = address.IPv4Address('UDP', self.public_ip, self.port)
        transport.attach_mock(mock.Mock(return_value=ret_val), 'getHost')
        self.wire_protocol.makeConnection(transport)

        self.node1 = Node(digest("id1"), self.addr1[0], self.addr1[1],
                          digest("key1"), None, FULL_CONE, True)
        self.node2 = Node(digest("id2"), self.addr2[0], self.addr2[1],
                          digest("key2"), None, FULL_CONE, True)
        self.node3 = Node(digest("id3"), self.addr3[0], self.addr3[1],
                          digest("key3"), None, FULL_CONE, True)
    def setUp(self):
        self.public_ip = '123.45.67.89'
        self.port = 12345
        self.own_addr = (self.public_ip, self.port)
        self.addr1 = ('132.54.76.98', 54321)
        self.addr2 = ('231.76.45.89', 15243)
        self.addr3 = ("193.193.111.00", 99999)

        self.clock = task.Clock()
        connection.REACTOR.callLater = self.clock.callLater

        self.proto_mock = mock.Mock(spec_set=rudp.ConnectionMultiplexer)
        self.handler_mock = mock.Mock(spec_set=connection.Handler)
        self.con = connection.Connection(self.proto_mock, self.handler_mock,
                                         self.own_addr, self.addr1)

        valid_key = "1a5c8e67edb8d279d1ae32fa2da97e236b95e95c837dc8c3c7c2ff7a7cc29855"
        self.signing_key = nacl.signing.SigningKey(
            valid_key, encoder=nacl.encoding.HexEncoder)
        verify_key = self.signing_key.verify_key
        signed_pubkey = self.signing_key.sign(str(verify_key))
        h = nacl.hash.sha512(signed_pubkey)
        self.storage = ForgetfulStorage()
        self.node = Node(unhexlify(h[:40]), self.public_ip, self.port,
                         signed_pubkey, None, FULL_CONE, True)
        self.db = Database(filepath=":memory:")
        self.protocol = KademliaProtocol(self.node, self.storage, 20, self.db)

        self.wire_protocol = OpenBazaarProtocol(self.own_addr, FULL_CONE)
        self.wire_protocol.register_processor(self.protocol)

        self.protocol.connect_multiplexer(self.wire_protocol)
        self.handler = self.wire_protocol.ConnHandler([self.protocol],
                                                      self.wire_protocol, None)

        transport = mock.Mock(spec_set=udp.Port)
        ret_val = address.IPv4Address('UDP', self.public_ip, self.port)
        transport.attach_mock(mock.Mock(return_value=ret_val), 'getHost')
        self.wire_protocol.makeConnection(transport)

        self.node1 = Node(digest("id1"), self.addr1[0], self.addr1[1],
                          digest("key1"), None, FULL_CONE, True)
        self.node2 = Node(digest("id2"), self.addr2[0], self.addr2[1],
                          digest("key2"), None, FULL_CONE, True)
        self.node3 = Node(digest("id3"), self.addr3[0], self.addr3[1],
                          digest("key3"), None, FULL_CONE, True)
Пример #4
0
    def __init__(self, ip_address, nat_type, testnet=False, relaying=False):
        """
        Initialize the new protocol with the connection handler factory.

        Args:
                ip_address: a `tuple` of the (ip address, port) of ths node.
        """
        self.ip_address = ip_address
        self.testnet = testnet
        self.ws = None
        self.blockchain = None
        self.processors = []
        self.relay_node = None
        self.nat_type = nat_type
        self.vendors = Database(testnet).VendorStore().get_vendors()
        self.factory = self.ConnHandlerFactory(self.processors, nat_type, self.relay_node)
        self.log = Logger(system=self)
        ConnectionMultiplexer.__init__(self, CryptoConnectionFactory(self.factory), self.ip_address[0], relaying)
Пример #5
0
def run(*args):
    TESTNET = args[0]

    # Create the database
    db = Database(testnet=TESTNET)

    # logging
    logFile = logfile.LogFile.fromFullPath(DATA_FOLDER + "debug.log",
                                           rotateLength=15000000,
                                           maxRotatedFiles=1)
    log.addObserver(FileLogObserver(logFile, level="debug").emit)
    log.addObserver(FileLogObserver(level="debug").emit)
    logger = Logger(system="Httpseed")

    # Load the keys
    keychain = KeyChain(db)

    if os.path.isfile(DATA_FOLDER + 'keys.pickle'):
        keys = pickle.load(open(DATA_FOLDER + "keys.pickle", "r"))
        signing_key_hex = keys["signing_privkey"]
        signing_key = nacl.signing.SigningKey(signing_key_hex,
                                              encoder=nacl.encoding.HexEncoder)
    else:
        signing_key = nacl.signing.SigningKey.generate()
        keys = {
            'signing_privkey':
            signing_key.encode(encoder=nacl.encoding.HexEncoder),
            'signing_pubkey':
            signing_key.verify_key.encode(encoder=nacl.encoding.HexEncoder)
        }
        pickle.dump(keys, open(DATA_FOLDER + "keys.pickle", "wb"))

    # Stun
    port = 18467 if not TESTNET else 28467
    logger.info("Finding NAT Type...")
    response = stun.get_ip_info(stun_host="stun.l.google.com",
                                source_port=port,
                                stun_port=19302)
    logger.info("%s on %s:%s" % (response[0], response[1], response[2]))
    ip_address = response[1]
    port = response[2]

    # Start the kademlia server
    this_node = Node(keychain.guid,
                     ip_address,
                     port,
                     keychain.guid_signed_pubkey,
                     vendor=False)
    protocol = OpenBazaarProtocol((ip_address, port),
                                  response[0],
                                  testnet=TESTNET)

    try:
        kserver = Server.loadState('cache.pickle', ip_address, port, protocol,
                                   db)
    except Exception:
        kserver = Server(this_node, db)
        kserver.protocol.connect_multiplexer(protocol)

    protocol.register_processor(kserver.protocol)
    kserver.saveStateRegularly('cache.pickle', 10)

    # start the market server
    mserver = network.Server(kserver, keychain.signing_key, db)
    mserver.protocol.connect_multiplexer(protocol)
    protocol.register_processor(mserver.protocol)

    reactor.listenUDP(port, protocol)

    class WebResource(resource.Resource):
        def __init__(self, kserver_r):
            resource.Resource.__init__(self)
            self.kserver = kserver_r
            self.nodes = {}
            for bucket in self.kserver.protocol.router.buckets:
                for node in bucket.getNodes():
                    self.nodes[(node.ip, node.port)] = node
            self.nodes[(this_node.ip, this_node.port)] = this_node
            loopingCall = task.LoopingCall(self.crawl)
            loopingCall.start(180, True)

        def crawl(self):
            def gather_results(result):
                for proto in result:
                    n = objects.Node()
                    try:
                        n.ParseFromString(proto)
                        node = Node(n.guid, n.ip, n.port, n.signedPublicKey,
                                    n.vendor)
                        self.nodes[(node.ip, node.port)] = node
                    except Exception:
                        pass

            def start_crawl(results):
                for node, result in results.items():
                    if not result[0]:
                        del self.nodes[(node.ip, node.port)]
                node = Node(digest(random.getrandbits(255)))
                nearest = self.kserver.protocol.router.findNeighbors(node)
                spider = NodeSpiderCrawl(self.kserver.protocol, node, nearest,
                                         100, 4)
                spider.find().addCallback(gather_results)

            ds = {}
            for bucket in self.kserver.protocol.router.buckets:
                for node in bucket.getNodes():
                    self.nodes[(node.ip, node.port)] = node
            for node in self.nodes.values():
                if node.id != this_node.id:
                    ds[node] = self.kserver.protocol.callPing(node)
            deferredDict(ds).addCallback(start_crawl)

        def getChild(self, child, request):
            return self

        def render_GET(self, request):
            nodes = self.nodes.values()
            shuffle(nodes)
            logger.info("Received a request for nodes, responding...")
            if "format" in request.args:
                if request.args["format"][0] == "json":
                    json_list = []
                    if "type" in request.args and request.args["type"][
                            0] == "vendors":
                        for node in nodes:
                            if node.vendor is True:
                                node_dic = {}
                                node_dic["ip"] = node.ip
                                node_dic["port"] = node.port
                                node_dic["guid"] = node.id.encode("hex")
                                node_dic[
                                    "signed_pubkey"] = node.signed_pubkey.encode(
                                        "hex")
                                json_list.append(node_dic)
                        sig = signing_key.sign(str(json_list))
                        resp = {
                            "peers": json_list,
                            "signature": hexlify(sig[:64])
                        }
                        request.write(json.dumps(resp, indent=4))
                    else:
                        for node in nodes[:50]:
                            node_dic = {}
                            node_dic["ip"] = node.ip
                            node_dic["port"] = node.port
                            json_list.append(node_dic)
                        sig = signing_key.sign(str(json_list))
                        resp = {
                            "peers": json_list,
                            "signature": hexlify(sig[:64])
                        }
                        request.write(json.dumps(resp, indent=4))
                elif request.args["format"][0] == "protobuf":
                    proto = peers.PeerSeeds()
                    for node in nodes[:50]:
                        peer = peers.PeerData()
                        peer.ip_address = node.ip
                        peer.port = node.port
                        peer.vendor = node.vendor
                        proto.peer_data.append(peer.SerializeToString())

                    sig = signing_key.sign("".join(proto.peer_data))[:64]
                    proto.signature = sig
                    uncompressed_data = proto.SerializeToString()
                    request.write(uncompressed_data.encode("zlib"))
            else:
                proto = peers.PeerSeeds()
                if "type" in request.args and request.args["type"][
                        0] == "vendors":
                    for node in nodes:
                        if node.vendor is True:
                            peer = peers.PeerData()
                            peer.ip_address = node.ip
                            peer.port = node.port
                            peer.vendor = node.vendor
                            peer.guid = node.id
                            peer.signedPubkey = node.signed_pubkey
                            proto.peer_data.append(peer.SerializeToString())

                    sig = signing_key.sign("".join(proto.peer_data))[:64]
                    proto.signature = sig
                    uncompressed_data = proto.SerializeToString()
                    request.write(uncompressed_data.encode("zlib"))
                else:
                    for node in nodes[:50]:
                        peer = peers.PeerData()
                        peer.ip_address = node.ip
                        peer.port = node.port
                        peer.vendor = node.vendor
                        proto.peer_data.append(peer.SerializeToString())

                    sig = signing_key.sign("".join(proto.peer_data))[:64]
                    proto.signature = sig
                    uncompressed_data = proto.SerializeToString()
                    request.write(uncompressed_data.encode("zlib"))
            request.finish()
            return server.NOT_DONE_YET

    server_protocol = server.Site(WebResource(kserver))
    reactor.listenTCP(8080, server_protocol)

    reactor.run()
Пример #6
0
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 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)
class DatastoreTest(unittest.TestCase):
    def setUp(self):
        self.db = Database(filepath="test.db")
        self.test_hash = "87e0555568bf5c7e4debd6645fc3f41e88df6ca8"
        self.test_hash2 = "97e0555568bf5c7e4debd6645fc3f41e88df6ca8"
        self.test_file = "Contents of test.txt"
        self.test_file2 = "Contents of test2.txt"

        self.sp = Profile()
        self.key = Profile().PublicKey()
        self.key.public_key = "Key"
        self.key.signature = "Sig"
        self.sp.name = "Test User"
        self.sp.encryption_key.MergeFrom(self.key)
        self.sp.location = CountryCode.Value('UNITED_STATES')

        self.serialized_listings = Listings()
        self.lm = self.serialized_listings.ListingMetadata()
        self.lm.contract_hash = self.test_hash
        self.lm.title = "TEST CONTRACT TITLE"
        self.lm.price = 0
        self.lm.currency_code = "USD"
        self.lm.nsfw = False
        self.lm.origin = CountryCode.Value('ALL')

        self.u = Following.User()
        self.u.guid = '0000000000000000000000000000000000'
        self.u.signed_pubkey = 'signed_pubkey'

        self.m = Metadata()
        self.m.name = 'Test User'
        self.m.handle = '@TestUser'
        self.m.avatar_hash = ''
        self.m.nsfw = False
        self.u.metadata.MergeFrom(self.m)

        self.f = Followers.Follower()
        self.f.guid = '0000000000000000000000000000000001'
        self.f.following = ''
        self.f.signed_pubkey = ''
        self.f.metadata.MergeFrom(self.m)

        self.hm = self.db.HashMap()
        self.hm.delete_all()

        self.ps = self.db.ProfileStore()
        self.ls = self.db.ListingsStore()
        self.ks = self.db.KeyStore()
        self.fd = self.db.FollowData()
        self.ms = self.db.MessageStore()
        self.ns = self.db.NotificationStore()
        self.vs = self.db.VendorStore()

    def tearDown(self):
        os.remove("test.db")

    def test_hashmapInsert(self):
        self.hm.insert(self.test_hash, self.test_file)
        f = self.hm.get_file(self.test_hash)
        self.assertEqual(f, self.test_file)

    def test_hashmapDelete(self):
        self.hm.insert(self.test_hash, self.test_file)
        f = self.hm.get_file(self.test_hash)
        self.assertEqual(f, self.test_file)
        self.hm.delete(self.test_hash)
        v = self.hm.get_file(self.test_hash)
        self.assertIsNone(v)

    def test_hashmapGetEmpty(self):
        f = self.hm.get_file('87e0555568bf5c7e4debd6645fc3f41e88df6ca9')
        self.assertEqual(f, None)

    def test_hashmapGetAll(self):
        # Get All from empty datastore
        self.hm.delete_all()
        f = self.hm.get_all()
        self.assertEqual(0, len(f))

        # Get All from populated datastore
        self.hm.insert(self.test_hash, self.test_file)
        self.hm.insert(self.test_hash2, self.test_file2)
        f = self.hm.get_all()

        self.assertIn((self.test_hash, self.test_file), f)
        self.assertIn((self.test_hash2, self.test_file2), f)

    def test_setProto(self):
        self.ps.set_proto(self.sp.SerializeToString())
        sp = self.ps.get_proto()
        val = Profile()
        val.ParseFromString(sp)
        self.assertEqual(self.sp, val)

    def test_addListing(self):
        self.ls.delete_all_listings()
        self.ls.add_listing(self.lm)
        l = self.ls.get_proto()
        val = Listings()
        val.ParseFromString(l)
        self.assertEqual(self.lm, val.listing[0])

    def test_deleteListing(self):
        self.ls.delete_all_listings()
        self.ls.add_listing(self.lm)
        self.ls.delete_listing(self.test_hash)
        l = self.ls.get_proto()
        val = Listings()
        val.ParseFromString(l)
        self.assertEqual(0, len(val.listing))

        # Try to delete when table is already empty
        self.ls.delete_all_listings()
        self.assertEqual(None, self.ls.delete_listing(self.test_hash))

    def test_setGUIDKey(self):
        self.ks.set_key("guid", "privkey", "signed_privkey")
        key = self.ks.get_key("guid")
        self.assertEqual(("privkey", "signed_privkey"), key)

    def test_setBitcoinKey(self):
        self.ks.set_key("bitcoin", "privkey", "signed_privkey")
        key = self.ks.get_key("bitcoin")
        self.assertEqual(("privkey", "signed_privkey"), key)

    def test_getKeyFromEmptyTable(self):
        self.ks.delete_all_keys()
        self.assertEqual(None, self.ks.get_key("guid"))

    def test_follow_unfollow(self):
        self.fd.follow(self.u)
        following = self.fd.get_following()
        self.assertIsNotNone(following)

        self.assertTrue(self.fd.is_following(self.u.guid))

        self.fd.unfollow(self.u.guid)
        following = self.fd.get_following()
        self.assertEqual(following, '')
        self.assertFalse(self.fd.is_following(self.u.guid))

    def test_deleteFollower(self):
        self.fd.set_follower(self.f)
        f = self.fd.get_followers()
        self.assertIsNotNone(f)
        self.fd.delete_follower(self.f.guid)
        f = self.fd.get_followers()
        self.assertEqual(f, '')

    def test_saveMessage(self):
        msgs = self.ms.get_messages(self.u.guid, 'CHAT')
        self.assertTrue(len(msgs) == 0)
        self.ms.save_message(self.u.guid, self.m.handle, self.u.signed_pubkey,
                             '', 'SUBJECT', 'CHAT', 'MESSAGE', '0000-00-00 00:00:00',
                             '', '', '')
        msgs = self.ms.get_messages(self.u.guid, 'CHAT')
        self.assertIsNotNone(msgs)
        self.ms.delete_message(self.u.guid)
        msgs = self.ms.get_messages(self.u.guid, 'CHAT')
        self.assertTrue(len(msgs) == 0)

    def test_notificationStore(self):
        n = self.ns.get_notifications()
        self.assertTrue(len(n) == 0)
        self.ns.save_notification("1234", self.u.guid, self.m.handle, 'NOTICE', "", ""
                                  '0000-00-00 00:00:00', '', 0)
        n = self.ns.get_notifications()
        self.assertIsNotNone(n)
        self.ns.delete_notification("1234")
        n = self.ns.get_notifications()
        self.assertTrue(len(n) == 0)

    def test_vendorStore(self):
        v = self.vs.get_vendors()
        self.assertEqual(v, [])
        self.vs.save_vendor(self.u.guid, '127.0.0.1', '80', '')
        v = self.vs.get_vendors()
        self.assertIsNot(v, [])
        self.vs.delete_vendor(self.u.guid)
        v = self.vs.get_vendors()
        self.assertEqual(v, [])
Пример #9
0
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()
Пример #10
0
def run(*args):
    TESTNET = args[0]

    # database
    db = Database(TESTNET)

    # key generation
    keys = KeyChain(db)

    # logging
    # TODO: prune this log file and prevent it from getting too large?
    logFile = logfile.LogFile.fromFullPath(DATA_FOLDER + "debug.log")
    log.addObserver(log.FileLogObserver(logFile).emit)
    log.startLogging(sys.stdout)

    # stun
    # TODO: accept port from command line
    port = 18467 if not TESTNET else 28467
    print "Finding NAT Type.."
    # TODO: maintain a list of backup STUN servers and try them if ours fails
    response = stun.get_ip_info(stun_host="seed.openbazaar.org",
                                source_port=port)
    print "%s on %s:%s" % (response[0], response[1], response[2])
    ip_address = response[1]
    port = response[2]

    # TODO: try UPnP if restricted NAT

    # TODO: maintain open connection to seed node if STUN/UPnP fail

    # TODO: use TURN if symmetric NAT

    def on_bootstrap_complete(resp):
        mlistener = MessageListenerImpl(ws_factory, db)
        mserver.get_messages(mlistener)
        mserver.protocol.add_listener(mlistener)
        nlistener = NotificationListenerImpl(ws_factory, db)
        mserver.protocol.add_listener(nlistener)

        # TODO: after bootstrap run through any pending contracts and see if the bitcoin address
        # has been funded, if not listen on the address and start the 10 minute delete timer.

    protocol = OpenBazaarProtocol((ip_address, port), testnet=TESTNET)

    # kademlia
    node = Node(keys.guid,
                ip_address,
                port,
                signed_pubkey=keys.guid_signed_pubkey)

    try:
        kserver = Server.loadState(DATA_FOLDER + 'cache.pickle',
                                   ip_address,
                                   port,
                                   protocol,
                                   db,
                                   on_bootstrap_complete,
                                   storage=PersistentStorage(db.DATABASE))
    except Exception:
        kserver = Server(node,
                         db,
                         KSIZE,
                         ALPHA,
                         storage=PersistentStorage(db.DATABASE))
        kserver.protocol.connect_multiplexer(protocol)
        kserver.bootstrap(
            kserver.querySeed("seed.openbazaar.org:8080",
                              "ddd862778e3ed71af06db0e3619a4c6269ec7468c745132dbb73982b319fc572"))\
            .addCallback(on_bootstrap_complete)
        # TODO: load seeds from config file
    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)

    reactor.listenUDP(port, protocol)

    # websockets api
    ws_factory = WSFactory("ws://127.0.0.1:18466", mserver, kserver)
    ws_factory.protocol = WSProtocol
    ws_factory.setProtocolOptions(allowHixie76=True)
    listenWS(ws_factory)
    webdir = File(".")
    web = Site(webdir)
    reactor.listenTCP(9000, web, interface="127.0.0.1")

    # rest api
    api = OpenBazaarAPI(mserver, kserver, protocol)
    site = Site(api, timeout=None)
    reactor.listenTCP(18469, site, interface="127.0.0.1")

    # TODO: add optional SSL on rest and websocket servers

    # blockchain
    # TODO: listen on the libbitcoin heartbeat port instead fetching height
    def height_fetched(ec, height):
        # TODO: re-broadcast any unconfirmed txs in the db using height to find confirmation status
        print "Libbitcoin server online"
        try:
            timeout.cancel()
        except Exception:
            pass

    def timeout(client):
        print "Libbitcoin server offline"
        client = None

    if TESTNET:
        libbitcoin_client = LibbitcoinClient(
            "tcp://libbitcoin2.openbazaar.org:9091")
    else:
        libbitcoin_client = LibbitcoinClient(
            "tcp://libbitcoin1.openbazaar.org:9091")

    # TODO: load libbitcoin server url from config file

    libbitcoin_client.fetch_last_height(height_fetched)
    timeout = reactor.callLater(5, timeout, libbitcoin_client)

    protocol.set_servers(ws_factory, libbitcoin_client)

    reactor.run()
Пример #11
0
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()
Пример #12
0
 def setUp(self):
     self.db = Database(filepath="test.db")
     self.createTestUser()
Пример #13
0
def run(*args):
    TESTNET = args[0]

    # database
    db = Database(TESTNET)

    # key generation
    keys = KeyChain(db)

    # logging
    # TODO: prune this log file and prevent it from getting too large?
    logFile = logfile.LogFile.fromFullPath(DATA_FOLDER + "debug.log")
    log.addObserver(FileLogObserver(logFile, level=args[1]).emit)
    log.addObserver(FileLogObserver(level=args[1]).emit)
    logger = Logger(system="OpenBazaard")

    # NAT traversal
    port = args[2]
    PortMapper().add_port_mapping(port, port, 'UDP')
    logger.info("Finding NAT Type...")
    try:
        response = stun.get_ip_info(source_port=port)
    except Exception:
        response = stun.get_ip_info()
    logger.info("%s on %s:%s" % (response[0], response[1], response[2]))
    ip_address = response[1]
    port = response[2]

    # TODO: use TURN if symmetric NAT

    def on_bootstrap_complete(resp):
        logger.info("bootstrap complete, downloading outstanding messages...")
        mlistener = MessageListenerImpl(ws_factory, db)
        mserver.get_messages(mlistener)
        mserver.protocol.add_listener(mlistener)
        nlistener = NotificationListenerImpl(ws_factory, db)
        mserver.protocol.add_listener(nlistener)

        # TODO: ping seed node to establish connection if not full cone NAT

        # TODO: after bootstrap run through any pending contracts and see if the bitcoin address
        # has been funded, if not listen on the address and start the 10 minute delete timer.

    protocol = OpenBazaarProtocol((ip_address, port), 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.openbazaar.org:8080",
                              "5b44be5c18ced1bc9400fe5e79c8ab90204f06bebacc04dd9c70a95eaca6e117"))\
            .addCallback(on_bootstrap_complete)
        # TODO: load seeds from config file
    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)

    reactor.listenUDP(port, protocol)

    # websockets api
    ws_factory = WSFactory("ws://127.0.0.1:18466", mserver, kserver)
    ws_factory.protocol = WSProtocol
    ws_factory.setProtocolOptions(allowHixie76=True)
    listenWS(ws_factory)
    webdir = File(".")
    web = Site(webdir)
    reactor.listenTCP(9000, web, interface=args[4])

    # rest api
    api = OpenBazaarAPI(mserver, kserver, protocol)
    site = Site(api, timeout=None)
    reactor.listenTCP(18469, site, interface=args[3])

    # TODO: add optional SSL on rest and websocket servers

    # blockchain
    # TODO: listen on the libbitcoin heartbeat port instead fetching height
    def height_fetched(ec, height):
        # TODO: re-broadcast any unconfirmed txs in the db using height to find confirmation status
        logger.info("Libbitcoin server online")
        try:
            timeout.cancel()
        except Exception:
            pass

    def timeout(client):
        logger.critical("Libbitcoin server offline")
        client = None

    if TESTNET:
        libbitcoin_client = LibbitcoinClient(
            "tcp://libbitcoin2.openbazaar.org:9091")
    else:
        libbitcoin_client = LibbitcoinClient(
            "tcp://libbitcoin1.openbazaar.org:9091")

    # TODO: load libbitcoin server url from config file

    libbitcoin_client.fetch_last_height(height_fetched)
    timeout = reactor.callLater(7, timeout, libbitcoin_client)

    protocol.set_servers(ws_factory, libbitcoin_client)

    reactor.run()
Пример #14
0
class DatastoreTest(unittest.TestCase):
    def setUp(self):

        self.db = Database(filepath="test.db")
        self.test_hash = "87e0555568bf5c7e4debd6645fc3f41e88df6ca8"
        self.test_hash2 = "97e0555568bf5c7e4debd6645fc3f41e88df6ca8"
        self.test_file = "Contents of test.txt"
        self.test_file2 = "Contents of test2.txt"

        self.sp = Profile()
        self.key = Profile().PublicKey()
        self.key.public_key = "Key"
        self.key.signature = "Sig"
        self.sp.name = "Test User"
        self.sp.guid_key.MergeFrom(self.key)
        self.sp.location = CountryCode.Value('UNITED_STATES')

        self.serialized_listings = Listings()
        self.lm = self.serialized_listings.ListingMetadata()
        self.lm.contract_hash = self.test_hash
        self.lm.title = "TEST CONTRACT TITLE"
        self.lm.price = 0
        self.lm.currency_code = "USD"
        self.lm.nsfw = False
        self.lm.origin = CountryCode.Value('ALL')

        self.u = Following.User()
        self.u.guid = '0000000000000000000000000000000000'
        self.u.pubkey = 'signed_pubkey'

        self.m = Metadata()
        self.m.name = 'Test User'
        self.m.handle = '@TestUser'
        self.m.avatar_hash = ''
        self.m.nsfw = False
        self.u.metadata.MergeFrom(self.m)

        self.f = Followers.Follower()
        self.f.guid = '0000000000000000000000000000000001'
        self.f.following = ''
        self.f.pubkey = ''
        self.f.metadata.MergeFrom(self.m)

        self.hm = self.db.HashMap()
        self.hm.delete_all()

        self.ps = self.db.ProfileStore()
        self.ls = self.db.ListingsStore()
        self.ks = self.db.KeyStore()
        self.fd = self.db.FollowData()
        self.ms = self.db.MessageStore()
        self.ns = self.db.NotificationStore()
        self.vs = self.db.VendorStore()
        self.bs = self.db.BroadcastStore()
        self.moderators = self.db.ModeratorStore()
        self.purchases = self.db.Purchases()
        self.sales = self.db.Sales()
        self.settings = self.db.Settings()

    def tearDown(self):
        os.remove("test.db")

    def test_hashmapInsert(self):
        self.hm.insert(self.test_hash, self.test_file)
        f = self.hm.get_file(self.test_hash)
        self.assertEqual(f, self.test_file)

    def test_hashmapDelete(self):
        self.hm.insert(self.test_hash, self.test_file)
        f = self.hm.get_file(self.test_hash)
        self.assertEqual(f, self.test_file)
        self.hm.delete(self.test_hash)
        v = self.hm.get_file(self.test_hash)
        self.assertIsNone(v)

    def test_hashmapGetEmpty(self):
        f = self.hm.get_file('87e0555568bf5c7e4debd6645fc3f41e88df6ca9')
        self.assertEqual(f, None)

    def test_hashmapGetAll(self):
        # Get All from empty datastore
        self.hm.delete_all()
        f = self.hm.get_all()
        self.assertEqual(0, len(f))

        # Get All from populated datastore
        self.hm.insert(self.test_hash, self.test_file)
        self.hm.insert(self.test_hash2, self.test_file2)
        f = self.hm.get_all()

        self.assertIn((self.test_hash, self.test_file), f)
        self.assertIn((self.test_hash2, self.test_file2), f)

    def test_setProto(self):
        self.ps.set_proto(self.sp.SerializeToString())
        sp = self.ps.get_proto()
        val = Profile()
        val.ParseFromString(sp)
        self.assertEqual(self.sp, val)

    def test_addListing(self):
        self.ls.delete_all_listings()
        self.ls.add_listing(self.lm)
        self.ls.add_listing(self.lm)

        l = self.ls.get_proto()
        val = Listings()
        val.ParseFromString(l)
        self.assertEqual(self.lm, val.listing[0])
        self.assertEqual(1, len(val.listing))

    def test_deleteListing(self):
        self.ls.delete_all_listings()
        self.ls.add_listing(self.lm)
        self.ls.delete_listing(self.test_hash)
        l = self.ls.get_proto()
        val = Listings()
        val.ParseFromString(l)
        self.assertEqual(0, len(val.listing))

        # Try to delete when table is already empty
        self.ls.delete_all_listings()
        self.assertEqual(None, self.ls.delete_listing(self.test_hash))

    def test_setGUIDKey(self):
        self.ks.set_key("guid", "privkey", "signed_privkey")
        key = self.ks.get_key("guid")
        self.assertEqual(("privkey", "signed_privkey"), key)

    def test_setBitcoinKey(self):
        self.ks.set_key("bitcoin", "privkey", "signed_privkey")
        key = self.ks.get_key("bitcoin")
        self.assertEqual(("privkey", "signed_privkey"), key)

    def test_getKeyFromEmptyTable(self):
        self.ks.delete_all_keys()
        self.assertEqual(None, self.ks.get_key("guid"))

    def test_follow_unfollow(self):
        self.fd.follow(self.u)
        following = self.fd.get_following()
        self.assertIsNotNone(following)

        self.fd.follow(self.u)
        self.assertTrue(self.fd.is_following(self.u.guid))

        self.fd.unfollow(self.u.guid)
        self.fd.unfollow(self.f)
        following = self.fd.get_following()
        self.assertEqual(following, '')
        self.assertFalse(self.fd.is_following(self.u.guid))

    def test_deleteFollower(self):
        self.fd.set_follower(self.f)
        self.fd.set_follower(self.f)
        f = self.fd.get_followers()
        self.assertIsNotNone(f)
        self.fd.delete_follower(self.f.guid)
        f = self.fd.get_followers()
        self.assertEqual(f, '')

    def test_MassageStore(self):
        msgs = self.ms.get_messages(self.u.guid, 'CHAT')
        self.assertEqual(0, len(msgs))
        guids = self.ms.get_unread()
        self.assertEqual(0, len(guids))
        conversations = self.ms.get_conversations()
        self.assertEqual(0, len(conversations))

        self.ms.save_message(self.u.guid, self.m.handle, self.u.pubkey,
                             'SUBJECT', 'CHAT', 'MESSAGE', ZERO_TIMESTAMP, '',
                             '', '')
        msgs = self.ms.get_messages(self.u.guid, 'CHAT')
        self.assertEqual(1, len(msgs))

        guids = self.ms.get_unread()
        self.assertEqual(1, len(guids))

        conversations = self.ms.get_conversations()
        self.assertEqual(1, len(conversations))

        self.ms.mark_as_read(self.u.guid)
        guids = self.ms.get_unread()
        self.assertEqual(0, len(guids))

        self.ms.delete_message(self.u.guid)
        msgs = self.ms.get_messages(self.u.guid, 'CHAT')
        self.assertEqual(0, len(msgs))

    def test_BroadcastStore(self):
        bmsgs = self.bs.get_broadcasts()
        self.assertEqual(0, len(bmsgs))

        self.bs.save_broadcast('BID', self.u.guid, self.m.handle, 'MESSAGE',
                               ZERO_TIMESTAMP, '')
        bmsgs = self.bs.get_broadcasts()
        self.assertEqual(1, len(bmsgs))

        self.bs.delete_broadcast('BID')
        bmsgs = self.bs.get_broadcasts()
        self.assertEqual(0, len(bmsgs))

    def test_ModeratorStore(self):
        moderators = self.moderators.get_moderator(self.u.guid)
        self.assertIsNone(moderators)

        self.moderators.save_moderator(self.u.guid, self.u.pubkey, '', '', '',
                                       'JOHN', '', '0', '')
        moderators = self.moderators.get_moderator(self.u.guid)
        self.assertEqual(moderators[0], self.u.guid)

        self.moderators.delete_moderator(self.u.guid)
        moderators = self.moderators.get_moderator(self.u.guid)
        self.assertIsNone(moderators)

        self.moderators.save_moderator(self.u.guid, self.u.pubkey, '', '', '',
                                       'JOHN', '', '0', '')
        self.moderators.clear_all()
        moderators = self.moderators.get_moderator(self.u.guid)
        self.assertIsNone(moderators)

    def test_Purchases(self):
        purchase = self.purchases.get_purchase('NO_EXIST')
        self.assertIsNone(purchase)
        purchases = self.purchases.get_all()
        self.assertEqual(0, len(purchases))

        self.purchases.new_purchase('OID', 'NEW', '', ZERO_TIMESTAMP, '', '',
                                    '0', '', '', '', '')
        purchase = self.purchases.get_purchase('OID')
        self.assertEqual('OID', purchase[0])
        purchases = self.purchases.get_all()
        self.assertEqual(1, len(purchases))

        unfunded = self.purchases.get_unfunded()
        self.assertEqual(1, len(unfunded))

        status = self.purchases.get_status('OID')
        self.assertEqual(0, status)

        self.purchases.update_status('OID', 1)
        status = self.purchases.get_status('OID')
        self.assertEqual(1, status)

        unfunded = self.purchases.get_unfunded()
        self.assertEqual(0, len(unfunded))

        outpoint = self.purchases.get_outpoint('OID')
        self.assertIsNone(outpoint)
        self.purchases.update_outpoint('OID', 'OUTPOINT')
        outpoint = self.purchases.get_outpoint('OID')
        self.assertEqual('OUTPOINT', outpoint)

        self.purchases.delete_purchase('OID')
        purchase = self.purchases.get_purchase('OID')
        self.assertIsNone(purchase)

    def test_Sales(self):
        sale = self.sales.get_sale('NO_EXIST')
        self.assertIsNone(sale)
        sales = self.sales.get_all()
        self.assertEqual(0, len(sales))

        self.sales.new_sale('OID', 'NEW', '', ZERO_TIMESTAMP, '', '', '0', '',
                            '', '')
        sale = self.sales.get_sale('OID')
        self.assertEqual('OID', sale[0])
        sales = self.sales.get_all()
        self.assertEqual(1, len(sales))

        unfunded = self.sales.get_unfunded()
        self.assertEqual(1, len(unfunded))

        status = self.sales.get_status('OID')
        self.assertEqual(0, status)

        self.sales.update_status('OID', 1)
        status = self.sales.get_status('OID')
        self.assertEqual(1, status)

        unfunded = self.sales.get_unfunded()
        self.assertEqual(0, len(unfunded))

        outpoint = self.sales.get_outpoint('OID')
        self.assertIsNone(outpoint)
        self.sales.update_outpoint('OID', 'OUTPOINT')
        outpoint = self.sales.get_outpoint('OID')
        self.assertEqual('OUTPOINT', outpoint)

        self.sales.update_payment_tx('OID', 'TXDI')
        # no get method for payment_tx

        self.sales.delete_sale('OID')
        sale = self.sales.get_sale('OID')
        self.assertIsNone(sale)

    def test_NotificationStore(self):
        n = self.ns.get_notifications()
        self.assertTrue(len(n) == 0)
        self.ns.save_notification("1234", self.u.guid, self.m.handle, 'NOTICE',
                                  "", ""
                                  '0000-00-00 00:00:00', '', 0)
        n = self.ns.get_notifications()
        self.assertIsNotNone(n)
        self.ns.mark_as_read("1234")

        self.ns.delete_notification("1234")
        n = self.ns.get_notifications()
        self.assertTrue(len(n) == 0)

    def test_VendorStore(self):
        v = self.vs.get_vendors()
        self.assertEqual(v, {})
        addr = Node.IPAddress()
        addr.ip = "127.0.0.1"
        addr.port = 1234
        n = Node()
        n.guid = digest("abcdefg")
        n.publicKey = digest("signed pubkey")
        n.nodeAddress.MergeFrom(addr)
        n.natType = FULL_CONE
        self.vs.save_vendor(self.u.guid, n.SerializeToString())
        v = self.vs.get_vendors()
        self.assertIsNot(v, {})
        self.vs.delete_vendor(self.u.guid)
        v = self.vs.get_vendors()
        self.assertEqual(v, {})

    def test_Settings(self):
        NUM_SETTINGS = 16
        settings = self.settings.get()
        self.assertIsNone(settings)

        self.settings.update('NEW_ADDRESS', 'BTC', 'AUSTRALIA', 'EN', '', '',
                             '', '', '', '', '', '', '', '', "")
        settings = self.settings.get()
        self.assertEqual(NUM_SETTINGS, len(settings))