DHT InfoHash Lookup sequence. PeerID vs InfoHash

206 views Asked by At

I know there is a previous question about this somewhere on SO, but I cannot find it again. The relationship between NodeId and InfoHash. Is the following diagram roughly correct?

enter image description here

Background (no need to read)

I'm trying to implement my own DHT/bittorrent application in Java. I know that there are already some excellent implementations that I will never better. But this is purely a hedonistic pursuit. What was it Kennedy said? "we choose to do this not because it is easy.."

I have conquered the easy part, which is to write the low level socket handling and Remote Procedure Call syntax etc. Now I am on to the hard part, I must behave responsibly and service incoming requests on the DHT. (maintain KBuckets etc.)

1

There are 1 answers

0
amirouche On

Yes that diagram is correct. Here some python code that implements FIND_VALUE algorithm you describe:

async def _get(self, key):
    """Fetch the value associated with KEY from the network"""
    uid = pack(key)
    queried = set()
    while True:
        # retrieve the k nearest peers and remove already queried peers
        peers = await self.peers((None, None), uid)
        peers = [address for address in peers if address not in queried]
        # no more peer to query, the key is not found in the dht
        if not peers:
            raise KeyError(unpack(uid))
        # query selected peers
        queries = dict()
        for address in peers:
            query = self._protocol.rpc(address, "value", uid)
            queries[address] = query
        responses = await gather(queries, return_exceptions=True)
        for (address, response) in responses.items():
            queried.add(address)
            if isinstance(response, Exception):
                continue
            elif response[0] == b"VALUE":
                value = response[1]
                if hash(value) == unpack(uid):
                    # store it
                    @h.transactional
                    def add(tr, key, value):
                        tr.add("QADOM:MAPPING", key, "value", value)

                    await self._run(add, self._hoply, key, value)
                    # at last!
                    return value
                else:
                    log.warning(
                        "[%r] bad value returned from %r", self._uid, address
                    )
                    await self.blacklist(address)
                    continue
            elif response[0] == b"PEERS":
                await self._welcome_peers(response[1])
            else:
                await self.blacklist(address)
                log.warning(
                    "[%r] unknown response %r from %r",
                    self._uid,
                    response[0],
                    address,

This is extract from qadom project peer.py.