kademlia 最近的好节点在两个请求之间不会相交

kademlia closest good nodes won't intersect enough between two requests

致力于 bep44 实现,我使用定义的 kademlia 算法找到给定哈希 ID 的最近的好节点。

我使用我的程序 go run main.go -put "Hello World!" -kname mykey -salt foobar2 -b public 并获取存储在一百个节点上的值(好)。

现在,当我运行它连续多次时,put请求写入的ip集合很差。

这是一个问题,因为当我尝试执行 get 请求时,查询的 ips 集与 put 集不相交,因此找不到该值。

在我的测试中,我使用 public dht bootstrap 节点

        "router.utorrent.com:6881",
        "router.bittorrent.com:6881",
        "dht.transmissionbt.com:6881",

当我查询节点时,我 select 8 个最近的节点 (nodes := s.ClosestGoodNodes(8, msg.InfoHash())),通常在递归遍历后最终出现在 ~1K 查询列表中。

根据我的理解,考虑到 table 的状态,在 dht table 中存储信息散列的地址是确定性的。当我进行连续查询时,我希望 table 确实会发生变化,但变化不大。

商店节点集不相交怎么办?

由于BEP44是一个扩展,它只被DHT节点的一个子集支持,这意味着迭代查找机制在确定最近节点集是否为stable时需要考虑支持可以终止查找。

如果节点 returns 在获取响应中有 tokenvseq 字段,则它有资格获得最接近的读取集仅得到.

如果节点 returns 是 token 那么它有资格获得 get 的最近集合,然后是 put操作.

因此您的查找可能会定位到键空间中最接近目标 ID 但不符合相关操作条件的一组节点。只要您有比最知名的合格联系人更接近的候选人,您就必须继续搜索。我称此为周边扩大,因为它在概念上扩大了目标周围的搜索区域。

此外,在执行 put 请求时,您还需要考虑错误响应或缺少响应。您可以重试该节点或尝试下一个符合条件的节点。

我在我自己的 DHT 实现的文档中写下了一些 additional constraints 出于稳健性和安全性原因,人们可能希望将其放在最接近的查找集上。

which usually end up in a list of ~1K queries after a recursive traversal.

这表明您的查找算法有问题。根据我的经验,如果您正在使用并发请求进行查找,则查找应该只需要 60 到 200 个 udp 请求就可以找到它的目标,如果是顺序请求,可能会更少。

Verbose logs 的终端集会关注查找的进展情况以及我从同行那里得到多少垃圾对我很有帮助。

In my tests i use the public dht bootstrap node

您应该将您的路由 table 写入磁盘并从那里重新加载它,并且仅当您的 RT 中的 none 个持久节点可访问时才执行 bootstrapping。否则你会浪费 bootstrap 节点的资源,并且在执行任何查找之前必须先重新填充你的路由 table 也会浪费时间。