cuprated/rpc/service/
txpool.rs
1use std::{collections::HashSet, convert::Infallible, num::NonZero};
4
5use anyhow::{anyhow, Error};
6use monero_serai::transaction::Transaction;
7use tower::{Service, ServiceExt};
8
9use cuprate_helper::cast::usize_to_u64;
10use cuprate_rpc_types::misc::{SpentKeyImageInfo, TxInfo};
11use cuprate_txpool::{
12 service::{
13 interface::{TxpoolReadRequest, TxpoolReadResponse},
14 TxpoolReadHandle,
15 },
16 TxEntry,
17};
18use cuprate_types::{
19 rpc::{PoolInfo, PoolInfoFull, PoolInfoIncremental, PoolTxInfo, TxpoolStats},
20 TxInPool, TxRelayChecks,
21};
22
23pub async fn backlog(txpool_read: &mut TxpoolReadHandle) -> Result<Vec<TxEntry>, Error> {
27 let TxpoolReadResponse::Backlog(tx_entries) = txpool_read
28 .ready()
29 .await
30 .map_err(|e| anyhow!(e))?
31 .call(TxpoolReadRequest::Backlog)
32 .await
33 .map_err(|e| anyhow!(e))?
34 else {
35 unreachable!();
36 };
37
38 Ok(tx_entries)
39}
40
41pub async fn size(
43 txpool_read: &mut TxpoolReadHandle,
44 include_sensitive_txs: bool,
45) -> Result<u64, Error> {
46 let TxpoolReadResponse::Size(size) = txpool_read
47 .ready()
48 .await
49 .map_err(|e| anyhow!(e))?
50 .call(TxpoolReadRequest::Size {
51 include_sensitive_txs,
52 })
53 .await
54 .map_err(|e| anyhow!(e))?
55 else {
56 unreachable!();
57 };
58
59 Ok(usize_to_u64(size))
60}
61
62pub async fn pool_info(
64 txpool_read: &mut TxpoolReadHandle,
65 include_sensitive_txs: bool,
66 max_tx_count: usize,
67 start_time: Option<NonZero<usize>>,
68) -> Result<PoolInfo, Error> {
69 let TxpoolReadResponse::PoolInfo(pool_info) = txpool_read
70 .ready()
71 .await
72 .map_err(|e| anyhow!(e))?
73 .call(TxpoolReadRequest::PoolInfo {
74 include_sensitive_txs,
75 max_tx_count,
76 start_time,
77 })
78 .await
79 .map_err(|e| anyhow!(e))?
80 else {
81 unreachable!();
82 };
83
84 Ok(pool_info)
85}
86
87pub async fn txs_by_hash(
89 txpool_read: &mut TxpoolReadHandle,
90 tx_hashes: Vec<[u8; 32]>,
91 include_sensitive_txs: bool,
92) -> Result<Vec<TxInPool>, Error> {
93 let TxpoolReadResponse::TxsByHash(txs_in_pool) = txpool_read
94 .ready()
95 .await
96 .map_err(|e| anyhow!(e))?
97 .call(TxpoolReadRequest::TxsByHash {
98 tx_hashes,
99 include_sensitive_txs,
100 })
101 .await
102 .map_err(|e| anyhow!(e))?
103 else {
104 unreachable!();
105 };
106
107 Ok(txs_in_pool)
108}
109
110pub async fn key_images_spent(
112 txpool_read: &mut TxpoolReadHandle,
113 key_images: HashSet<[u8; 32]>,
114 include_sensitive_txs: bool,
115) -> Result<bool, Error> {
116 let TxpoolReadResponse::KeyImagesSpent(status) = txpool_read
117 .ready()
118 .await
119 .map_err(|e| anyhow!(e))?
120 .call(TxpoolReadRequest::KeyImagesSpent {
121 key_images,
122 include_sensitive_txs,
123 })
124 .await
125 .map_err(|e| anyhow!(e))?
126 else {
127 unreachable!();
128 };
129
130 Ok(status)
131}
132
133pub async fn key_images_spent_vec(
135 txpool_read: &mut TxpoolReadHandle,
136 key_images: Vec<[u8; 32]>,
137 include_sensitive_txs: bool,
138) -> Result<Vec<bool>, Error> {
139 let TxpoolReadResponse::KeyImagesSpentVec(status) = txpool_read
140 .ready()
141 .await
142 .map_err(|e| anyhow!(e))?
143 .call(TxpoolReadRequest::KeyImagesSpentVec {
144 key_images,
145 include_sensitive_txs,
146 })
147 .await
148 .map_err(|e| anyhow!(e))?
149 else {
150 unreachable!();
151 };
152
153 Ok(status)
154}
155
156pub async fn pool(
158 txpool_read: &mut TxpoolReadHandle,
159 include_sensitive_txs: bool,
160) -> Result<(Vec<TxInfo>, Vec<SpentKeyImageInfo>), Error> {
161 let TxpoolReadResponse::Pool {
162 txs,
163 spent_key_images,
164 } = txpool_read
165 .ready()
166 .await
167 .map_err(|e| anyhow!(e))?
168 .call(TxpoolReadRequest::Pool {
169 include_sensitive_txs,
170 })
171 .await
172 .map_err(|e| anyhow!(e))?
173 else {
174 unreachable!();
175 };
176
177 let txs = txs.into_iter().map(Into::into).collect();
178 let spent_key_images = spent_key_images.into_iter().map(Into::into).collect();
179
180 Ok((txs, spent_key_images))
181}
182
183pub async fn pool_stats(
185 txpool_read: &mut TxpoolReadHandle,
186 include_sensitive_txs: bool,
187) -> Result<TxpoolStats, Error> {
188 let TxpoolReadResponse::PoolStats(txpool_stats) = txpool_read
189 .ready()
190 .await
191 .map_err(|e| anyhow!(e))?
192 .call(TxpoolReadRequest::PoolStats {
193 include_sensitive_txs,
194 })
195 .await
196 .map_err(|e| anyhow!(e))?
197 else {
198 unreachable!();
199 };
200
201 Ok(txpool_stats)
202}
203
204pub async fn all_hashes(
206 txpool_read: &mut TxpoolReadHandle,
207 include_sensitive_txs: bool,
208) -> Result<Vec<[u8; 32]>, Error> {
209 let TxpoolReadResponse::AllHashes(hashes) = txpool_read
210 .ready()
211 .await
212 .map_err(|e| anyhow!(e))?
213 .call(TxpoolReadRequest::AllHashes {
214 include_sensitive_txs,
215 })
216 .await
217 .map_err(|e| anyhow!(e))?
218 else {
219 unreachable!();
220 };
221
222 Ok(hashes)
223}
224
225pub async fn flush(txpool_manager: &mut Infallible, tx_hashes: Vec<[u8; 32]>) -> Result<(), Error> {
227 todo!();
228 Ok(())
229}
230
231pub async fn relay(txpool_manager: &mut Infallible, tx_hashes: Vec<[u8; 32]>) -> Result<(), Error> {
233 todo!();
234 Ok(())
235}
236
237pub async fn check_maybe_relay_local(
239 txpool_manager: &mut Infallible,
240 tx: Transaction,
241 relay: bool,
242) -> Result<TxRelayChecks, Error> {
243 Ok(todo!())
244}