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}