alloy_provider/ext/
net.rs

1//! This module extends the Ethereum JSON-RPC provider with the Net namespace's RPC methods.
2use crate::Provider;
3use alloy_network::Network;
4use alloy_transport::TransportResult;
5
6/// Net namespace rpc interface that provides access to network information of the node.
7#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
8#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
9pub trait NetApi<N>: Send + Sync {
10    /// Returns a `bool` indicating whether or not the node is listening for network connections.
11    async fn net_listening(&self) -> TransportResult<bool>;
12    /// Returns the number of peers connected to the node.
13    async fn net_peer_count(&self) -> TransportResult<u64>;
14    /// Returns the network ID (e.g. 1 for mainnet).
15    async fn net_version(&self) -> TransportResult<u64>;
16}
17
18#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))]
19#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)]
20impl<N, P> NetApi<N> for P
21where
22    N: Network,
23    P: Provider<N>,
24{
25    async fn net_listening(&self) -> TransportResult<bool> {
26        self.client().request_noparams("net_listening").await
27    }
28
29    async fn net_peer_count(&self) -> TransportResult<u64> {
30        self.client().request_noparams("net_peerCount").map_resp(crate::utils::convert_u64).await
31    }
32
33    async fn net_version(&self) -> TransportResult<u64> {
34        self.client().request_noparams("net_version").map_resp(crate::utils::convert_u64).await
35    }
36}
37
38#[cfg(test)]
39mod test {
40    use super::*;
41    use crate::{ext::test::async_ci_only, ProviderBuilder};
42    use alloy_node_bindings::{utils::run_with_tempdir, Geth};
43
44    #[tokio::test]
45    async fn call_net_version() {
46        async_ci_only(|| async move {
47            run_with_tempdir("geth-test-", |temp_dir| async move {
48                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
49                let provider = ProviderBuilder::new().on_http(geth.endpoint_url());
50
51                let version =
52                    provider.net_version().await.expect("net_version call should succeed");
53                assert_eq!(version, 1);
54            })
55            .await;
56        })
57        .await;
58    }
59
60    #[tokio::test]
61    async fn call_net_peer_count() {
62        async_ci_only(|| async move {
63            run_with_tempdir("geth-test-", |temp_dir| async move {
64                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
65                let provider = ProviderBuilder::new().on_http(geth.endpoint_url());
66
67                let count =
68                    provider.net_peer_count().await.expect("net_peerCount call should succeed");
69                assert_eq!(count, 0);
70            })
71            .await;
72        })
73        .await;
74    }
75
76    #[tokio::test]
77    async fn call_net_listening() {
78        async_ci_only(|| async move {
79            run_with_tempdir("geth-test-", |temp_dir| async move {
80                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
81                let provider = ProviderBuilder::new().on_http(geth.endpoint_url());
82
83                let listening =
84                    provider.net_listening().await.expect("net_listening call should succeed");
85                assert!(listening);
86            })
87            .await;
88        })
89        .await;
90    }
91}