コード例 #1
0
 def test_get(self):
     v = Value()
     v.valueKey = self.key1
     v.serializedData = self.value
     testv = [v.SerializeToString()]
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value)
     self.assertEqual(testv, f.get(self.keyword1))
コード例 #2
0
ファイル: test_storage.py プロジェクト: Renelvon/Network
 def test_get(self):
     v = Value()
     v.valueKey = self.key1
     v.serializedData = self.value
     testv = [v.SerializeToString()]
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value)
     self.assertEqual(testv, f.get(self.keyword1))
コード例 #3
0
 def test_get(self):
     v = Value()
     v.valueKey = self.key1
     v.serializedData = self.value
     v.ttl = 10
     testv = [v.SerializeToString()]
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     self.assertEqual(testv, p.get(self.keyword1))
コード例 #4
0
 def test_get(self):
     v = Value()
     v.valueKey = self.key1
     v.serializedData = self.value
     v.ttl = 10
     testv = [v.SerializeToString()]
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     self.assertEqual(testv, p.get(self.keyword1))
コード例 #5
0
ファイル: test_protocol.py プロジェクト: Renelvon/Network
    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.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, True)
        self.protocol = KademliaProtocol(self.node, self.storage, 20)

        self.handler = self.protocol.RPCHandler(False, 5, self.protocol._outstanding, self.protocol)
        self.handler.connection = self.con

        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.protocol.makeConnection(transport)
コード例 #6
0
    def setUp(self):
        self.version = PROTOCOL_VERSION
        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.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, objects.FULL_CONE, True)
        self.db = datastore.Database(filepath="test.db")
        self.protocol = KademliaProtocol(self.node, self.storage, 20, self.db,
                                         self.signing_key)

        self.wire_protocol = PulseShopProtocol(self.db, self.own_addr,
                                               objects.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)
        self.handler.connection = self.con

        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)
コード例 #7
0
 def test_setitem(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     p[self.keyword2] = (self.key1, self.value, 10)
     p[self.keyword2] = (self.key2, self.value, 10)
     self.assertEqual(p[self.keyword1][0][:2], (self.key1, self.value))
     ret = []
     for val in p[self.keyword2]:
         ret.append(val[:2])
     self.assertEqual(ret, [(self.key1, self.value),
                            (self.key2, self.value)])
コード例 #8
0
    def setUp(self):
        self.version = PROTOCOL_VERSION
        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.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, objects.FULL_CONE, True)
        self.db = datastore.Database(filepath="test.db")
        self.protocol = KademliaProtocol(self.node, self.storage, 20, self.db)

        self.wire_protocol = OpenBazaarProtocol(self.own_addr, objects.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.handler.connection = self.con

        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)
コード例 #9
0
 def test_setitem(self):
     f = ForgetfulStorage()
     tdict1 = TTLDict(3)
     tdict1[self.key1] = self.value
     f[self.keyword1] = (self.key1, self.value, 10)
     tdict2 = TTLDict(3)
     tdict2[self.key1] = self.value
     tdict2[self.key2] = self.value
     f[self.keyword2] = (self.key1, self.value, 10)
     f[self.keyword2] = (self.key2, self.value, 10)
     self.assertEqual(f.data[self.keyword1], tdict1)
     self.assertEqual(f.data[self.keyword2], tdict2)
コード例 #10
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 = "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, 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)

        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"), True)
        self.node2 = Node(digest("id2"), self.addr2[0], self.addr2[1],
                          digest("key2"), True)
        self.node3 = Node(digest("id3"), self.addr3[0], self.addr3[1],
                          digest("key3"), True)
コード例 #11
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=":memory:")
        self.protocol = KademliaProtocol(self.node, self.storage, 20, self.db,
                                         self.signing_key)

        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)
コード例 #12
0
    def __init__(self, node, ksize=20, alpha=3, storage=None):
        """
        Create a server instance.  This will start listening on the given port.

        Args:
            node: The node instance for this peer. It must contain (at minimum) an ID,
                public key, ip address, and port.
            ksize (int): The k parameter from the paper
            alpha (int): The alpha parameter from the paper
            storage: An instance that implements :interface:`~dht.storage.IStorage`
        """
        self.ksize = ksize
        self.alpha = alpha
        self.log = Logger(system=self)
        self.storage = storage or ForgetfulStorage()
        self.node = node
        self.protocol = KademliaProtocol(self.node, self.storage, ksize)
        self.refreshLoop = LoopingCall(self.refreshTable).start(3600)
コード例 #13
0
    def setUp(self):
        self.version = PROTOCOL_VERSION
        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.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, objects.FULL_CONE, True)
        self.db = datastore.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, objects.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)
        self.handler.connection = self.con

        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)
コード例 #14
0
    def setUp(self):
        self.version = PROTOCOL_VERSION
        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.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, True)
        self.db = datastore.Database(filepath="test.db")
        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)
        self.handler.connection = self.con

        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)
コード例 #15
0
 def test_iteritems(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     for k, v in p.iteritems(self.keyword1):
         self.assertEqual((self.key1, self.value), (k, v))
コード例 #16
0
 def test_ttl(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value, .00000000000001)
     self.assertTrue(self.keyword1 not in f)
コード例 #17
0
 def test_iterkeys(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     for k in p.iterkeys():
         self.assertEqual(k[0].decode("hex"), self.keyword1)
コード例 #18
0
 def test_iteritems(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value)
     for k, v in f.iteritems(self.keyword1):
         self.assertEqual((self.key1, self.value), (k, v))
コード例 #19
0
class KademliaProtocolTest(unittest.TestCase):
    def setUp(self):
        self.version = PROTOCOL_VERSION
        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.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, True)
        self.db = datastore.Database(filepath="test.db")
        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)
        self.handler.connection = self.con

        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)

    def tearDown(self):
        if self.con.state != connection.State.SHUTDOWN:
            self.con.shutdown()
        self.wire_protocol.shutdown()
        os.remove("test.db")

    def test_invalid_datagram(self):
        self.assertFalse(self.handler.receive_message("hi"))
        self.assertFalse(self.handler.receive_message("hihihihihihihihihihihihihihihihihihihihih"))

    def test_rpc_ping(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("PING")
        m.protoVer = self.version
        m.testnet = False
        data = m.SerializeToString()
        m.arguments.append(self.protocol.sourceNode.getProto().SerializeToString())
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_store(self):
        self._connecting_to_connected()
        self.protocol.router.addContact(self.protocol.sourceNode)

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key",
                            self.protocol.sourceNode.getProto().SerializeToString(), str(10)])
        data = m.SerializeToString()
        del m.arguments[-4:]
        m.arguments.append("True")
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

    def test_bad_rpc_store(self):
        r = self.protocol.rpc_store(self.node, 'testkeyword', 'kw', 'val', 10)
        self.assertEqual(r, ['False'])

    def test_rpc_delete(self):
        self._connecting_to_connected()
        self.protocol.router.addContact(self.protocol.sourceNode)

        # Set a keyword to store
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key",
                            self.protocol.sourceNode.getProto().SerializeToString(), str(10)])
        data = m.SerializeToString()
        del m.arguments[-4:]
        m.arguments.append("True")
        expected_message1 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        # Test bad signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key", "Bad Signature"])
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("False")
        expected_message2 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list
        )
        self.assertEqual(sent_packets[0].payload, expected_message1)
        self.assertEqual(sent_packets[1].payload, expected_message2)
        self.proto_mock.send_datagram.call_args_list = []

        # Test good signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key", self.signing_key.sign("Key")[:64]])
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("True")
        expected_message3 = m.SerializeToString()
        self.handler.receive_message(data)
        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        self.assertEqual(sent_packet.payload, expected_message3)
        self.assertTrue(self.storage.getSpecific(digest("Keyword"), "Key") is None)

    def test_rpc_stun(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STUN")
        m.protoVer = self.version
        m.testnet = False
        data = m.SerializeToString()
        m.arguments.extend([self.public_ip, str(self.port)])
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_node(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_NODE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.append(digest("nodetofind"))
        data = m.SerializeToString()
        del m.arguments[-1]
        m.arguments.extend([node2.getProto().SerializeToString(), node1.getProto().SerializeToString(),
                            node3.getProto().SerializeToString()])
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_value(self):
        self._connecting_to_connected()
        self.protocol.router.addContact(self.protocol.sourceNode)

        # Set a value to find
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.protoVer = self.version
        m.arguments.extend([digest("Keyword"), "Key",
                            self.protocol.sourceNode.getProto().SerializeToString(), str(10)])
        data = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        # Send the find_value rpc
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.append(digest("Keyword"))
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        value = objects.Value()
        value.valueKey = "Key"
        value.serializedData = self.protocol.sourceNode.getProto().SerializeToString()
        value.ttl = 10
        m.arguments.append("value")
        m.arguments.append(value.SerializeToString())
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list
        )
        received_message = sent_packets[1].payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 3)

    def test_rpc_find_without_value(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.append(digest("Keyword"))
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        m.arguments.extend([node3.getProto().SerializeToString(), node1.getProto().SerializeToString(),
                            node2.getProto().SerializeToString()])
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        m = message.Message()
        m.ParseFromString(received_message)

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_callPing(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callPing(n)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.PING)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)

    def test_callStore(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callStore(n, digest("Keyword"), digest("Key"),
                                self.protocol.sourceNode.getProto().SerializeToString(), 10)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.STORE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], self.protocol.sourceNode.getProto().SerializeToString())

    def test_callFindValue(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        keyword = Node(digest("Keyword"))
        self.protocol.callFindValue(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.FIND_VALUE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callFindNode(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        keyword = Node(digest("nodetofind"))
        self.protocol.callFindNode(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.FIND_NODE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callDelete(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callDelete(n, digest("Keyword"), digest("Key"), digest("Signature"))

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.DELETE)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], digest("Signature"))

    def test_acceptResponse(self):
        self._connecting_to_connected()

        def handle_response(resp):
            self.assertTrue(resp[0])
            self.assertEqual(resp[1][0], "test")
            self.assertTrue(message_id not in self.protocol._outstanding)

        message_id = digest("msgid")
        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        d = defer.Deferred()
        self.protocol._outstanding[message_id] = (d, self.addr1, reactor.callLater(5, handle_response))
        self.protocol._acceptResponse(message_id, ["test"], n)

        return d.addCallback(handle_response)

    def test_unknownRPC(self):
        self.assertFalse(self.handler.receive_message(str(random.getrandbits(1400))))

    def test_timeout(self):

        def handle_response(resp, n):
            self.assertFalse(resp[0])
            self.assertIsNone(resp[1])
            self.assertTrue(self.protocol.router.isNewNode(n))

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        d = defer.Deferred().addCallback(handle_response, n)
        self.protocol._outstanding["msgID"] = [d, self.addr1]
        self.protocol.router.addContact(n)
        self.protocol.timeout(self.addr1, n)

    def test_transferKeyValues(self):
        self._connecting_to_connected()
        self.wire_protocol[self.addr1] = self.con

        self.protocol.router.addContact(mknode())

        self.protocol.storage[digest("keyword")] = (
            digest("key"), self.protocol.sourceNode.getProto().SerializeToString(), 10)
        self.protocol.storage[digest("keyword")] = (
            digest("key2"), self.protocol.sourceNode.getProto().SerializeToString(), 10)

        self.protocol.transferKeyValues(Node(digest("id"), self.addr1[0], self.addr1[1]))

        self.clock.advance(1)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload
        x = message.Message()
        x.ParseFromString(sent_message)

        i = objects.Inv()
        i.keyword = digest("keyword")
        i.valueKey = digest("key")

        i2 = objects.Inv()
        i2.keyword = digest("keyword")
        i2.valueKey = digest("key2")

        m = message.Message()
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("INV")
        m.protoVer = self.version
        m.arguments.append(i.SerializeToString())
        m.arguments.append(i2.SerializeToString())
        self.assertEqual(x.sender, m.sender)
        self.assertEqual(x.command, m.command)
        self.assertTrue(x.arguments[0] in m.arguments)
        self.assertTrue(x.arguments[1] in m.arguments)

    def test_refreshIDs(self):
        node1 = Node(digest("id1"), "127.0.0.1", 12345, signed_pubkey=digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, signed_pubkey=digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, signed_pubkey=digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        for b in self.protocol.router.buckets:
            b.lastUpdated = (time.time() - 5000)
        ids = self.protocol.getRefreshIDs()
        self.assertTrue(len(ids) == 1)

    def _connecting_to_connected(self):
        remote_synack_packet = packet.Packet.from_data(
            42,
            self.con.own_addr,
            self.con.dest_addr,
            ack=0,
            syn=True
        )
        self.con.receive_packet(remote_synack_packet)

        self.clock.advance(0)
        connection.REACTOR.runUntilCurrent()

        self.next_remote_seqnum = 43

        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_syn_packet = packet.Packet.from_bytes(m_calls[0][0][0])
        seqnum = sent_syn_packet.sequence_number

        self.handler_mock.reset_mock()
        self.proto_mock.reset_mock()

        self.next_seqnum = seqnum + 1

    def test_badRPCDelete(self):
        n = mknode()
        val = self.protocol.rpc_delete(n, 'testkeyword', 'key', 'testsig')
        self.assertEqual(val, ["False"])
        val = self.protocol.rpc_delete(n, '', '', '')
コード例 #20
0
class KademliaProtocolTest(unittest.TestCase):
    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.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, True)
        self.protocol = KademliaProtocol(self.node, self.storage, 20)

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

        self.protocol.connect_multiplexer(self.wire_protocol)
        self.handler = self.wire_protocol.ConnHandler([self.protocol])
        self.handler.connection = self.con

        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)

    def tearDown(self):
        self.con.shutdown()
        self.wire_protocol.shutdown()

    def test_invalid_datagram(self):
        self.assertFalse(self.handler.receive_message("hi"))
        self.assertFalse(
            self.handler.receive_message(
                "hihihihihihihihihihihihihihihihihihihihih"))

    def test_rpc_ping(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("PING")
        data = m.SerializeToString()
        m.arguments.append(
            self.protocol.sourceNode.getProto().SerializeToString())
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_store(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.extend([
            digest("Keyword"), "Key",
            self.protocol.sourceNode.getProto().SerializeToString()
        ])
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("True")
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

    def test_rpc_delete(self):
        self._connecting_to_connected()

        # Set a keyword to store
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.extend([
            digest("Keyword"), "Key",
            self.protocol.sourceNode.getProto().SerializeToString()
        ])
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("True")
        expected_message1 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        # Test bad signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.arguments.extend([digest("Keyword"), "Key", "Bad Signature"])
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("False")
        expected_message2 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list)
        self.assertEqual(sent_packets[0].payload, expected_message1)
        self.assertEqual(sent_packets[1].payload, expected_message2)
        self.proto_mock.send_datagram.call_args_list = []

        # Test good signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.arguments.extend(
            [digest("Keyword"), "Key",
             self.signing_key.sign("Key")[:64]])
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("True")
        expected_message3 = m.SerializeToString()
        self.handler.receive_message(data)
        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        self.assertEqual(sent_packet.payload, expected_message3)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") is None)

    def test_rpc_stun(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STUN")
        data = m.SerializeToString()
        m.arguments.extend([self.public_ip, str(self.port)])
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_node(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_NODE")
        m.arguments.append(digest("nodetofind"))
        data = m.SerializeToString()
        del m.arguments[-1]
        m.arguments.extend([
            node2.getProto().SerializeToString(),
            node1.getProto().SerializeToString(),
            node3.getProto().SerializeToString()
        ])
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_value(self):
        self._connecting_to_connected()

        # Set a value to find
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.extend([
            digest("Keyword"), "Key",
            self.protocol.sourceNode.getProto().SerializeToString()
        ])
        data = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        # Send the find_value rpc
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.arguments.append(digest("Keyword"))
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        value = objects.Value()
        value.valueKey = "Key"
        value.serializedData = self.protocol.sourceNode.getProto(
        ).SerializeToString()
        m.arguments.append("value")
        m.arguments.append(value.SerializeToString())
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list)
        received_message = sent_packets[1].payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 3)

    def test_rpc_find_without_value(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.arguments.append(digest("Keyword"))
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        m.arguments.extend([
            node3.getProto().SerializeToString(),
            node1.getProto().SerializeToString(),
            node2.getProto().SerializeToString()
        ])
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        m = message.Message()
        m.ParseFromString(received_message)

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_callPing(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callPing(n)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid,
                         m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey,
                         m.sender.signedPublicKey)
        self.assertTrue(m.command == message.PING)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1],
                         self.addr1)

    def test_callStore(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callStore(
            n, digest("Keyword"), digest("Key"),
            self.protocol.sourceNode.getProto().SerializeToString())

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid,
                         m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey,
                         m.sender.signedPublicKey)
        self.assertTrue(m.command == message.STORE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1],
                         self.addr1)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(
            m.arguments[2],
            self.protocol.sourceNode.getProto().SerializeToString())

    def test_callFindValue(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        keyword = Node(digest("Keyword"))
        self.protocol.callFindValue(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid,
                         m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey,
                         m.sender.signedPublicKey)
        self.assertTrue(m.command == message.FIND_VALUE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1],
                         self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callFindNode(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        keyword = Node(digest("nodetofind"))
        self.protocol.callFindNode(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid,
                         m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey,
                         m.sender.signedPublicKey)
        self.assertTrue(m.command == message.FIND_NODE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1],
                         self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callDelete(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callDelete(n, digest("Keyword"), digest("Key"),
                                 digest("Signature"))

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1],
                         self.addr1)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid,
                         m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey,
                         m.sender.signedPublicKey)
        self.assertTrue(m.command == message.DELETE)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], digest("Signature"))

    def test_acceptResponse(self):
        self._connecting_to_connected()

        def handle_response(resp):
            self.assertTrue(resp[0])
            self.assertEqual(resp[1][0], self.protocol.sourceNode.id)

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        d = self.protocol.callPing(n)

        self.clock.advance(1)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        timeout = reactor.callLater(5, self.protocol._timeout, m.messageID)
        self.protocol._outstanding[m.messageID] = (d, timeout)
        m.arguments.append(self.protocol.sourceNode.id)
        self.handler.receive_message(m.SerializeToString())

        return d.addCallback(handle_response)

    def test_unknownRPC(self):
        self.assertFalse(
            self.handler.receive_message(str(random.getrandbits(1400))))

    def test_timeout(self):
        self._connecting_to_connected()
        self.wire_protocol[self.addr1] = self.con

        def test_remove_outstanding():
            self.assertTrue(len(self.protocol._outstanding) == 0)

        def test_deffered(d):
            self.assertFalse(d[0])
            test_remove_outstanding()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        d = self.protocol.callPing(n)
        self.clock.advance(6)
        connection.REACTOR.runUntilCurrent()
        self.clock.advance(6)
        return d.addCallback(test_deffered)

    def test_transferKeyValues(self):
        self._connecting_to_connected()
        self.wire_protocol[self.addr1] = self.con

        self.protocol.addToRouter(mknode())

        self.protocol.storage[digest("keyword")] = (
            digest("key"),
            self.protocol.sourceNode.getProto().SerializeToString())
        self.protocol.transferKeyValues(
            Node(digest("id"), self.addr1[0], self.addr1[1]))

        self.clock.advance(1)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(
            self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload
        x = message.Message()
        x.ParseFromString(sent_message)

        m = message.Message()
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.append(digest("keyword"))
        m.arguments.append(digest("key"))
        m.arguments.append(
            self.protocol.sourceNode.getProto().SerializeToString())
        self.assertEqual(x.sender, m.sender)
        self.assertEqual(x.command, m.command)
        self.assertEqual(x.arguments[0], m.arguments[0])
        self.assertEqual(x.arguments[1], m.arguments[1])
        self.assertEqual(x.arguments[2], m.arguments[2])

    def test_refreshIDs(self):
        node1 = Node(digest("id1"),
                     "127.0.0.1",
                     12345,
                     signed_pubkey=digest("key1"))
        node2 = Node(digest("id2"),
                     "127.0.0.1",
                     22222,
                     signed_pubkey=digest("key2"))
        node3 = Node(digest("id3"),
                     "127.0.0.1",
                     77777,
                     signed_pubkey=digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        for b in self.protocol.router.buckets:
            b.lastUpdated = (time.time() - 5000)
        ids = self.protocol.getRefreshIDs()
        self.assertTrue(len(ids) == 1)

    def _connecting_to_connected(self):
        remote_synack_packet = packet.Packet.from_data(42,
                                                       self.con.own_addr,
                                                       self.con.dest_addr,
                                                       ack=0,
                                                       syn=True)
        self.con.receive_packet(remote_synack_packet)

        self.clock.advance(0)
        connection.REACTOR.runUntilCurrent()

        self.next_remote_seqnum = 43

        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_syn_packet = packet.Packet.from_bytes(m_calls[0][0][0])
        seqnum = sent_syn_packet.sequence_number

        self.handler_mock.reset_mock()
        self.proto_mock.reset_mock()

        self.next_seqnum = seqnum + 1

    def test_badRPCDelete(self):
        n = mknode()
        val = self.protocol.rpc_delete(n, 'testkeyword', 'key', 'testsig')
        self.assertEqual(val, ["False"])
        val = self.protocol.rpc_delete(n, '', '', '')
コード例 #21
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()
コード例 #22
0
 def test_iterkeys(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     for k in p.iterkeys():
         self.assertEqual(k[0].decode("hex"), self.keyword1)
コード例 #23
0
 def test_iteritems(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     for k, v in p.iteritems(self.keyword1):
         self.assertEqual((self.key1, self.value), (k, v))
コード例 #24
0
 def test_getSpecific(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     self.assertEqual(self.value, p.getSpecific(self.keyword1, self.key1))
コード例 #25
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()
コード例 #26
0
 def test_getitem(self):
     f = ForgetfulStorage()
     tdict = TTLDict(3)
     tdict[self.key1] = self.value
     f[self.keyword1] = (self.key1, self.value, 10)
     self.assertEqual(tdict, f[self.keyword1])
コード例 #27
0
 def test_delete(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value, 10)
     f.delete(self.keyword1, self.key1)
     self.assertEqual(f.get(self.keyword1), None)
コード例 #28
0
 def test_iterkeys(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value, 10)
     for k in f.iterkeys():
         self.assertEqual(k, self.keyword1)
コード例 #29
0
 def test_ttl(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, .000000000001)
     self.assertTrue(p.get(self.keyword1) is None)
コード例 #30
0
 def test_ttl(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, .000000000001)
     self.assertTrue(p.get(self.keyword1) is None)
コード例 #31
0
ファイル: test_storage.py プロジェクト: Renelvon/Network
 def test_getSpecific(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value)
     self.assertEqual(self.value, f.getSpecific(self.keyword1, self.key1))
コード例 #32
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()
コード例 #33
0
class KademliaProtocolTest(unittest.TestCase):
    def setUp(self):
        self.version = PROTOCOL_VERSION
        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.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, objects.FULL_CONE, True)
        self.db = datastore.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, objects.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.handler.connection = self.con

        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)

    def tearDown(self):
        if self.con.state != connection.State.SHUTDOWN:
            self.con.shutdown()
        self.wire_protocol.shutdown()
        os.remove("test.db")

    def test_invalid_datagram(self):
        self.assertFalse(self.handler.receive_message("hi"))
        self.assertFalse(self.handler.receive_message("hihihihihihihihihihihihihihihihihihihihih"))

    def test_rpc_ping(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("PING")
        m.protoVer = self.version
        m.testnet = False
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        m.arguments.append(self.protocol.sourceNode.getProto().SerializeToString())
        m.ClearField("signature")
        expected_message = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        m2 = message.Message()
        m2.ParseFromString(received_message)
        m2.ClearField("signature")
        received_message = m2.SerializeToString()

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_store(self):
        self._connecting_to_connected()
        self.protocol.router.addContact(self.protocol.sourceNode)

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key",
                            self.protocol.sourceNode.getProto().SerializeToString(), str(10)])
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        del m.arguments[-4:]
        m.arguments.append("True")
        m.ClearField("signature")
        expected_message = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        m2 = message.Message()
        m2.ParseFromString(received_message)
        m2.ClearField("signature")
        received_message = m2.SerializeToString()
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

    def test_bad_rpc_store(self):
        r = self.protocol.rpc_store(self.node, 'testkeyword', 'kw', 'val', 10)
        self.assertEqual(r, ['False'])

    def test_rpc_delete(self):
        self._connecting_to_connected()
        self.protocol.router.addContact(self.protocol.sourceNode)

        # Set a keyword to store
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key",
                            self.protocol.sourceNode.getProto().SerializeToString(), str(10)])
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        del m.arguments[-4:]
        m.arguments.append("True")
        m.ClearField("signature")
        expected_message1 = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        # Test bad signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key", "Bad Signature"])
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("False")
        m.ClearField("signature")
        expected_message2 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list
        )
        m2 = message.Message()
        m2.ParseFromString(sent_packets[0].payload)
        m2.ClearField("signature")
        received_message1 = m2.SerializeToString()
        m3 = message.Message()
        m3.ParseFromString(sent_packets[1].payload)
        m3.ClearField("signature")
        received_message2 = m3.SerializeToString()
        self.assertEqual(received_message1, expected_message1)
        self.assertEqual(received_message2, expected_message2)
        self.proto_mock.send_datagram.call_args_list = []

        # Test good signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.extend([digest("Keyword"), "Key", self.signing_key.sign("Key")[:64]])
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        del m.arguments[-3:]
        m.arguments.append("True")
        m.ClearField("signature")
        expected_message3 = m.SerializeToString()
        self.handler.receive_message(data)
        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        m4 = message.Message()
        m4.ParseFromString(sent_packet.payload)
        m4.ClearField("signature")
        received_message = m4.SerializeToString()
        self.assertEqual(received_message, expected_message3)
        self.assertTrue(self.storage.getSpecific(digest("Keyword"), "Key") is None)

    def test_rpc_stun(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STUN")
        m.protoVer = self.version
        m.testnet = False
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        m.arguments.extend([self.public_ip, str(self.port)])
        m.ClearField("signature")
        expected_message = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        a.ClearField("signature")
        received_message = a.SerializeToString()
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_node(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"), nat_type=objects.FULL_CONE)
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"), nat_type=objects.FULL_CONE)
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"), nat_type=objects.FULL_CONE)
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_NODE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.append(digest("nodetofind"))
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        del m.arguments[-1]
        m.arguments.extend([node2.getProto().SerializeToString(), node1.getProto().SerializeToString(),
                            node3.getProto().SerializeToString()])
        m.ClearField("signature")
        expected_message = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        a.ClearField("signature")
        received_message = a.SerializeToString()
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_value(self):
        self._connecting_to_connected()
        self.protocol.router.addContact(self.protocol.sourceNode)

        # Set a value to find
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.protoVer = self.version
        m.arguments.extend([digest("Keyword"), "Key",
                            self.protocol.sourceNode.getProto().SerializeToString(), str(10)])
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)
        self.assertTrue(
            self.storage.getSpecific(digest("Keyword"), "Key") ==
            self.protocol.sourceNode.getProto().SerializeToString())

        # Send the find_value rpc
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.append(digest("Keyword"))
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        value = objects.Value()
        value.valueKey = "Key"
        value.serializedData = self.protocol.sourceNode.getProto().SerializeToString()
        value.ttl = 10
        m.arguments.append("value")
        m.arguments.append(value.SerializeToString())
        m.ClearField("signature")
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list
        )
        received_message = sent_packets[1].payload
        a = message.Message()
        a.ParseFromString(received_message)
        a.ClearField("signature")
        received_message = a.SerializeToString()

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 3)

    def test_rpc_find_without_value(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"), nat_type=objects.FULL_CONE)
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"), nat_type=objects.FULL_CONE)
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"), nat_type=objects.FULL_CONE)
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.protoVer = self.version
        m.testnet = False
        m.arguments.append(digest("Keyword"))
        m.signature = self.signing_key.sign(m.SerializeToString())[:64]
        data = m.SerializeToString()
        self.handler.on_connection_made()
        self.handler.receive_message(data)

        del m.arguments[-1]
        m.arguments.extend([node3.getProto().SerializeToString(), node1.getProto().SerializeToString(),
                            node2.getProto().SerializeToString()])
        m.ClearField("signature")
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        a = message.Message()
        a.ParseFromString(received_message)
        a.ClearField("signature")
        received_message = a.SerializeToString()

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_callPing(self):
        self._connecting_to_connected()

        n = Node(digest("guid"), self.addr1[0], self.addr1[1], digest("pubkey"), None, objects.FULL_CONE, False)
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callPing(n)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().publicKey, m.sender.publicKey)
        self.assertTrue(m.command == message.PING)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)

    def test_callStore(self):
        self._connecting_to_connected()

        n = Node(digest("guid"), self.addr1[0], self.addr1[1], digest("pubkey"), None, objects.FULL_CONE, False)
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callStore(n, digest("Keyword"), digest("Key"),
                                self.protocol.sourceNode.getProto().SerializeToString(), 10)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().publicKey, m.sender.publicKey)
        self.assertTrue(m.command == message.STORE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], self.protocol.sourceNode.getProto().SerializeToString())

    def test_callFindValue(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        keyword = Node(digest("Keyword"))
        self.protocol.callFindValue(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().publicKey, m.sender.publicKey)
        self.assertTrue(m.command == message.FIND_VALUE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callFindNode(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        keyword = Node(digest("nodetofind"))
        self.protocol.callFindNode(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().publicKey, m.sender.publicKey)
        self.assertTrue(m.command == message.FIND_NODE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callDelete(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.wire_protocol[self.addr1] = self.con
        self.protocol.callDelete(n, digest("Keyword"), digest("Key"), digest("Signature"))

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().publicKey, m.sender.publicKey)
        self.assertTrue(m.command == message.DELETE)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], digest("Signature"))

    def test_acceptResponse(self):
        self._connecting_to_connected()

        def handle_response(resp):
            self.assertTrue(resp[0])
            self.assertEqual(resp[1][0], "test")
            self.assertTrue(message_id not in self.protocol._outstanding)

        message_id = digest("msgid")
        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        d = defer.Deferred()
        self.protocol._outstanding[message_id] = (d, self.addr1, reactor.callLater(5, handle_response))
        self.protocol._acceptResponse(message_id, ["test"], n)

        return d.addCallback(handle_response)

    def test_unknownRPC(self):
        self.assertFalse(self.handler.receive_message(str(random.getrandbits(1400))))

    def test_timeout(self):

        def handle_response(resp, n):
            self.assertFalse(resp[0])
            self.assertIsNone(resp[1])

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        d = defer.Deferred().addCallback(handle_response, n)
        self.protocol._outstanding["msgID"] = [d, self.addr1, reactor.callLater(5, handle_response)]
        self.protocol.router.addContact(n)
        self.protocol.timeout(n)

    def test_transferKeyValues(self):
        self._connecting_to_connected()
        self.wire_protocol[self.addr1] = self.con

        self.protocol.storage[digest("keyword")] = (
            digest("key"), self.protocol.sourceNode.getProto().SerializeToString(), 10)
        self.protocol.storage[digest("keyword")] = (
            digest("key2"), self.protocol.sourceNode.getProto().SerializeToString(), 10)

        self.protocol.transferKeyValues(Node(digest("id"), self.addr1[0], self.addr1[1]))

        self.clock.advance(1)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload
        x = message.Message()
        x.ParseFromString(sent_message)

        i = objects.Inv()
        i.keyword = digest("keyword")
        i.valueKey = digest("key")

        i2 = objects.Inv()
        i2.keyword = digest("keyword")
        i2.valueKey = digest("key2")

        m = message.Message()
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("INV")
        m.protoVer = self.version
        m.arguments.append(i.SerializeToString())
        m.arguments.append(i2.SerializeToString())
        self.assertEqual(x.sender.guid, m.sender.guid)
        self.assertEqual(x.command, m.command)
        self.assertTrue(x.arguments[0] in m.arguments)
        self.assertTrue(x.arguments[1] in m.arguments)

    def test_refreshIDs(self):
        node1 = Node(digest("id1"), "127.0.0.1", 12345, pubkey=digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, pubkey=digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, pubkey=digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        for b in self.protocol.router.buckets:
            b.lastUpdated = (time.time() - 5000)
        ids = self.protocol.getRefreshIDs()
        self.assertTrue(len(ids) == 1)

    def _connecting_to_connected(self):
        remote_synack_packet = packet.Packet.from_data(
            42,
            self.con.own_addr,
            self.con.dest_addr,
            ack=0,
            syn=True
        )
        self.con.receive_packet(remote_synack_packet, self.addr1)

        self.clock.advance(0)
        connection.REACTOR.runUntilCurrent()

        self.next_remote_seqnum = 43

        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_syn_packet = packet.Packet.from_bytes(m_calls[0][0][0])
        seqnum = sent_syn_packet.sequence_number

        self.handler_mock.reset_mock()
        self.proto_mock.reset_mock()

        self.next_seqnum = seqnum + 1

    def test_badRPCDelete(self):
        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        val = self.protocol.rpc_delete(n, 'testkeyword', 'key', 'testsig')
        self.assertEqual(val, ["False"])
        val = self.protocol.rpc_delete(n, '', '', '')
コード例 #34
0
ファイル: test_storage.py プロジェクト: Renelvon/Network
 def test_iteritems(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value)
     for k, v in f.iteritems(self.keyword1):
         self.assertEqual((self.key1, self.value), (k, v))
コード例 #35
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(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)
コード例 #36
0
 def test_getSpecific(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     self.assertEqual(self.value, p.getSpecific(self.keyword1, self.key1))
コード例 #37
0
 def test_getSpecific(self):
     f = ForgetfulStorage()
     f[self.keyword1] = (self.key1, self.value)
     self.assertEqual(self.value, f.getSpecific(self.keyword1, self.key1))
コード例 #38
0
 def test_delete(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     p.delete(self.keyword1, self.key1)
     self.assertEqual(p.get(self.keyword1), None)
コード例 #39
0
 def test_delete(self):
     p = ForgetfulStorage()
     p[self.keyword1] = (self.key1, self.value, 10)
     p.delete(self.keyword1, self.key1)
     self.assertEqual(p.get(self.keyword1), None)
コード例 #40
0
ファイル: test_protocol.py プロジェクト: Renelvon/Network
class KademliaProtocolTest(unittest.TestCase):

    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.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, True)
        self.protocol = KademliaProtocol(self.node, self.storage, 20)

        self.handler = self.protocol.RPCHandler(False, 5, self.protocol._outstanding, self.protocol)
        self.handler.connection = self.con

        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.protocol.makeConnection(transport)

    def tearDown(self):
        self.con.shutdown()
        self.protocol.shutdown()

    def test_invalid_datagram(self):
        self.assertFalse(self.handler.receive_message("hi"))
        self.assertFalse(self.handler.receive_message("hihihihihihihihihihihihihihihihihihihihih"))

    def test_rpc_ping(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("PING")
        data = m.SerializeToString()
        m.arguments.append(self.protocol.sourceNode.getProto().SerializeToString())
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_store(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.extend(["Keyword", "Key", self.protocol.sourceNode.getProto().SerializeToString()])
        data = m.SerializeToString()
        for i in range(0, 3):
            del m.arguments[-1]
        m.arguments.append("True")
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload
        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)
        self.assertTrue(self.storage.getSpecific("Keyword", "Key") == self.protocol.sourceNode.getProto().SerializeToString())

    def test_rpc_delete(self):
        self._connecting_to_connected()

        # Set a keyword to store
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.extend(["Keyword", "Key", self.protocol.sourceNode.getProto().SerializeToString()])
        data = m.SerializeToString()
        for i in range(0, 3):
            del m.arguments[-1]
        m.arguments.append("True")
        expected_message1 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(self.storage.getSpecific("Keyword", "Key") == self.protocol.sourceNode.getProto().SerializeToString())

        # Test bad signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.arguments.extend(["Keyword", "Key", "Bad Signature"])
        data = m.SerializeToString()
        for i in range(0, 3):
            del m.arguments[-1]
        m.arguments.append("False")
        expected_message2 = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(self.storage.getSpecific("Keyword", "Key") == self.protocol.sourceNode.getProto().SerializeToString())

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list
        )
        self.assertEqual(sent_packets[0].payload, expected_message1)
        self.assertEqual(sent_packets[1].payload, expected_message2)
        self.proto_mock.send_datagram.call_args_list = []

        # Test good signature
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("DELETE")
        m.arguments.extend(["Keyword", "Key", self.signing_key.sign("Key")[:64]])
        data = m.SerializeToString()
        for i in range(0, 3):
            del m.arguments[-1]
        m.arguments.append("True")
        expected_message3 = m.SerializeToString()
        self.handler.receive_message(data)
        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        self.assertEqual(sent_packet.payload, expected_message3)
        self.assertTrue(self.storage.getSpecific("Keyword", "Key") is None)

    def test_rpc_stun(self):
        self._connecting_to_connected()

        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STUN")
        data = m.SerializeToString()
        m.arguments.extend([self.addr1[0], str(self.addr1[1])])
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_node(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_NODE")
        m.arguments.append(digest("nodetofind"))
        data = m.SerializeToString()
        del m.arguments[-1]
        m.arguments.extend([node3.getProto().SerializeToString(), node2.getProto().SerializeToString(), node1.getProto().SerializeToString()])
        expected_message = m.SerializeToString()
        self.handler.receive_message(data)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_rpc_find_value(self):
        self._connecting_to_connected()

        # Set a value to find
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.extend(["Keyword", "Key", self.protocol.sourceNode.getProto().SerializeToString()])
        data = m.SerializeToString()
        self.handler.receive_message(data)
        self.assertTrue(self.storage.getSpecific("Keyword", "Key") == self.protocol.sourceNode.getProto().SerializeToString())

        # Send the find_value rpc
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.arguments.append("Keyword")
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        value = message.Value()
        value.valueKey = "Key"
        value.serializedData = self.protocol.sourceNode.getProto().SerializeToString()
        m.arguments.append("value")
        m.arguments.append(value.SerializeToString())
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packets = tuple(
            packet.Packet.from_bytes(call[0][0])
            for call in self.proto_mock.send_datagram.call_args_list
        )
        received_message = sent_packets[1].payload

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 3)

    def test_rpc_find_without_value(self):
        self._connecting_to_connected()

        node1 = Node(digest("id1"), "127.0.0.1", 12345, digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        m = message.Message()
        m.messageID = digest("msgid")
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("FIND_VALUE")
        m.arguments.append(digest("Keyword"))
        data = m.SerializeToString()
        self.handler.receive_message(data)

        del m.arguments[-1]
        m.arguments.extend([node2.getProto().SerializeToString(), node3.getProto().SerializeToString(), node1.getProto().SerializeToString()])
        expected_message = m.SerializeToString()

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        received_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(received_message)

        self.assertEqual(received_message, expected_message)
        self.assertEqual(len(m_calls), 2)

    def test_callPing(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.protocol[self.addr1] = self.con
        self.protocol.callPing(n)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.PING)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)

    def test_callStore(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.protocol[self.addr1] = self.con
        self.protocol.callStore(n, digest("Keyword"), digest("Key"), self.protocol.sourceNode.getProto().SerializeToString())

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.STORE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], self.protocol.sourceNode.getProto().SerializeToString())

    def test_callFindValue(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.protocol[self.addr1] = self.con
        keyword = Node(digest("Keyword"))
        self.protocol.callFindValue(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.FIND_VALUE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callFindNode(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.protocol[self.addr1] = self.con
        keyword = Node(digest("nodetofind"))
        self.protocol.callFindNode(n, keyword)

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.FIND_NODE)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertEqual(m.arguments[0], keyword.id)

    def test_callDelete(self):
        self._connecting_to_connected()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.protocol[self.addr1] = self.con
        self.protocol.callDelete(n, digest("Keyword"), digest("Key"), digest("Signature"))

        self.clock.advance(100 * constants.PACKET_TIMEOUT)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        self.assertEqual(self.proto_mock.send_datagram.call_args_list[0][0][1], self.addr1)
        self.assertTrue(len(m.messageID) == 20)
        self.assertEqual(self.protocol.sourceNode.getProto().guid, m.sender.guid)
        self.assertEqual(self.protocol.sourceNode.getProto().signedPublicKey, m.sender.signedPublicKey)
        self.assertTrue(m.command == message.DELETE)
        self.assertEqual(m.arguments[0], digest("Keyword"))
        self.assertEqual(m.arguments[1], digest("Key"))
        self.assertEqual(m.arguments[2], digest("Signature"))

    def test_acceptResponse(self):
        self._connecting_to_connected()

        def handle_response(resp):
            self.assertTrue(resp[0])
            self.assertEqual(resp[1][0], self.protocol.sourceNode.id)

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        self.protocol[self.addr1] = self.con
        d = self.protocol.callPing(n)

        self.clock.advance(1)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload

        m = message.Message()
        m.ParseFromString(sent_message)
        timeout = reactor.callLater(5, self.protocol._timeout, m.messageID)
        self.handler._outstanding[m.messageID] = (d, timeout)
        m.arguments.append(self.protocol.sourceNode.id)
        self.handler.receive_message(m.SerializeToString())

        return d.addCallback(handle_response)

    def test_unknownRPC(self):
        self.assertFalse(self.handler._acceptRequest(digest("msgid"), "unknown", [digest("argument")], Node(digest("nodeid"))))

    def test_timeout(self):
        self._connecting_to_connected()
        self.protocol[self.addr1] = self.con

        def test_remove_outstanding():
            self.assertTrue(len(self.protocol._outstanding) == 0)

        def test_deffered(d):
            self.assertFalse(d[0])
            test_remove_outstanding()

        n = Node(digest("S"), self.addr1[0], self.addr1[1])
        d = self.protocol.callPing(n)
        self.clock.advance(6)
        return d.addCallback(test_deffered)

    def test_transferKeyValues(self):
        self._connecting_to_connected()
        self.protocol[self.addr1] = self.con

        self.protocol.storage[digest("keyword")] = (digest("key"), self.protocol.sourceNode.getProto().SerializeToString())
        self.protocol.transferKeyValues(Node(digest("id"), self.addr1[0], self.addr1[1]))

        self.clock.advance(1)
        connection.REACTOR.runUntilCurrent()
        sent_packet = packet.Packet.from_bytes(self.proto_mock.send_datagram.call_args_list[0][0][0])
        sent_message = sent_packet.payload
        x = message.Message()
        x.ParseFromString(sent_message)

        m = message.Message()
        m.sender.MergeFrom(self.protocol.sourceNode.getProto())
        m.command = message.Command.Value("STORE")
        m.arguments.append(digest("keyword"))
        m.arguments.append(digest("key"))
        m.arguments.append(self.protocol.sourceNode.getProto().SerializeToString())
        self.assertEqual(x.sender, m.sender)
        self.assertEqual(x.command, m.command)
        self.assertEqual(x.arguments[0], m.arguments[0])
        self.assertEqual(x.arguments[1], m.arguments[1])
        self.assertEqual(x.arguments[2], m.arguments[2])

    def test_refreshIDs(self):
        node1 = Node(digest("id1"), "127.0.0.1", 12345, signed_pubkey=digest("key1"))
        node2 = Node(digest("id2"), "127.0.0.1", 22222, signed_pubkey=digest("key2"))
        node3 = Node(digest("id3"), "127.0.0.1", 77777, signed_pubkey=digest("key3"))
        self.protocol.router.addContact(node1)
        self.protocol.router.addContact(node2)
        self.protocol.router.addContact(node3)
        for b in self.protocol.router.buckets:
            b.lastUpdated = (time.time() - 5000)
        ids = self.protocol.getRefreshIDs()
        self.assertTrue(len(ids) == 1)

    def _connecting_to_connected(self):
        remote_synack_packet = packet.Packet.from_data(
            42,
            self.con.own_addr,
            self.con.dest_addr,
            ack=0,
            syn=True
        )
        self.con.receive_packet(remote_synack_packet)

        self.clock.advance(0)
        connection.REACTOR.runUntilCurrent()

        self.next_remote_seqnum = 43

        m_calls = self.proto_mock.send_datagram.call_args_list
        sent_syn_packet = packet.Packet.from_bytes(m_calls[0][0][0])
        seqnum = sent_syn_packet.sequence_number

        self.handler_mock.reset_mock()
        self.proto_mock.reset_mock()

        self.next_seqnum = seqnum + 1