A Kademlia Distributed Hash Table for LibP2P
The Kademlia Distributed Hash Table (DHT) subsystem in libp2p is a DHT implementation largely based on the Kademlia [0] whitepaper, augmented with notions from S/Kademlia [1], Coral [2] and the BitTorrent DHT.
The libp2p Kademlia DHT offers the following types of operations:
-
Peer routing
- Finding the closest nodes to a given key via
FIND_NODE
.
- Finding the closest nodes to a given key via
-
Value storage and retrieval
-
Storing a value on the nodes closest to the value's key by looking up the closest nodes via
FIND_NODE
and then putting the value to those nodes viaPUT_VALUE
. -
Getting a value by its key from the nodes closest to that key via
GET_VALUE
.
-
-
Content provider advertisement and discovery
-
Adding oneself to the list of providers for a given key at the nodes closest to that key by finding the closest nodes via
FIND_NODE
and then adding oneself viaADD_PROVIDER
. -
Getting providers for a given key from the nodes closest to that key via
GET_PROVIDERS
.
-
In addition the libp2p Kademlia DHT offers the auxiliary bootstrap operation.
- For more information check out the Kad DHT Spec
Include the following dependency in your Package.swift file
let package = Package(
...
dependencies: [
...
.package(name: "LibP2PKadDHT", url: "https://github.com/swift-libp2p/swift-libp2p-kad-dht.git", .upToNextMajor(from: "0.0.1"))
],
...
)
check out the tests for more examples
import LibP2PKadDHT
let app = Application(.detect())
/// If you'd like to use the DHT as a DHT...
app.dht.use( .kadDHT )
/// Or if you're just interested in its peer discovery functionality
app.discovery.use(.kadDHT)
extension StorageKeys {
static let MyDHT = "MyDHT"
}
let dht = BasicKadDHT(protocolPrefix: "mydht", version: "1.0.0", k: 20, alpha: 4, peerstore: .shared(app.peerstore) ?? .basicInMemory, kvstore: .basicInMemory...)
app.use(dht, id: .MyDHT)
dht.handle(namespace: "pk", valueAs: PublicKey.self, withValidator: { msg in msg.record.value.multihash == msg.key && msg.key }).onPutSuccess({ msg in ... }).onPutFailed({ msg, error in ...})
dht.handle(namespace: "ipfs", valueAs: IPNSRecord.self, withValidator: { msg in ... }).onPutSuccess({ msg in ... }).onPutFailed({ msg, error in ...})
// ... or ...
app.dht.group("myDHT") { myDHT in
myDHT.on("pk", validator: ...) { pk in ... }
myDHT.on("ipld", validator: ...) { ipld in ... }
}
/// Somewhere else without reference to `dht`
app.dht.getValue(forKey: "Qm12...") { value in .... } //if you only have one DHT running
/// or
app.dhts.for(id: .MyDHT).put(value: Record, forKey: "Qm12...") { success in ... }
/// or
let val = await app.dhts.for(id: "MyDHT").findNode("Qm13...")
let routingTableInfo = await app.dhts.for(id: "MyDHT").routingTableInfo()
}
Contributions are welcomed! This code is very much a proof of concept. I can guarantee you there's a better / safer way to accomplish the same results. Any suggestions, improvements, or even just critques, are welcome!
Let's make this code better together! 🤝
- MPLEX Spec
- [0]: Maymounkov, P., & Mazières, D. (2002). Kademlia: A Peer-to-Peer Information System Based on the XOR Metric. In P. Druschel, F. Kaashoek, & A. Rowstron (Eds.), Peer-to-Peer Systems (pp. 53–65). Berlin, Heidelberg: Springer Berlin Heidelberg.
- [1]: Baumgart, I., & Mies, S. (2014). S / Kademlia : A practicable approach towards secure key-based routing S / Kademlia : A Practicable Approach Towards Secure Key-Based Routing, (June).
- [2]: Freedman, M. J., & Mazières, D. (2003). Sloppy Hashing and Self-Organizing Clusters. In IPTPS. Springer Berlin / Heidelberg. Retrieved from
- bittorrent
- uvarint-spec
- ping
- go-libp2p-xor
MIT © 2022 Breth Inc.