Skip to main content

forest/tool/subcommands/
net_cmd.rs

1// Copyright 2019-2026 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3
4use crate::libp2p::ping::p2p_ping;
5use clap::Subcommand;
6use libp2p::Multiaddr;
7use std::time::Duration;
8
9#[derive(Debug, Subcommand)]
10pub enum NetCommands {
11    /// Ping a peer via its `multiaddress`
12    Ping {
13        /// Peer `multiaddress`
14        peer: Multiaddr,
15        /// The number of times it should ping
16        #[arg(short, long, default_value_t = 5)]
17        count: usize,
18        /// The minimum seconds between pings
19        #[arg(short, long, default_value_t = 1)]
20        interval: u64,
21    },
22}
23
24impl NetCommands {
25    pub async fn run(self) -> anyhow::Result<()> {
26        match self {
27            NetCommands::Ping {
28                peer,
29                count,
30                interval,
31            } => {
32                println!("PING {peer}");
33                let mut n_success = 0;
34                let mut total_duration = Duration::default();
35                for _ in 0..count {
36                    match p2p_ping(peer.clone()).await {
37                        Ok(duration) => {
38                            n_success += 1;
39                            total_duration += duration;
40                            println!("Pong received: time={}ms", duration.as_millis())
41                        }
42                        Err(error) => {
43                            println!("Ping failed: error={error}")
44                        }
45                    }
46                    tokio::time::sleep(Duration::from_secs(interval)).await;
47                }
48                if n_success > 0 {
49                    let avg_ms = total_duration.as_millis() / n_success;
50                    println!("Average latency: {avg_ms}ms");
51                }
52            }
53        }
54
55        Ok(())
56    }
57}