@@ -51,7 +51,7 @@ impl BitcoindRpcClient {
5151 pub ( crate ) async fn broadcast_transaction ( & self , tx : & Transaction ) -> std:: io:: Result < Txid > {
5252 let tx_serialized = bitcoin:: consensus:: encode:: serialize_hex ( tx) ;
5353 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
5555 }
5656
5757 pub ( crate ) async fn get_fee_estimate_for_target (
@@ -62,15 +62,15 @@ impl BitcoindRpcClient {
6262 self . rpc_client
6363 . call_method :: < FeeResponse > (
6464 "estimatesmartfee" ,
65- & vec ! [ num_blocks_json, estimation_mode_json] ,
65+ & [ num_blocks_json, estimation_mode_json] ,
6666 )
6767 . await
6868 . map ( |resp| resp. 0 )
6969 }
7070
7171 pub ( crate ) async fn get_mempool_minimum_fee_rate ( & self ) -> std:: io:: Result < FeeRate > {
7272 self . rpc_client
73- . call_method :: < MempoolMinFeeResponse > ( "getmempoolinfo" , & vec ! [ ] )
73+ . call_method :: < MempoolMinFeeResponse > ( "getmempoolinfo" , & [ ] )
7474 . await
7575 . map ( |resp| resp. 0 )
7676 }
@@ -82,7 +82,7 @@ impl BitcoindRpcClient {
8282 let txid_json = serde_json:: json!( txid_hex) ;
8383 match self
8484 . rpc_client
85- . call_method :: < GetRawTransactionResponse > ( "getrawtransaction" , & vec ! [ txid_json] )
85+ . call_method :: < GetRawTransactionResponse > ( "getrawtransaction" , & [ txid_json] )
8686 . await
8787 {
8888 Ok ( resp) => Ok ( Some ( resp. 0 ) ) ,
@@ -113,14 +113,33 @@ impl BitcoindRpcClient {
113113 }
114114 }
115115
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 ) ;
118118 self . rpc_client
119- . call_method :: < GetRawMempoolResponse > ( "getrawmempool" , & vec ! [ verbose_flag_json] )
119+ . call_method :: < GetRawMempoolResponse > ( "getrawmempool" , & [ verbose_flag_json] )
120120 . await
121121 . map ( |resp| resp. 0 )
122122 }
123123
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+
124143 /// Get mempool transactions, alongside their first-seen unix timestamps.
125144 ///
126145 /// This method is an adapted version of `bdk_bitcoind_rpc::Emitter::mempool`. It emits each
@@ -132,7 +151,7 @@ impl BitcoindRpcClient {
132151 let prev_mempool_time = self . latest_mempool_timestamp . load ( Ordering :: Relaxed ) ;
133152 let mut latest_time = prev_mempool_time;
134153
135- let mempool_entries = self . get_raw_mempool ( ) . await ?;
154+ let mempool_entries = self . get_mempool_entries ( ) . await ?;
136155 let mut txs_to_emit = Vec :: new ( ) ;
137156
138157 for entry in mempool_entries {
@@ -254,58 +273,82 @@ impl TryInto<GetRawTransactionResponse> for JsonResponse {
254273 }
255274}
256275
257- pub struct GetRawMempoolResponse ( Vec < RawMempoolEntry > ) ;
276+ pub struct GetRawMempoolResponse ( Vec < Txid > ) ;
258277
259278impl TryInto < GetRawMempoolResponse > for JsonResponse {
260279 type Error = std:: io:: Error ;
261280 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 (
264282 std:: io:: ErrorKind :: Other ,
265283 "Failed to parse getrawmempool response" ,
266284 ) ) ?;
267285
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 ( ) ) ;
288287
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+ ) ) ;
297304 } ;
298- let entry = RawMempoolEntry { txid, time, height } ;
299305
300- mempool_transactions. push ( entry ) ;
306+ mempool_transactions. push ( txid ) ;
301307 }
302308
303309 Ok ( GetRawMempoolResponse ( mempool_transactions) )
304310 }
305311}
306312
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+
307350#[ derive( Debug , Clone ) ]
308- pub ( crate ) struct RawMempoolEntry {
351+ pub ( crate ) struct MempoolEntry {
309352 /// The transaction id
310353 txid : Txid ,
311354 /// Local time transaction entered pool in seconds since 1 Jan 1970 GMT
0 commit comments