hashinfo是否等效于Mainline DHT中的对等ID?

时间:2019-05-27 11:59:53

标签: p2p bittorrent dht kademlia

我正在处理Mainline DHT,但我不了解其中的细微差别。

在这里:https://www.bittorrent.org/beps/bep_0005.html写道:““距离度量”用于比较两个节点ID或一个节点ID与一个信息散列来比较“紧密度”。

还写道:“宣布控制查询节点的对等方正在端口上下载torrent。announce_peer具有四个参数:“ id”包含查询节点的节点ID,“ info_hash”包含查询节点的ID种子,“ port”(包含端口的整数),以及响应先前的get_peers查询而收到的“令牌”。”

因此,例如,我们有一个ID为223456789zxcvbnmasdf的对等方,其IP为86.23.145.714,端口为:7853 我知道这个同龄人下载了2个带有信息哈希值的torrent文件:023456789zxcvbnmasdf和123456789zxcvbnmasdf。

那么我的k-bucket记录应该是什么样子? 像这样:

{"id": "223456789zxcvbnmasdf", "ip": "86.23.145.714", "port": "7853", "torrents": ["023456789zxcvbnmasdg", "123456789zxcvbnmasdh"]} ?

或者,torrent文件应该像对等体一样,在k-buckets中像“等效”记录(具有重复的ip和端口):

{"id": "223456789zxcvbnmasdf", "ip": "86.23.145.714", "port": "7853"},

{"id": "023456789zxcvbnmasdg", "ip": "86.23.145.714", "port": "7853"},

{"id": "123456789zxcvbnmasdh", "ip": "86.23.145.714", "port": "7853"} ?

我在问,因为这不仅仅是实现方面的细微差别。因为“ k”在所有客户端中通常为20或其他整数。因此,如果我使用k-bucket将torrent文件存储为完全拥有权限的成员,那么我将没有多少空间来存储真实的对等数据。

感谢答案!

2 个答案:

答案 0 :(得分:1)

如何内部构造数据取决于您自己。它所要做的就是履行规格合同。原则上,您可以根据异或距离将洪流与水桶相关联,例如出于资源核算的原因–但是大多数实现将路由表和存储区分开。

主要路由表仅包含节点,它们是DHT覆盖本身的结构成员。另一方面,洪流不属于叠加层。它们是存储在叠加层(哈希表抽象)顶部的数据。因此,名称为“分布式哈希表”。即它们存在于不同的抽象级别。

答案 1 :(得分:0)

k-buckets数据结构是bit-torrent协议的一种实现细节,因此同级可以足够快地回复FIND_PEERSFIND_VALUE

在我的kademlia实现中,我所做的就是将路由表保存在python字典中,并且默认情况下,我会在5秒内计算最近的对等点,这是我等待UDP答复所用的超时。为此,我需要将路由表保持在1000万以下。

就像我上面所说的,路由表是一个简单的Python dict,它将peerid映射到(address, port)

路由表存储对等体而不是值。不是infohash个地址。

当我收到一条FIND_PEERS消息时,该程序将回复以下代码:

async def peers(self, address, uid):
    """Remote procedure that returns peers that are near UID"""
    log.debug("[%r] find peers uid=%r from %r", self._uid, uid, address)
    # XXX: if this takes more than 5 seconds (see RPCProtocol) it
    # will timeout in the other side.
    uids = nearest(self._replication, self._peers.keys(), uid)
    out = [self._peers[x] for x in uids]
    return out

当我收到一条FIND_VALUE消息时,该程序将回复以下代码:

async def value(self, address, key):
    """Remote procedure that returns the associated value or peers that
    are near KEY"""
    log.debug("[%r] value key=%r from %r", self._uid, key, address)
    out = await lookup(key)
    if out is None:
        # value is not found, reply with peers that are near KEY
        out = nearest(self._replication, self._peers.keys(), uid)
        return (b"PEERS", out)
    else:
        return (b"VALUE", out)

这是nearest的定义:

def nearest(k, peers, uid):
    """Return K nearest to to UID peers in PEERS according to XOR"""
    # XXX: It only works with len(peers) < 10^6 more than that count
    # of peers and the time it takes to compute the nearest peers will
    # timeout after 5 seconds on the other side. See RPCProtocol and
    # Peer.peers.
    return nsmallest(k, peers, key=functools.partial(operator.xor, uid))

这是根据peerspeerid进行排序并返回最小的k的结果。 nsmallest应该是sort(peers, key=functools.partial(operator.xor, uid))[:k]的优化版本,其中uidpeeridinfohash(分别是FIND_PEERSFIND_VALUE )。

现在回到您的问题:

  

hashinfo是否等效于Mainline DHT中的对等ID?

hashinfo是一种哈希值,与peerid相同,即哈希值。它们是路由表中的可能键。也就是说,torrent文件与哈希关联,对等节点与称为peerid的同类哈希关联。同行拥有peerid附近的密钥的“所有权”。但是,hashinfo不会存储在路由表或k-bucket中。 hashinfo存储在另一个将hashinfo哈希值与其值关联的映射中。

  

我在问,因为这不仅仅是实现方面的细微差别。因为“ k”在所有客户端中通常为20或其他整数。因此,如果我使用k-bucket将torrent文件存储为完全拥有权限的成员,那么我将没有多少空间来存储真实的对等数据。

对于我在上面尝试解释的同一件事,这里存在误解。 hashinfo是存储字典中的键。而peerid是路由表中的密钥。 k桶数据结构。它们都具有相同的格式,因为这是kademlia路由算法的工作方式。您必须能够将hashinfopeeridxor进行比较,才能分辨出哪个对等方“拥有”哪个hashinfo的价值。

在第二个片段中可以看到,当另一个同位体询问与哈希相关的值时,它调用lookup(key)类似于storage.get(key),但在我的情况下,代码将值存储在数据库。


关于使用k-bucket存储 DHT路由信息这一事实,可能存在误解。而且最重要的种子协议使用DHT存储 种子路由信息。


对于它的价值,qadom's peer.py file是我实施从kademlia启发而来的DHT的地方(除了我使用256位哈希并放弃alphak参数并使用单个{{ 1}}参数)。该代码大部分时间都有效检查测试。

另外,还有一个我从名为kademlia的项目中得到了启发,该项目(试图实现)实现了k-buckets。

据我了解,洪流DHT路由看起来像qadom bag functions,但接收方必须对通知进行身份验证,而在qadom包中则是免费的。

还请检查原始的卡德姆里亚纸。