]> git.mxchange.org Git - quix0rs-apt-p2p.git/blobdiff - ktable.py
fix peer update problem connection refused in store value
[quix0rs-apt-p2p.git] / ktable.py
index 9cd373246ab1ea23cf556e9e939d1128bef272cf..aa86eb9bb66895024349a513afaa3b822a7764b6 100644 (file)
--- a/ktable.py
+++ b/ktable.py
@@ -5,10 +5,11 @@ from bisect import *
 import time
 from types import *
 
+import const
 from node import Node
 
 # The all-powerful, magical Kademlia "k" constant, bucket depth
-K = 20
+K = 8
 
 # how many bits wide is our hash?
 HASH_LENGTH = 160
@@ -60,27 +61,25 @@ class KTable:
        except ValueError:
            pass
        else:
-           self.buckets[i].touch()
            return [self.buckets[i].l[index]]
            
        nodes = nodes + self.buckets[i].l
-       if len(nodes) == K:
+       if len(nodes) >= K:
            nodes.sort(sort)
-           return nodes
+           return nodes[:K]
        else:
            # need more nodes
            min = i - 1
            max = i + 1
-           while (len(nodes) < K and (min >= 0 and max < len(self.buckets))):
+           while (len(nodes) < K and (min >= 0 or max < len(self.buckets))):
                if min >= 0:
                    nodes = nodes + self.buckets[min].l
-                   self.buckets[min].touch()
                if max < len(self.buckets):
                    nodes = nodes + self.buckets[max].l
-                   self.buckets[max].touch()
-               
+               min = min - 1
+               max = max + 1
            nodes.sort(sort)
-           return nodes[:K-1]
+           return nodes[:K]
 
     def _splitBucket(self, a):
        diff = (a.max - a.min) / 2
@@ -104,13 +103,16 @@ class KTable:
            return
 
        del(self.buckets[i].l[it])
-       self.buckets[i].l.append(new)
+       if new:
+           self.buckets[i].l.append(new)
 
-    def insertNode(self, node):
+    def insertNode(self, node, contacted=1):
        """ 
        this insert the node, returning None if successful, returns the oldest node in the bucket if it's full
        the caller responsible for pinging the returned node and calling replaceStaleNode if it is found to be stale!!
+       contacted means that yes, we contacted THEM and we know the node is available
        """
+       assert(node.id != " "*20)
        # get the bucket for this node
        i = self. _bucketIndexForInt(node.int)
        ## check to see if node is in the bucket already
@@ -120,16 +122,22 @@ class KTable:
            ## no
            pass
        else:
-           node.updateLastSeen()
-           # move node to end of bucket
-           del(self.buckets[i].l[it])
-           self.buckets[i].l.append(node)
-           self.buckets[i].touch()
+           if contacted:
+               node.updateLastSeen()
+               # move node to end of bucket
+               xnode = self.buckets[i].l[it]
+               del(self.buckets[i].l[it])
+               # note that we removed the original and replaced it with the new one
+               # utilizing this nodes new contact info
+               self.buckets[i].l.append(xnode)
+               self.buckets[i].touch()
            return
        
        # we don't have this node, check to see if the bucket is full
        if len(self.buckets[i].l) < K:
            # no, append this node and return
+           if contacted:
+               node.updateLastSeen()
            self.buckets[i].l.append(node)
            self.buckets[i].touch()
            return
@@ -162,7 +170,16 @@ class KTable:
            n.updateLastSeen()
            return tstamp
 
-
+    def nodeFailed(self, node):
+       """ call this when a node fails to respond to a message, to invalidate that node """
+       try:
+           n = self.findNodes(node.int)[0]
+       except IndexError:
+           return None
+       else:
+           if(n.msgFailed() >= const.MAX_FAILURES):
+               self.replaceStaleNode(n, None)
+       
 class KBucket:
     __slots = ['min', 'max', 'lastAccessed']
     def __init__(self, contents, min, max):
@@ -177,7 +194,6 @@ class KBucket:
     def getNodeWithInt(self, int):
        try:
            return self.l[self.l.index(int)]
-           self.touch()
        except IndexError:
            raise ValueError
        
@@ -218,11 +234,11 @@ import unittest
 
 class TestKTable(unittest.TestCase):
     def setUp(self):
-       self.a = Node(hash.newID(), 'localhost', 2002)
+       self.a = Node().init(hash.newID(), 'localhost', 2002)
        self.t = KTable(self.a)
 
     def test_replace_stale_node(self):
-       self.b = Node(hash.newID(), 'localhost', 2003)
+       self.b = Node().init(hash.newID(), 'localhost', 2003)
        self.t.replaceStaleNode(self.a, self.b)
        assert(len(self.t.buckets[0].l) == 1)
        assert(self.t.buckets[0].l[0].id == self.b.id)