libp2p-rs kad usage and debugging method

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

Guess you like

Origin blog.51cto.com/14915984/2596842