alloy_provider/ext/
txpool.rs

1//! This modules extends the Ethereum JSON-RPC provider with the `txpool` namespace.
2use crate::Provider;
3use alloy_network::{Ethereum, Network};
4use alloy_primitives::Address;
5use alloy_rpc_types_txpool::{TxpoolContent, TxpoolContentFrom, TxpoolInspect, TxpoolStatus};
6use alloy_transport::TransportResult;
7
8/// Txpool namespace rpc interface.
9#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
10#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
11pub trait TxPoolApi<N: Network = Ethereum>: Send + Sync {
12    /// Returns the content of the transaction pool.
13    ///
14    /// Lists the exact details of all the transactions currently pending for inclusion in the next
15    /// block(s), as well as the ones that are being scheduled for future execution only.
16    ///
17    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details
18    async fn txpool_content(&self) -> TransportResult<TxpoolContent<N::TransactionResponse>>;
19
20    /// Returns the content of the transaction pool filtered by a specific address.
21    ///
22    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_contentFrom) for more details
23    async fn txpool_content_from(
24        &self,
25        from: Address,
26    ) -> TransportResult<TxpoolContentFrom<N::TransactionResponse>>;
27
28    /// Returns a textual summary of each transaction in the pool.
29    ///
30    /// Lists a textual summary of all the transactions currently pending for inclusion in the next
31    /// block(s), as well as the ones that are being scheduled for future execution only.
32    /// This is a method specifically tailored to developers to quickly see the
33    /// transactions in the pool and find any potential issues.
34    ///
35    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_inspect) for more details
36    async fn txpool_inspect(&self) -> TransportResult<TxpoolInspect>;
37
38    /// Returns the current status of the transaction pool.
39    ///
40    /// i.e the number of transactions currently pending for inclusion in the next block(s), as well
41    /// as the ones that are being scheduled for future execution only.
42    ///
43    /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_status) for more details
44    async fn txpool_status(&self) -> TransportResult<TxpoolStatus>;
45}
46
47#[cfg_attr(target_family = "wasm", async_trait::async_trait(?Send))]
48#[cfg_attr(not(target_family = "wasm"), async_trait::async_trait)]
49impl<P, N> TxPoolApi<N> for P
50where
51    P: Provider<N>,
52    N: Network,
53{
54    async fn txpool_content(&self) -> TransportResult<TxpoolContent<N::TransactionResponse>> {
55        self.client().request_noparams("txpool_content").await
56    }
57
58    async fn txpool_content_from(
59        &self,
60        from: Address,
61    ) -> TransportResult<TxpoolContentFrom<N::TransactionResponse>> {
62        self.client().request("txpool_contentFrom", (from,)).await
63    }
64
65    async fn txpool_inspect(&self) -> TransportResult<TxpoolInspect> {
66        self.client().request_noparams("txpool_inspect").await
67    }
68
69    async fn txpool_status(&self) -> TransportResult<TxpoolStatus> {
70        self.client().request_noparams("txpool_status").await
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77    use crate::{ext::test::async_ci_only, ProviderBuilder};
78    use alloy_node_bindings::{utils::run_with_tempdir, Geth};
79
80    #[tokio::test]
81    async fn test_txpool_content() {
82        async_ci_only(|| async move {
83            run_with_tempdir("geth-test-", |temp_dir| async move {
84                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
85                let provider = ProviderBuilder::new().connect_http(geth.endpoint_url());
86                let content = provider.txpool_content().await.unwrap();
87                assert_eq!(content, TxpoolContent::default());
88            })
89            .await;
90        })
91        .await;
92    }
93
94    #[tokio::test]
95    async fn test_txpool_content_from() {
96        async_ci_only(|| async move {
97            run_with_tempdir("geth-test-", |temp_dir| async move {
98                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
99                let provider = ProviderBuilder::new().connect_http(geth.endpoint_url());
100                let content = provider.txpool_content_from(Address::default()).await.unwrap();
101                assert_eq!(content, TxpoolContentFrom::default());
102            })
103            .await;
104        })
105        .await;
106    }
107
108    #[tokio::test]
109    async fn test_txpool_inspect() {
110        async_ci_only(|| async move {
111            run_with_tempdir("geth-test-", |temp_dir| async move {
112                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
113                let provider = ProviderBuilder::new().connect_http(geth.endpoint_url());
114                let content = provider.txpool_inspect().await.unwrap();
115                assert_eq!(content, TxpoolInspect::default());
116            })
117            .await;
118        })
119        .await;
120    }
121
122    #[tokio::test]
123    async fn test_txpool_status() {
124        async_ci_only(|| async move {
125            run_with_tempdir("geth-test-", |temp_dir| async move {
126                let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn();
127                let provider = ProviderBuilder::new().connect_http(geth.endpoint_url());
128                let content = provider.txpool_status().await.unwrap();
129                assert_eq!(content, TxpoolStatus::default());
130            })
131            .await;
132        })
133        .await;
134    }
135}