@@ -51,7 +51,7 @@ impl BitcoindRpcClient {
51
51
pub ( crate ) async fn broadcast_transaction ( & self , tx : & Transaction ) -> std:: io:: Result < Txid > {
52
52
let tx_serialized = bitcoin:: consensus:: encode:: serialize_hex ( tx) ;
53
53
let tx_json = serde_json:: json!( tx_serialized) ;
54
- self . rpc_client . call_method :: < Txid > ( "sendrawtransaction" , & vec ! [ tx_json] ) . await
54
+ self . rpc_client . call_method :: < Txid > ( "sendrawtransaction" , & [ tx_json] ) . await
55
55
}
56
56
57
57
pub ( crate ) async fn get_fee_estimate_for_target (
@@ -62,15 +62,15 @@ impl BitcoindRpcClient {
62
62
self . rpc_client
63
63
. call_method :: < FeeResponse > (
64
64
"estimatesmartfee" ,
65
- & vec ! [ num_blocks_json, estimation_mode_json] ,
65
+ & [ num_blocks_json, estimation_mode_json] ,
66
66
)
67
67
. await
68
68
. map ( |resp| resp. 0 )
69
69
}
70
70
71
71
pub ( crate ) async fn get_mempool_minimum_fee_rate ( & self ) -> std:: io:: Result < FeeRate > {
72
72
self . rpc_client
73
- . call_method :: < MempoolMinFeeResponse > ( "getmempoolinfo" , & vec ! [ ] )
73
+ . call_method :: < MempoolMinFeeResponse > ( "getmempoolinfo" , & [ ] )
74
74
. await
75
75
. map ( |resp| resp. 0 )
76
76
}
@@ -82,7 +82,7 @@ impl BitcoindRpcClient {
82
82
let txid_json = serde_json:: json!( txid_hex) ;
83
83
match self
84
84
. rpc_client
85
- . call_method :: < GetRawTransactionResponse > ( "getrawtransaction" , & vec ! [ txid_json] )
85
+ . call_method :: < GetRawTransactionResponse > ( "getrawtransaction" , & [ txid_json] )
86
86
. await
87
87
{
88
88
Ok ( resp) => Ok ( Some ( resp. 0 ) ) ,
@@ -113,14 +113,33 @@ impl BitcoindRpcClient {
113
113
}
114
114
}
115
115
116
- pub ( crate ) async fn get_raw_mempool ( & self ) -> std:: io:: Result < Vec < RawMempoolEntry > > {
117
- let verbose_flag_json = serde_json:: json!( true ) ;
116
+ pub ( crate ) async fn get_raw_mempool ( & self ) -> std:: io:: Result < Vec < Txid > > {
117
+ let verbose_flag_json = serde_json:: json!( false ) ;
118
118
self . rpc_client
119
- . call_method :: < GetRawMempoolResponse > ( "getrawmempool" , & vec ! [ verbose_flag_json] )
119
+ . call_method :: < GetRawMempoolResponse > ( "getrawmempool" , & [ verbose_flag_json] )
120
120
. await
121
121
. map ( |resp| resp. 0 )
122
122
}
123
123
124
+ pub ( crate ) async fn get_mempool_entry ( & self , txid : Txid ) -> std:: io:: Result < MempoolEntry > {
125
+ let txid_hex = bitcoin:: consensus:: encode:: serialize_hex ( & txid) ;
126
+ let txid_json = serde_json:: json!( txid_hex) ;
127
+ self . rpc_client
128
+ . call_method :: < GetMempoolEntryResponse > ( "getmempoolentry" , & [ txid_json] )
129
+ . await
130
+ . map ( |resp| MempoolEntry { txid, height : resp. height , time : resp. time } )
131
+ }
132
+
133
+ pub ( crate ) async fn get_mempool_entries ( & self ) -> std:: io:: Result < Vec < MempoolEntry > > {
134
+ let mempool_txids = self . get_raw_mempool ( ) . await ?;
135
+ let mut mempool_entries = Vec :: with_capacity ( mempool_txids. len ( ) ) ;
136
+ for txid in mempool_txids {
137
+ let entry = self . get_mempool_entry ( txid) . await ?;
138
+ mempool_entries. push ( entry) ;
139
+ }
140
+ Ok ( mempool_entries)
141
+ }
142
+
124
143
/// Get mempool transactions, alongside their first-seen unix timestamps.
125
144
///
126
145
/// This method is an adapted version of `bdk_bitcoind_rpc::Emitter::mempool`. It emits each
@@ -132,7 +151,7 @@ impl BitcoindRpcClient {
132
151
let prev_mempool_time = self . latest_mempool_timestamp . load ( Ordering :: Relaxed ) ;
133
152
let mut latest_time = prev_mempool_time;
134
153
135
- let mempool_entries = self . get_raw_mempool ( ) . await ?;
154
+ let mempool_entries = self . get_mempool_entries ( ) . await ?;
136
155
let mut txs_to_emit = Vec :: new ( ) ;
137
156
138
157
for entry in mempool_entries {
@@ -254,58 +273,82 @@ impl TryInto<GetRawTransactionResponse> for JsonResponse {
254
273
}
255
274
}
256
275
257
- pub struct GetRawMempoolResponse ( Vec < RawMempoolEntry > ) ;
276
+ pub struct GetRawMempoolResponse ( Vec < Txid > ) ;
258
277
259
278
impl TryInto < GetRawMempoolResponse > for JsonResponse {
260
279
type Error = std:: io:: Error ;
261
280
fn try_into ( self ) -> std:: io:: Result < GetRawMempoolResponse > {
262
- let mut mempool_transactions = Vec :: new ( ) ;
263
- let res = self . 0 . as_object ( ) . ok_or ( std:: io:: Error :: new (
281
+ let res = self . 0 . as_array ( ) . ok_or ( std:: io:: Error :: new (
264
282
std:: io:: ErrorKind :: Other ,
265
283
"Failed to parse getrawmempool response" ,
266
284
) ) ?;
267
285
268
- for ( k, v) in res {
269
- let txid = match bitcoin:: consensus:: encode:: deserialize_hex ( k) {
270
- Ok ( txid) => txid,
271
- Err ( _) => {
272
- return Err ( std:: io:: Error :: new (
273
- std:: io:: ErrorKind :: Other ,
274
- "Failed to parse getrawmempool response" ,
275
- ) ) ;
276
- } ,
277
- } ;
278
-
279
- let time = match v[ "time" ] . as_u64 ( ) {
280
- Some ( time) => time,
281
- None => {
282
- return Err ( std:: io:: Error :: new (
283
- std:: io:: ErrorKind :: Other ,
284
- "Failed to parse getrawmempool response" ,
285
- ) ) ;
286
- } ,
287
- } ;
286
+ let mut mempool_transactions = Vec :: with_capacity ( res. len ( ) ) ;
288
287
289
- let height = match v[ "height" ] . as_u64 ( ) . and_then ( |h| h. try_into ( ) . ok ( ) ) {
290
- Some ( height) => height,
291
- None => {
292
- return Err ( std:: io:: Error :: new (
293
- std:: io:: ErrorKind :: Other ,
294
- "Failed to parse getrawmempool response" ,
295
- ) ) ;
296
- } ,
288
+ for hex in res {
289
+ let txid = if let Some ( hex_str) = hex. as_str ( ) {
290
+ match bitcoin:: consensus:: encode:: deserialize_hex ( hex_str) {
291
+ Ok ( txid) => txid,
292
+ Err ( _) => {
293
+ return Err ( std:: io:: Error :: new (
294
+ std:: io:: ErrorKind :: Other ,
295
+ "Failed to parse getrawmempool response" ,
296
+ ) ) ;
297
+ } ,
298
+ }
299
+ } else {
300
+ return Err ( std:: io:: Error :: new (
301
+ std:: io:: ErrorKind :: Other ,
302
+ "Failed to parse getrawmempool response" ,
303
+ ) ) ;
297
304
} ;
298
- let entry = RawMempoolEntry { txid, time, height } ;
299
305
300
- mempool_transactions. push ( entry ) ;
306
+ mempool_transactions. push ( txid ) ;
301
307
}
302
308
303
309
Ok ( GetRawMempoolResponse ( mempool_transactions) )
304
310
}
305
311
}
306
312
313
+ pub struct GetMempoolEntryResponse {
314
+ time : u64 ,
315
+ height : u32 ,
316
+ }
317
+
318
+ impl TryInto < GetMempoolEntryResponse > for JsonResponse {
319
+ type Error = std:: io:: Error ;
320
+ fn try_into ( self ) -> std:: io:: Result < GetMempoolEntryResponse > {
321
+ let res = self . 0 . as_object ( ) . ok_or ( std:: io:: Error :: new (
322
+ std:: io:: ErrorKind :: Other ,
323
+ "Failed to parse getmempoolentry response" ,
324
+ ) ) ?;
325
+
326
+ let time = match res[ "time" ] . as_u64 ( ) {
327
+ Some ( time) => time,
328
+ None => {
329
+ return Err ( std:: io:: Error :: new (
330
+ std:: io:: ErrorKind :: Other ,
331
+ "Failed to parse getmempoolentry response" ,
332
+ ) ) ;
333
+ } ,
334
+ } ;
335
+
336
+ let height = match res[ "height" ] . as_u64 ( ) . and_then ( |h| h. try_into ( ) . ok ( ) ) {
337
+ Some ( height) => height,
338
+ None => {
339
+ return Err ( std:: io:: Error :: new (
340
+ std:: io:: ErrorKind :: Other ,
341
+ "Failed to parse getmempoolentry response" ,
342
+ ) ) ;
343
+ } ,
344
+ } ;
345
+
346
+ Ok ( GetMempoolEntryResponse { time, height } )
347
+ }
348
+ }
349
+
307
350
#[ derive( Debug , Clone ) ]
308
- pub ( crate ) struct RawMempoolEntry {
351
+ pub ( crate ) struct MempoolEntry {
309
352
/// The transaction id
310
353
txid : Txid ,
311
354
/// Local time transaction entered pool in seconds since 1 Jan 1970 GMT
0 commit comments