How to implement Kademlia DHT

408 views Asked by At

I'm trying to implement the Kademlia(binary tree) DHT in python. From what I understand the routing table needs to compare the individual bits from a root node's ID against a new entry. If the ID's bits do not match, you go left, if they match, you go right. This can be done recursively and your stopping condition is either that you have reached the end of the length of the ID's or that you have reached a leaf node. Then each leaf node contains its own kbucket (an array).

Currently what I have tried is the following:

#!/usr/bin/python

class Node:
    def __init__(self, id, data):
        self.id = id
        self.data = data
        self.left = None
        self.right = None

    def __str__(self):
        return '{id:' + self.id + ',' + self.data + '}'

class Tree:
    def __init__(self):
        self.root = None

    def find_placement(self, node, previous_node, id_index):
        if (node == None):
            return previous_node, id_index
        elif (node.right == None and node.left == None):
            return node, id_index
        elif (node.id[id_index] == previous_node.id[id_index]):
            return self.find_placement(node.right, node, id_index+1)
        elif (node.id[id_index] != previous_node.id[id_index]):
            return self.find_placement(node.left, node, id_index+1)
 
    def add(self, id, data):
        new_node = Node(id, data)
        if (self.root == None):
            self.root = new_node
            return
        previous_node = current_node = self.root
        id_index = 0
        current_node, id_index = self.find_placement(current_node, previous_node, id_index)
        if (current_node.id[id_index] == new_node.id[id_index]):
            current_node.right = new_node
        elif (current_node.id[id_index] != new_node.id[id_index]):
            current_node.left = new_node
        new_node.parent = current_node

    def printtree(self, node=None, level=0, lr = ''):
        if (node == None):
            node = self.root
        
        print (lr, level, node)
        if (node.left != None):
            self.printtree(node.left, level+1, 'L')
        if (node.right != None):
            self.printtree(node.right, level+1, 'R')



if __name__ == "__main__":
    t = Tree()
    t.add('0000','test')
    t.add('0100','test')
    t.add('0010','test')
    t.add('0001','test')
    t.add('0101','test')

    t.printtree()

Currently what I attempt to do is find a leaf node that the new node could be a child of.

Could anyone help me figure out what I'm doing wrong exactly? If I have left out anything that's needed I apologize in advance and welcome any suggestions on how I could make this post better!

I guess what my problem is this:

Currently my nodes are sorted according to the first bit that contradicts the bit at the same index of the root node. Instead what I need to do is have the nodes sorted such that the rightmost node is your own node after bootstrapping.

If this is the case, what would the root node be? Is there a way to do this where the root node is your own node while still maintaining the integrity of the network?

After adding a new node to the network, how would I restructure the tree to maintain the rule that the branches you traverse (each new fork) represents a single bit in a leaf node's id? To the point that the rightmost node is the closest node to your own and the leftmost would be the one furthest away.

The tree can be elaborated on more here: https://www.researchgate.net/publication/2492563_Kademlia_A_Peer-to-peer_Information_System_Based_on_the_XOR_Metric

0

There are 0 answers