DHT(Discovery)Community

This document contains a description of how to use the DHTCommunity class for distributed hash table (DHT) data storage and the DHTDiscoveryCommunity extension of this functionality, which provides functionality to connect given public keys.

In particular this document will not discuss how distributed hash table work, for this we refer the reader to other resources on the Internet.

Storing values and finding keys

The DHTCommunity is the main overlay that allows for decentralized key-value storage. There are two main functions in this overlay: the store_value() function and the find_values() function.

When you call store_value(), you choose the globally unique key that your given value data is stored under. You can, but are not required to, sign this new stored value with your public key to provide it with authenticity. Note that this function may lead to a ipv8.dht.DHTError: in this case, you will have to try again later. An example of a call that stores the signed value b"my value" under the key b"my key", is the following.

    try:
        await dht_community.store_value(b"my key", b"my value", True)
        print(dht_community.my_peer.public_key.key_to_bin(), "published b'my value' under b'my key'!")
    except DHTError as e:
        print("Failed to store my value under my key!", e)

The value can later be retrieved from the network by calling find_values() with the key that the information was stored under. The following snippet retrieves the value that was stored in the previous snippet, under the b"my key" key.

    try:
        results = await dht_community.find_values(b"my key")
        print(f"We got results from {len(results)} peers!")
        for value, signer_key in results:
            print(f"The value {value} was found, signed by {signer_key}")
    except DHTError as e:
        print("Failed to find key!", e)

Note that multiple peers may respond with answers and if (a) the orginal value is not signed or (b) multiple values are published under the same key, the reported values may be different. In this example, only one value is published and it is signed so only a single value is ever returned.

Finding peers

The DHTDiscoveryCommunity allows for peers to be found by their public key. You can search for public keys by their SHA-1 hash (conveniently available as Peer.mid). To do so, you can call connect_peer() with the hash/mid as shown in the following example.

    some_peer_mid = instances[2].keys["anonymous id"].mid
    while True:
        try:
            await sleep(0.5)
            await dht_discovery_community.connect_peer(some_peer_mid)
            break
        except DHTError as e:
            print("Failed to connect to peer!", e)

Note that you may need a few attempts to find the peer you are looking for. Of course, if the peer you are looking for is not online, you may be waiting forever.