libp2p-rs v0.2.0 already supports Kad-DHT, which supports nodes to discover nodes and content through the DHT network.
This article mainly shows how to use DHT in libp2p-rs , and lists some APIs of swarm and kad.
Use kad
step1: Create swarm
let sec = secio::Config::new(keys.clone());
let mux = yamux::Config::new();
let tu = TransportUpgrade::new(TcpConfig::default(), mux, sec);
let mut swarm = Swarm::new(keys.public())
.with_transport(Box::new(tu))
.with_identify(IdentifyConfig::new(false));
swarm.listen_on(vec![listen_addr]).expect("listen on");
let mut swarm_control = swarm.control();
step2: create kad
let store = MemoryStore::new(swarm.local_peer_id().clone());
let kad = Kademlia::new(swarm.local_peer_id().clone(), store);
let kad_handler = kad.handler();
let mut kad_ctrl = kad.control();
step3: register kad
Upgrade swarm to have routing function.
// register handler to swarm
swarm = swarm.with_protocol(Box::new(kad_handler)).with_routing(Box::new(kad_ctrl.clone()));
step4: start kad and swarm
kad.start(swarm_control.clone());
swarm.start();
step5: use kad
First add the bootstrap node to the peerstore and routing table, and then start bootstrap.
kad_control.add_node(bootstrap_peer, vec![bootstrap_addr]).await;
kad_control.bootstrap().await;
step6: enable cli
Integrated cli, can debug swarm and kad.
let mut app = App::new("xCLI").version("v0.1").author("[email protected]");
app.add_subcommand_with_userdata(swarm_cli_commands(), Box::new(swarm_control.clone()));
app.add_subcommand_with_userdata(dht_cli_commands(), Box::new(kad_control.clone()));
app.run();
cli debugging
The following only lists some of the commonly used debugging commands. For more ways to play, please unlock it yourself.
swarm connection
The connection command can be used to obtain information about all current connections and their substreams, or to obtain connection information with a certain peer.
# s con
CID DIR Remote-Peer-Id I/O Remote-Multiaddr
231 In Qmf3ZX3yHnmzaXFGH5G149HyrAeKRFantVnZ9gZdnuPv1U 2/0 /ip4/114.227.83.230/tcp/24792
(231 Sid(7) In /ipfs/kad/1.0.0)
(231 Sid(9) In /ipfs/kad/1.0.0)
161 In QmZC9dZPyJWXSB2Ao2ChGJMjfuFiT7TyKdsGsFEKVSqnnf 0/0 /ip4/212.102.37.201/tcp/4001
2185 In QmTmnqSEarcSLJxhehJRKX64pxSkeKn7jS2fDEZFjjt9Bn 1/0 /ip4/114.226.44.86/tcp/3109
(2185 Sid(7) In /ipfs/kad/1.0.0)
2069 In 12D3KooWPtfLkqAVMPP6FNufHvqxPYe55XuAdEZWUn2cPbLLAwuT 1/0 /ip4/111.16.39.80/tcp/17881
(2069 Sid(1) In /ipfs/kad/1.0.0)
2349 In QmVcXP4bnoCJkUUJinduuM68n5jfSjDj6sKaTjRhHoecpt 1/0 /ip4/83.248.150.24/tcp/42761
(2349 Sid(3) In /ipfs/kad/1.0.0)
492 In 12D3KooWKBkFNUCvyP5PbV2mAhrzcvPi4EPL4vD3CjieGGU9ZcQr 1/0 /ip4/203.145.95.60/tcp/64417
(492 Sid(1) In /ipfs/kad/1.0.0)
18 In QmP6waLA8S6M8WPoQ5tWPE6xpgtsJ44LGQcq7vDTUAmyob 1/0 /ip4/188.127.190.220/tcp/4001
(18 Sid(7) In /ipfs/kad/1.0.0)
# s con Qmf3ZX3yHnmzaXFGH5G149HyrAeKRFantVnZ9gZdnuPv1U
CID DIR Remote-Peer-Id I/O Remote-Multiaddr
231 In Qmf3ZX3yHnmzaXFGH5G149HyrAeKRFantVnZ9gZdnuPv1U 2/0 /ip4/114.227.83.230/tcp/24792
(231 Sid(7) In /ipfs/kad/1.0.0)
(231 Sid(9) In /ipfs/kad/1.0.0)
dht states
States is used to count the running status of iterative queries, and you can also observe the number of Kad requests received by the current node.
# d st
Total refreshes : 1
Successful queries : 4
Timeout queries : 0
Query details : QueryStats { requests: 59, success: 41, failure: 10, duration: 18.198653932s }
Kad rx messages : MessageStats { ping: 0, find_node: 17216, get_provider: 559, add_provider: 3667, get_value: 1, put_value: 27 }
dht dump
The dump command is used to dump out the routing table information, and use verbose to print detailed information.
# d dp
Index Entries Active
244 1 1
246 1 1
247 2 2
248 7 7
249 10 8
250 20 20
251 20 20
252 20 20
253 20 20
254 20 19
255 20 20
# d dp 1
Index Entries Active
244 1 1
Qme9PR5oDcSSGoS2He53RqaML4vinDD5CNgxxmV2qPefFP Conn(false) Some(52292.68894773s) Addrs([])
246 1 1
QmboRZYso6VdQ5yfXe1DAj9u8EqouZGUsf2inoqYDtzdf8 Conn(true) Some(4330.367016609s) Addrs([])
247 2 2
QmZsbivLpaVpWQ4Mum2nzbEcoXbH7QbftRkQCmmJiTqcUp Conn(false) Some(77688.875853187s) Addrs([])
QmZaCQ6anyaPuebhLeomzpyKRAY6GnNS5NCU8h7kSjwFKN Conn(false) Some(43775.12096365s) Addrs(["/ip4/127.0.0.1/tcp/4001", "/ip4/138.68.29.104/tcp/4001", "/ip4/10.46.0.6/tcp/4001", "/ip4/10.138.16.85/tcp/4001", "/ip6/::1/tcp/4001"])
API introduction
At present, the APIs of swarm and kad are relatively complete. Only some commonly used APIs are listed below. For more APIs, please read the source code directly.
swarm
peerstore
/// Gets the public key by peer_id.
pub fn get_key(&self, peer_id: &PeerId) -> Option<PublicKey>
/// Gets all multiaddr of a peer.
pub fn get_addrs(&self, peer_id: &PeerId) -> Option<Vec<Multiaddr>>
/// Adds a address to address_book by peer_id, if exists, update rtt.
pub fn add_addr(&self, peer_id: &PeerId, addr: Multiaddr, ttl: Duration)
/// Adds many new addresses if they're not already in the peer store.
pub fn add_addrs(&self, peer_id: &PeerId, addrs: Vec<Multiaddr>, ttl: Duration)
/// Clears all multiaddr of a peer from the peer store.
pub fn clear_addrs(&self, peer_id: &PeerId)
connection
/// Make a new connection towards the remote peer with addresses specified.
pub async fn connect_with_addrs(&mut self, peer_id: PeerId, addrs: Vec<Multiaddr>) -> Result<()>
/// Make a new connection towards the remote peer.
///
/// It will lookup the peer store for address of the peer, otherwise
/// initiate the routing interface for querying the addresses, if routing
/// is available.
pub async fn new_connection(&mut self, peer_id: PeerId) -> Result<()>
/// Make a new connection towards the remote peer, without using routing(Kad-DHT).
pub async fn new_connection_no_routing(&mut self, peer_id: PeerId) -> Result<()>
/// Close connection towards the remote peer.
pub async fn disconnect(&mut self, peer_id: PeerId) -> Result<()>
stream
/// Open a new outbound stream towards the remote peer.
///
/// It will lookup the peer store for address of the peer,
/// otherwise initiate the routing interface for address querying,
/// when routing is enabled. In the end, it will open an outgoing
/// sub-stream when the connection is eventually established.
pub async fn new_stream(&mut self, peer_id: PeerId, pids: Vec<ProtocolId>) -> Result<Substream>
/// Open a new outbound stream towards the remote peer, without routing.
pub async fn new_stream_no_routing(&mut self, peer_id: PeerId, pids: Vec<ProtocolId>) -> Result<Substream>
/// Open a new outbound stream towards the remote peer, without routing.
pub async fn new_stream_no_routing(&mut self, peer_id: PeerId, pids: Vec<ProtocolId>) -> Result<Substream>
when
/// Add a node and its listening addresses to KBuckets.
pub async fn add_node(&mut self, peer_id: PeerId, addrs: Vec<Multiaddr>)
/// Add a node and its listening addresses to KBuckets.
pub async fn remove_node(&mut self, peer_id: PeerId)
/// Initiate bootstrapping.
///
/// In general it should be done only once upon Kad startup.
pub async fn bootstrap(&mut self)
/// Lookup the closer peers with the given key.
pub async fn lookup(&mut self, key: record::Key) -> Result<Vec<KadPeer>>
/// Lookup the given peer.
pub async fn find_peer(&mut self, peer_id: &PeerId) -> Result<KadPeer>
/// Put value in local and other peers which closest to the given key.
pub async fn put_value(&mut self, key: Vec<u8>, value: Vec<u8>) -> Result<()>
/// Get value from local and other peers which closest to the given key.
pub async fn get_value(&mut self, key: Vec<u8>) -> Result<Vec<u8>>
/// Announce to peers which closer to the given key that self provide content.
pub async fn provide(&mut self, key: Vec<u8>) -> Result<()>
/// Find peers who provide content.
pub async fn find_providers(&mut self, key: Vec<u8>, count: usize) -> Option<Vec<KadPeer>>
to sum up
After starting kad and swarm, you can call the API through the controller. The current
swarm API is relatively complete, and it can now support a more complex protocol such as Kad-DHT, which also creates conditions for the addition of new protocols.
Netwarps is composed of a senior cloud computing and distributed technology development team in China. The team has very rich experience in the financial, power, communications and Internet industries. Netwarps currently has R&D centers in Shenzhen and Beijing, with a team size of 30+, most of which are technicians with more than ten years of development experience, from professional fields such as the Internet, finance, cloud computing, blockchain, and scientific research institutions.
Netwarps focuses on the development and application of secure storage technology products. The main products include decentralized file system (DFS) and decentralized computing platform (DCP), and are committed to providing distributed storage and distributed based on decentralized network technology. The computing platform has the technical characteristics of high availability, low power consumption and low network, and is suitable for scenarios such as the Internet of Things and Industrial Internet.
Official account: Netwarps