@@ -54,17 +54,31 @@ impl BitcoindRpcClient {
54
54
}
55
55
56
56
pub ( crate ) async fn broadcast_transaction ( & self , tx : & Transaction ) -> std:: io:: Result < Txid > {
57
+ Self :: broadcast_transaction_inner ( self . rpc_client ( ) , tx) . await
58
+ }
59
+
60
+ async fn broadcast_transaction_inner (
61
+ rpc_client : Arc < RpcClient > , tx : & Transaction ,
62
+ ) -> std:: io:: Result < Txid > {
57
63
let tx_serialized = bitcoin:: consensus:: encode:: serialize_hex ( tx) ;
58
64
let tx_json = serde_json:: json!( tx_serialized) ;
59
- self . rpc_client . call_method :: < Txid > ( "sendrawtransaction" , & [ tx_json] ) . await
65
+ rpc_client. call_method :: < Txid > ( "sendrawtransaction" , & [ tx_json] ) . await
60
66
}
61
67
62
68
pub ( crate ) async fn get_fee_estimate_for_target (
63
69
& self , num_blocks : usize , estimation_mode : FeeRateEstimationMode ,
70
+ ) -> std:: io:: Result < FeeRate > {
71
+ Self :: get_fee_estimate_for_target_inner ( self . rpc_client ( ) , num_blocks, estimation_mode)
72
+ . await
73
+ }
74
+
75
+ /// Estimate the fee rate for the provided target number of blocks.
76
+ async fn get_fee_estimate_for_target_inner (
77
+ rpc_client : Arc < RpcClient > , num_blocks : usize , estimation_mode : FeeRateEstimationMode ,
64
78
) -> std:: io:: Result < FeeRate > {
65
79
let num_blocks_json = serde_json:: json!( num_blocks) ;
66
80
let estimation_mode_json = serde_json:: json!( estimation_mode) ;
67
- self . rpc_client
81
+ rpc_client
68
82
. call_method :: < FeeResponse > (
69
83
"estimatesmartfee" ,
70
84
& [ num_blocks_json, estimation_mode_json] ,
@@ -74,19 +88,32 @@ impl BitcoindRpcClient {
74
88
}
75
89
76
90
pub ( crate ) async fn get_mempool_minimum_fee_rate ( & self ) -> std:: io:: Result < FeeRate > {
77
- self . rpc_client
91
+ Self :: get_mempool_minimum_fee_rate_rpc ( self . rpc_client ( ) ) . await
92
+ }
93
+
94
+ /// Get the minimum mempool fee rate via RPC interface.
95
+ async fn get_mempool_minimum_fee_rate_rpc (
96
+ rpc_client : Arc < RpcClient > ,
97
+ ) -> std:: io:: Result < FeeRate > {
98
+ rpc_client
78
99
. call_method :: < MempoolMinFeeResponse > ( "getmempoolinfo" , & [ ] )
79
100
. await
80
101
. map ( |resp| resp. 0 )
81
102
}
82
103
83
104
pub ( crate ) async fn get_raw_transaction (
84
105
& self , txid : & Txid ,
106
+ ) -> std:: io:: Result < Option < Transaction > > {
107
+ Self :: get_raw_transaction_rpc ( self . rpc_client ( ) , txid) . await
108
+ }
109
+
110
+ /// Retrieve raw transaction for provided transaction ID via the RPC interface.
111
+ async fn get_raw_transaction_rpc (
112
+ rpc_client : Arc < RpcClient > , txid : & Txid ,
85
113
) -> std:: io:: Result < Option < Transaction > > {
86
114
let txid_hex = bitcoin:: consensus:: encode:: serialize_hex ( txid) ;
87
115
let txid_json = serde_json:: json!( txid_hex) ;
88
- match self
89
- . rpc_client
116
+ match rpc_client
90
117
. call_method :: < GetRawTransactionResponse > ( "getrawtransaction" , & [ txid_json] )
91
118
. await
92
119
{
@@ -119,24 +146,33 @@ impl BitcoindRpcClient {
119
146
}
120
147
121
148
pub ( crate ) async fn get_raw_mempool ( & self ) -> std:: io:: Result < Vec < Txid > > {
149
+ Self :: get_raw_mempool_rpc ( self . rpc_client ( ) ) . await
150
+ }
151
+
152
+ /// Retrieves the raw mempool via the RPC interface.
153
+ async fn get_raw_mempool_rpc ( rpc_client : Arc < RpcClient > ) -> std:: io:: Result < Vec < Txid > > {
122
154
let verbose_flag_json = serde_json:: json!( false ) ;
123
- self . rpc_client
155
+ rpc_client
124
156
. call_method :: < GetRawMempoolResponse > ( "getrawmempool" , & [ verbose_flag_json] )
125
157
. await
126
158
. map ( |resp| resp. 0 )
127
159
}
128
160
129
161
pub ( crate ) async fn get_mempool_entry (
130
162
& self , txid : Txid ,
163
+ ) -> std:: io:: Result < Option < MempoolEntry > > {
164
+ Self :: get_mempool_entry_inner ( self . rpc_client ( ) , txid) . await
165
+ }
166
+
167
+ /// Retrieves the mempool entry of the provided transaction ID.
168
+ async fn get_mempool_entry_inner (
169
+ client : Arc < RpcClient > , txid : Txid ,
131
170
) -> std:: io:: Result < Option < MempoolEntry > > {
132
171
let txid_hex = bitcoin:: consensus:: encode:: serialize_hex ( & txid) ;
133
172
let txid_json = serde_json:: json!( txid_hex) ;
134
- match self
135
- . rpc_client
136
- . call_method :: < GetMempoolEntryResponse > ( "getmempoolentry" , & [ txid_json] )
137
- . await
138
- {
139
- Ok ( resp) => Ok ( Some ( MempoolEntry { txid, height : resp. height , time : resp. time } ) ) ,
173
+
174
+ match client. call_method :: < GetMempoolEntryResponse > ( "getmempoolentry" , & [ txid_json] ) . await {
175
+ Ok ( resp) => Ok ( Some ( MempoolEntry { txid, time : resp. time , height : resp. height } ) ) ,
140
176
Err ( e) => match e. into_inner ( ) {
141
177
Some ( inner) => {
142
178
let rpc_error_res: Result < Box < RpcError > , _ > = inner. downcast ( ) ;
@@ -165,9 +201,15 @@ impl BitcoindRpcClient {
165
201
}
166
202
167
203
pub ( crate ) async fn update_mempool_entries_cache ( & self ) -> std:: io:: Result < ( ) > {
204
+ self . update_mempool_entries_cache_inner ( & self . mempool_entries_cache ) . await
205
+ }
206
+
207
+ async fn update_mempool_entries_cache_inner (
208
+ & self , mempool_entries_cache : & tokio:: sync:: Mutex < HashMap < Txid , MempoolEntry > > ,
209
+ ) -> std:: io:: Result < ( ) > {
168
210
let mempool_txids = self . get_raw_mempool ( ) . await ?;
169
211
170
- let mut mempool_entries_cache = self . mempool_entries_cache . lock ( ) . await ;
212
+ let mut mempool_entries_cache = mempool_entries_cache. lock ( ) . await ;
171
213
mempool_entries_cache. retain ( |txid, _| mempool_txids. contains ( txid) ) ;
172
214
173
215
if let Some ( difference) = mempool_txids. len ( ) . checked_sub ( mempool_entries_cache. capacity ( ) )
@@ -210,13 +252,28 @@ impl BitcoindRpcClient {
210
252
async fn get_mempool_transactions_and_timestamp_at_height (
211
253
& self , best_processed_height : u32 ,
212
254
) -> std:: io:: Result < Vec < ( Transaction , u64 ) > > {
213
- let prev_mempool_time = self . latest_mempool_timestamp . load ( Ordering :: Relaxed ) ;
255
+ self . get_mempool_transactions_and_timestamp_at_height_inner (
256
+ & self . latest_mempool_timestamp ,
257
+ & self . mempool_entries_cache ,
258
+ & self . mempool_txs_cache ,
259
+ best_processed_height,
260
+ )
261
+ . await
262
+ }
263
+
264
+ async fn get_mempool_transactions_and_timestamp_at_height_inner (
265
+ & self , latest_mempool_timestamp : & AtomicU64 ,
266
+ mempool_entries_cache : & tokio:: sync:: Mutex < HashMap < Txid , MempoolEntry > > ,
267
+ mempool_txs_cache : & tokio:: sync:: Mutex < HashMap < Txid , ( Transaction , u64 ) > > ,
268
+ best_processed_height : u32 ,
269
+ ) -> std:: io:: Result < Vec < ( Transaction , u64 ) > > {
270
+ let prev_mempool_time = latest_mempool_timestamp. load ( Ordering :: Relaxed ) ;
214
271
let mut latest_time = prev_mempool_time;
215
272
216
273
self . update_mempool_entries_cache ( ) . await ?;
217
274
218
- let mempool_entries_cache = self . mempool_entries_cache . lock ( ) . await ;
219
- let mut mempool_txs_cache = self . mempool_txs_cache . lock ( ) . await ;
275
+ let mempool_entries_cache = mempool_entries_cache. lock ( ) . await ;
276
+ let mut mempool_txs_cache = mempool_txs_cache. lock ( ) . await ;
220
277
mempool_txs_cache. retain ( |txid, _| mempool_entries_cache. contains_key ( txid) ) ;
221
278
222
279
if let Some ( difference) =
@@ -260,7 +317,7 @@ impl BitcoindRpcClient {
260
317
}
261
318
262
319
if !txs_to_emit. is_empty ( ) {
263
- self . latest_mempool_timestamp . store ( latest_time, Ordering :: Release ) ;
320
+ latest_mempool_timestamp. store ( latest_time, Ordering :: Release ) ;
264
321
}
265
322
Ok ( txs_to_emit)
266
323
}
@@ -272,8 +329,21 @@ impl BitcoindRpcClient {
272
329
async fn get_evicted_mempool_txids_and_timestamp (
273
330
& self , unconfirmed_txids : Vec < Txid > ,
274
331
) -> std:: io:: Result < Vec < ( Txid , u64 ) > > {
275
- let latest_mempool_timestamp = self . latest_mempool_timestamp . load ( Ordering :: Relaxed ) ;
276
- let mempool_entries_cache = self . mempool_entries_cache . lock ( ) . await ;
332
+ self . get_evicted_mempool_txids_and_timestamp_inner (
333
+ & self . latest_mempool_timestamp ,
334
+ & self . mempool_entries_cache ,
335
+ unconfirmed_txids,
336
+ )
337
+ . await
338
+ }
339
+
340
+ async fn get_evicted_mempool_txids_and_timestamp_inner (
341
+ & self , latest_mempool_timestamp : & AtomicU64 ,
342
+ mempool_entries_cache : & tokio:: sync:: Mutex < HashMap < Txid , MempoolEntry > > ,
343
+ unconfirmed_txids : Vec < Txid > ,
344
+ ) -> std:: io:: Result < Vec < ( Txid , u64 ) > > {
345
+ let latest_mempool_timestamp = latest_mempool_timestamp. load ( Ordering :: Relaxed ) ;
346
+ let mempool_entries_cache = mempool_entries_cache. lock ( ) . await ;
277
347
let evicted_txids = unconfirmed_txids
278
348
. into_iter ( )
279
349
. filter ( |txid| mempool_entries_cache. contains_key ( txid) )
0 commit comments