Beispiel #1
0
    def test_ne(self):
        a = Kbucket(20, 0, 63, 5, 7)
        n = Node(None, None, 100)
        self.assertTrue(a != n)

        n = Node(None, None, 50)
        self.assertFalse(a != n)
Beispiel #2
0
    def test_ge(self):
        a = Kbucket(20, 64, 127, 5, 7)
        n = Node(None, None, 65)
        self.assertTrue(a >= n)

        n = Node(None, None, 128)
        self.assertFalse(a >= n)
Beispiel #3
0
    def test_eq(self):
        a = Kbucket(20, 0, 127, 5, 7)
        n = Node(None, None, 100)
        self.assertTrue(a == n)

        n = Node(None, None, 128)
        self.assertFalse(a == n)
Beispiel #4
0
    def test_le(self):
        a = Kbucket(20, 0, 63, 5, 7)
        n = Node(None, None, 63)
        self.assertTrue(a <= n)

        n = Node(None, None, -1)
        self.assertFalse(a <= n)
Beispiel #5
0
    def test_add_node(self):
        node = Node(None, None, 100)
        tree = RoutingTree(node, 2, 5, 5, 8)

        add_node = Node(None, None, 25)
        self.assertEqual(tree.addNode(add_node), None)
        index = tree.bucketIndex(add_node)
        self.assertIn(add_node, tree.buckets[index].nodes)
Beispiel #6
0
 def test_seen(self,time_mock):
     time_mock.time.return_value = 1000
     n = Node('127.0.0.1',5000,100)
     n.error()
     self.assertEquals(n.errors, 1)
     self.assertEquals(n.last_seen, 0)
     n.seen()
     self.assertEquals(n.errors, 0)
     self.assertEquals(n.last_seen, 1000)
Beispiel #7
0
 def setUp(self):
     self.key_space = 8
     self.bucket = Kbucket(5, 0, (2**self.key_space) - 1, 5, self.key_space)
     self.nodes = [
         Node(None, None, 0),
         Node(None, None, 25),
         Node(None, None, 50),
         Node(None, None, 255),
         Node(None, None, 230),
     ]
Beispiel #8
0
    def test_split(self):
        for n in self.nodes:
            self.bucket.addNode(n)

        expected_kept = [
            Node(None, None, 0),
            Node(None, None, 25),
            Node(None, None, 50)
        ]
        expected_evicted = [Node(None, None, 255), Node(None, None, 230)]
        evicted = self.bucket.updateRange(128)
        self.assertEquals(expected_evicted, evicted)
        self.assertEquals(expected_kept, self.bucket.nodes)
Beispiel #9
0
    def test_split_bucket(self):
        this = Node(None, None, 100)
        r = RoutingTree(this, 2, 5, 5, 8)
        nodes = [
            Node(None, None, 0),
            Node(None, None, 25),
            Node(None, None, 30),
            Node(None, None, 50),
            Node(None, None, 200),
            Node(None, None, 255),
            Node(None, None, 230),
        ]

        for node in nodes:
            r.addNode(node)

        # expected nodes split into buckets along with the bucket min/max
        expected = [(0, 15, [0]), (16, 31, [25, 30]), (32, 63, [50]),
                    (64, 127, [100]), (128, 191, []), (192, 223, [200]),
                    (224, 255, [255, 230])]

        for i in zip(r.buckets, expected):
            bucket, (mi, mx, nodes) = i
            self.assertEqual(bucket.range_min, mi)
            self.assertEqual(bucket.range_max, mx)
            for j in zip(bucket.nodes, nodes):
                self.assertEqual(j[0].id, j[1])
Beispiel #10
0
    def __init__(self, network, client_chan, node=None, alpha = 3):
        self.alpha = alpha       # concurrent network queries
        self.chan = client_chan  # channel for internal & network rpcs
        self.network = network   # interface to our network (nonblocking sends)

        if node == None:
            node = Node(None, None, None)

        self.addr, self.port = self.network.connect(self.chan.fetch_chan('rpc'), node.addr, node.port)
        node.addr = self.addr
        node.port = self.port

        if node.id is None:
            node.id = random.randint(1,2**160)

        self.node    = node

        self.routing = RoutingTree(self.node)

        self.rpc_actions = {
            'PING'         : self.rpc_handle_ping,
            'PONG'         : self.rpc_handle_pong,
            'STORE'        : self.rpc_handle_store,
            'FIND_VALUE'   : self.rpc_handle_find_value,
            'FIND_NODE'    : self.rpc_handle_find_node,
            'RETURN_NODE'  : self.rpc_handle_return_node,
            'RETURN_VALUE' : self.rpc_handle_return_value
        }

        self.internal_actions = {
            'ADD_NODE'           : self.int_add_node,
            'FIND_CLOSEST_NODES' : self.int_find_closest_nodes,
            'SEND_FIND_NODE'     : self.int_send_find_node,
            'REFRESH_BUCKETS'    : self.int_refresh_buckets,
            'STORE_VALUE'        : self.int_store_value,
            'SEND_FIND_VALUE'    : self.int_send_find_value
        }

        self.data_store = simple()
        self.rpc_xids = {}
        self.debug = True
Beispiel #11
0
 def rpc_handle_find_node(self, message):
     ''' rpc_handle_find_node looks for a node_id in the 'data
     portion of the message. The client then returns upto k
     nodes from our routing tree which are closest to the
     requested node.
     '''
     source = message['source']
     node_to_find = Node(None, None, message['data'])
     nodes = self.routing.findClosestNodes(node_to_find)
     m = self.rpc_create_message('RETURN_NODE', message['xid'])
     m['data'] = [(n.addr, n.port, n.id) for n in nodes]
     self.rpc_send_message(source.addr, source.port, m)
Beispiel #12
0
    def rpc_handle_message(self, m):
        ''' rpc_handle_message is the initial handler for all rpc messages
        the correct method will be called based on the message type
        '''
        if 'type' in m and m['type'] in self.rpc_actions:
            # add node into our routing tree
            node = Node(m['source'][0], m['source'][1], m['source'][2])
            self.routing.addNode(node)
            m['source'] = node

            # handle message
            self.rpc_actions[m['type']](m)
        else:
            self.log("process_message malformed message: %s" % m)
Beispiel #13
0
 def test_seen(self, time_mock):
     time_mock.time.return_value = 1000
     n = Node('127.0.0.1', 5000, 100)
     n.error()
     self.assertEquals(n.errors, 1)
     self.assertEquals(n.last_seen, 0)
     n.seen()
     self.assertEquals(n.errors, 0)
     self.assertEquals(n.last_seen, 1000)
Beispiel #14
0
    def _store_value(self, key, value):
        ''' _store_value is a blocking method call that stores
        a value under a key within the kad network

        nodes do not respond with an ack saying they

        '''

        key_hash = long(hashlib.sha1(key).hexdigest(), 16)
        nodes = self._node_lookup(Node(None, None, key_hash))
        for node in nodes:
            m, chan = self.create_message('STORE_VALUE')
            m['data']['key'] = key
            m['data']['key_hash'] = key_hash
            m['data']['value'] = value
            m['data']['node'] = node
            self.send_message(m)
Beispiel #15
0
    def rpc_handle_return_node(self, message):
        ''' rpc_handle_return_node handles a 'RETURN_NODE' message,
        add all returned nodes to the routing tree
        if there is a channel associated with this request then
        send the node list back
        '''
        if 'xid' in message and message['xid'] in self.rpc_xids:
            nodes = []

            for node in message['data']:
                n = Node(node[0], node[1], node[2])
                self.routing.addNode(n)
                nodes.append(n)

            if self.rpc_xids[message['xid']]['chan']:
                m = { 'timeout' : False, 'nodes' : nodes }
                self.rpc_xids[message['xid']]['chan'].put(m)

            del self.rpc_xids[message['xid']]
Beispiel #16
0
    def rpc_handle_find_value(self, message):
        ''' rpc_handle_find_value handles the rpc 'FIND_VALUE' message
        it either returns the value, if it is stored at this node or
        returns the closest k nodes to the requested key from our
        routing tree
        '''
        key_hash = message['data']['key_hash']
        source = message['source']
        value = self.data_store.retrieve(key_hash)
        if value is not None:
            response = { 'value' : value, 'found' : True }
        else:
            node_to_find = Node(None, None, key_hash)
            nodes = self.routing.findClosestNodes(node_to_find)
            nodes = [(n.addr, n.port, n.id) for n in nodes]
            response = { 'nodes' : nodes, 'found' : False }

        m = self.rpc_create_message('RETURN_VALUE', message['xid'])
        m['data'] = response
        self.rpc_send_message(source.addr, source.port, m)
Beispiel #17
0
 def test_create(self):
     n = Node('127.0.0.1', 5000, 100)
     self.assertIsInstance(n, Node)
Beispiel #18
0
 def test_create(self):
     r = RoutingTree(Node(None, None, 100))
     self.assertIsInstance(r, RoutingTree)
Beispiel #19
0
 def _fetch_value(self, key):
     ''' _fetch_value is a blocking method call that returns
     a value from the kad network or None if key is not found '''
     key_hash = long(hashlib.sha1(key).hexdigest(), 16)
     node = Node(None, None, key_hash)
     return self._node_lookup(node, key)
Beispiel #20
0
 def test_not_equal(self):
     a = Node('127.0.0.1', 5000, 100)
     b = Node('127.0.0.1', 5000, 500)
     self.assertNotEqual(a, b)
Beispiel #21
0
 def test_greater_than(self):
     a = Node('127.0.0.1', 5000, 100)
     b = Node('127.0.0.1', 5000, 500)
     self.assertTrue(b > a)
Beispiel #22
0
 def test_raises_KbucketWrong_exception(self):
     b = Kbucket(20, 0, 127, 5, 7)
     self.assertRaises(KbucketWrong, b.addNode, Node(None, None, 255))
Beispiel #23
0
    def test_raises_KbucketFull_exception(self):
        for n in self.nodes:
            self.bucket.addNode(n)

        self.assertRaises(KbucketFull, self.bucket.addNode,
                          Node(None, None, 231))
Beispiel #24
0
 def return_node(self):
     ''' return a copy of our node '''
     return Node(self.node.addr, self.node.port, self.node.id)
Beispiel #25
0
 def test_less_than(self):
     a = Node('127.0.0.1', 5000, 100)
     b = Node('127.0.0.1', 5000, 500)
     self.assertTrue(a < b)
 def createNodes(self, numberOfNodes):
     self.nodes = []
     for _ in range(numberOfNodes):
         self.nodes.append(Node(f'Node{_}'))