cfx_rpc/
txpool.rs

1use async_trait::async_trait;
2use cfx_rpc_eth_api::TxPoolApiServer;
3use cfx_rpc_eth_types::{
4    Transaction, TxpoolContent, TxpoolContentFrom, TxpoolInspect,
5    TxpoolInspectSummary, TxpoolStatus,
6};
7use cfx_types::{Address, AddressWithSpace, Space, U256, U64};
8use cfxcore::SharedTransactionPool;
9use jsonrpsee::core::RpcResult;
10use primitives::SignedTransaction;
11use std::{collections::BTreeMap, sync::Arc};
12
13pub struct TxPoolApi {
14    tx_pool: SharedTransactionPool,
15}
16
17impl TxPoolApi {
18    pub fn new(tx_pool: SharedTransactionPool) -> Self { Self { tx_pool } }
19
20    fn nonce_map_convert(
21        (nonce, tx): (U256, Arc<SignedTransaction>),
22    ) -> (String, Transaction) {
23        (
24            nonce.to_string(),
25            Transaction::from_signed(&tx, (None, None, None), (None, None)),
26        )
27    }
28}
29
30#[async_trait]
31impl TxPoolApiServer for TxPoolApi {
32    async fn txpool_status(&self) -> RpcResult<TxpoolStatus> {
33        let pending = self.tx_pool.total_pending(Some(Space::Ethereum));
34        let queued = self.tx_pool.total_queued(Some(Space::Ethereum));
35        Ok(TxpoolStatus {
36            pending: U64::from(pending),
37            queued: U64::from(queued),
38        })
39    }
40
41    async fn txpool_inspect(&self) -> RpcResult<TxpoolInspect> {
42        let converter =
43            |(addr, nonce_map): (Address, BTreeMap<String, Transaction>)| {
44                (
45                    addr,
46                    nonce_map
47                        .into_iter()
48                        .map(|(nonce, tx)| {
49                            (nonce, TxpoolInspectSummary::from_tx(tx))
50                        })
51                        .collect(),
52                )
53            };
54
55        let content = self.txpool_content().await?;
56        let pending = content.pending.into_iter().map(converter).collect();
57        let queued = content.queued.into_iter().map(converter).collect();
58        Ok(TxpoolInspect { pending, queued })
59    }
60
61    async fn txpool_content_from(
62        &self, from: Address,
63    ) -> RpcResult<TxpoolContentFrom> {
64        let (pending, queued) =
65            self.tx_pool.eth_content_from(AddressWithSpace {
66                address: from,
67                space: Space::Ethereum,
68            });
69        let pending =
70            pending.into_iter().map(Self::nonce_map_convert).collect();
71        let queued = queued.into_iter().map(Self::nonce_map_convert).collect();
72        Ok(TxpoolContentFrom { pending, queued })
73    }
74
75    async fn txpool_content(&self) -> RpcResult<TxpoolContent> {
76        let converter = |(addr, nonce_map): (
77            AddressWithSpace,
78            BTreeMap<U256, Arc<SignedTransaction>>,
79        )| {
80            (
81                addr.address,
82                nonce_map.into_iter().map(Self::nonce_map_convert).collect(),
83            )
84        };
85        let (pending, queued) = self.tx_pool.eth_content(Some(Space::Ethereum));
86        let pending = pending.into_iter().map(converter).collect();
87        let queued = queued.into_iter().map(converter).collect();
88        Ok(TxpoolContent { pending, queued })
89    }
90}