Routing 在torrent kademlia路由表上实现查找节点

Routing 在torrent kademlia路由表上实现查找节点,routing,bittorrent,dht,kademlia,Routing,Bittorrent,Dht,Kademlia,一、 我们已经审阅了许多关于这个主题的文件,但有些内容并不十分清楚。例如,BitTorrent文档()状态 路由表细分为“bucket”,每个bucket包含一个 空间的一部分。空表有一个ID为空格的bucket 最小值范围为0,最大值范围为2^160。将ID为“N”的节点插入到 表,它被放置在具有最小 它与关于kademlia路由表的其他文档有所不同,在kademlia路由表中,bucket是根据节点id的位前缀排列的,但还有另一件令人困惑的事情 bittorrent规范描述的路由表实现仅与。

一、 我们已经审阅了许多关于这个主题的文件,但有些内容并不十分清楚。例如,BitTorrent文档()状态

路由表细分为“bucket”,每个bucket包含一个 空间的一部分。空表有一个ID为空格的bucket 最小值范围为0,最大值范围为2^160。将ID为“N”的节点插入到 表,它被放置在具有最小 它与关于kademlia路由表的其他文档有所不同,在kademlia路由表中,bucket是根据节点id的位前缀排列的,但还有另一件令人困惑的事情

bittorrent规范描述的路由表实现仅与。它更容易实现,但也有一些缺点

例如,如果我们取这个bucket,从左边取一个,从右边取一个,然后搜索XOR最近的节点ID,我们将找到我们要查找的,并且没有必要遍历路由表中的所有节点

在完整的树状路由表实现和简化的BEP5变体中,每个bucket都可以被视为具有一个(请参阅)由bucket覆盖的前缀位和掩码位计数组成

在BEP5变体中,每个bucket的前缀都是从数组索引和节点自己的ID派生出来的。在类似树的表中,由于bucket拆分/合并操作,bucket必须跟踪其前缀

使用这些前缀可以找到覆盖目标密钥的bucket

问题是存储桶不必满,如果您想发送,假设一个响应中有20个节点,单个存储桶就不够了

因此,您必须以相对于目标键的升序距离(XOR)顺序遍历路由表(根据您自己的节点ID排序或按自然距离排序),才能访问多个bucket

由于XOR距离度量在每个位进位处折叠(XOR==少进位加法),因此它不能很好地映射到任何路由表布局。换句话说,拜访最近的水桶是不行的

用于从树状路由表中查找距离特定目标键最近的N个节点

我认为很多人只是简单地迭代整个路由表,因为对于常规节点,它最多只包含几十个bucket,而DHT节点看不到太多的流量,因此它只需要每秒执行几次此操作,如果以密集方式实现,缓存友好的数据结构那么最大的份额实际上可能是内存流量,而不是执行一些XOR和比较的CPU指令

也就是说,全表扫描很容易实现


假设我们有一个路由表,每个bucket都有以下位前缀。这些字母用作方便的名称)

现在让我们假设我们正在寻找这个目标键:

T = 0010011010111111001111100101011000001010010100001100100010011100000000100100000111001101100110110110101100010100111010111001101111110101001001001000100000001001
此外,存储桶并不是完全满的,或者我们需要比单个存储桶中的任何内容都多的条目,因此我们必须访问多个存储桶才能获得所需的数量

现在,要访问的第一个bucket非常明显,它是
B
,因为它的前缀覆盖了目标键

由于
B
的前缀长度为5位,因此该存储桶中的任何条目都将与
T
具有异或距离
00000?????…
。共享5个前缀位

B
是距离
T
最近的bucket,这意味着没有任何路由表条目比相对距离
00000…
更近。相反,这意味着
B
之外的任何条目可以拥有的最小距离是
00001…
。这意味着下一个最近的存储桶必须覆盖
T xor 00001…->001011101111110[…]

覆盖此区域的铲斗为
H

H
B

最终-假设我们必须访问6个桶-订单如下所示:

00100...      -> B
001011...     -> H
001010101...  -> F
0010101000... -> D
0010101001... -> E
00101011...   -> G
这似乎相当混乱。但是如果我们为每个访问的bucket绘制前缀到目标关键点的距离,它会变得更加明显:

00000...
000010...
000011000...
0000110010...
0000110011...
00001101...
因此,算法如下所示:

  • 找到覆盖目标密钥的初始存储桶
  • 将bucket的前缀与目标键(零掩码尾随位)异或
  • 将距离增加该前缀的最低有效位
  • 使用目标键的异或递增距离
  • 找到覆盖XORed键的下一个桶
  • 转到2

  • TL;博士:“只看左一桶,右一桶”是不够的。正确的算法相当复杂,对整个表进行线性扫描更容易实现。

    经过一些测试,我发现我以前的答案实际上不正确,因此对其进行了更新,以反映正确且经过测试的算法。
    00000...
    000010...
    000011000...
    0000110010...
    0000110011...
    00001101...