示例#1
0
    def transferKeyValues(self, node):
        """
        Given a new node, send it all the keys/values it should be storing.

        @param node: A new node that just joined (or that we just found out
        about).

        Process:
        For each key in storage, get k closest nodes.  If newnode is closer
        than the furtherst in that list, and the node for this server
        is closer than the closest in that list, then store the key/value
        on the new node (per section 2.5 of the paper)
        """
        def send_values(inv_list):
            values = []
            if inv_list[0]:
                for requested_inv in inv_list[1]:
                    try:
                        i = objects.Inv()
                        i.ParseFromString(requested_inv)
                        value = self.storage.getSpecific(i.keyword, i.valueKey)
                        if value is not None:
                            v = objects.Value()
                            v.keyword = i.keyword
                            v.valueKey = i.valueKey
                            v.serializedData = value
                            v.ttl = int(round(self.storage.get_ttl(i.keyword, i.valueKey)))
                            values.append(v.SerializeToString())
                    except Exception:
                        pass
                if len(values) > 0:
                    self.callValues(node, values)

        inv = []
        for keyword in self.storage.iterkeys():
            keyword = keyword[0].decode("hex")
            keynode = Node(keyword)
            neighbors = self.router.findNeighbors(keynode, exclude=node)
            if len(neighbors) > 0:
                newNodeClose = node.distanceTo(keynode) < neighbors[-1].distanceTo(keynode)
                thisNodeClosest = self.sourceNode.distanceTo(keynode) < neighbors[0].distanceTo(keynode)
            if len(neighbors) == 0 \
                    or (newNodeClose and thisNodeClosest) \
                    or (thisNodeClosest and len(neighbors) < self.ksize):
                # pylint: disable=W0612
                for k, v in self.storage.iteritems(keyword):
                    i = objects.Inv()
                    i.keyword = keyword
                    i.valueKey = k
                    inv.append(i.SerializeToString())
        if len(inv) > 100:
            random.shuffle(inv)
        if len(inv) > 0:
            self.callInv(node, inv[:100]).addCallback(send_values)
示例#2
0
 def rpc_inv(self, sender, *serlialized_invs):
     self.addToRouter(sender)
     ret = []
     for inv in serlialized_invs:
         try:
             i = objects.Inv()
             i.ParseFromString(inv)
             if self.storage.getSpecific(i.keyword, i.valueKey) is None:
                 ret.append(inv)
         except Exception:
             pass
     return ret
示例#3
0
    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)
示例#4
0
 def send_values(inv_list):
     values = []
     if inv_list[0]:
         for requested_inv in inv_list[1]:
             try:
                 i = objects.Inv()
                 i.ParseFromString(requested_inv)
                 value = self.storage.getSpecific(i.keyword, i.valueKey)
                 if value is not None:
                     v = objects.Value()
                     v.keyword = i.keyword
                     v.valueKey = i.valueKey
                     v.serializedData = value
                     v.ttl = int(round(self.storage.get_ttl(i.keyword, i.valueKey)))
                     values.append(v.SerializeToString())
             except Exception:
                 pass
         if len(values) > 0:
             self.callValues(node, values)