Skip to content

Commit b7de5f8

Browse files
committed
prefactor: prepare client for REST interface support
In the next commit, we'll introduce a unified bitcoind client with two variant - RPC and REST. In preparation to support chain syncing via the REST interface, we refactor some methods into helper functions specific to the interface client.
1 parent c1f27ef commit b7de5f8

File tree

1 file changed

+89
-19
lines changed

1 file changed

+89
-19
lines changed

src/chain/bitcoind.rs

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,31 @@ impl BitcoindRpcClient {
5454
}
5555

5656
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> {
5763
let tx_serialized = bitcoin::consensus::encode::serialize_hex(tx);
5864
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
6066
}
6167

6268
pub(crate) async fn get_fee_estimate_for_target(
6369
&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,
6478
) -> std::io::Result<FeeRate> {
6579
let num_blocks_json = serde_json::json!(num_blocks);
6680
let estimation_mode_json = serde_json::json!(estimation_mode);
67-
self.rpc_client
81+
rpc_client
6882
.call_method::<FeeResponse>(
6983
"estimatesmartfee",
7084
&[num_blocks_json, estimation_mode_json],
@@ -74,19 +88,32 @@ impl BitcoindRpcClient {
7488
}
7589

7690
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
7899
.call_method::<MempoolMinFeeResponse>("getmempoolinfo", &[])
79100
.await
80101
.map(|resp| resp.0)
81102
}
82103

83104
pub(crate) async fn get_raw_transaction(
84105
&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,
85113
) -> std::io::Result<Option<Transaction>> {
86114
let txid_hex = bitcoin::consensus::encode::serialize_hex(txid);
87115
let txid_json = serde_json::json!(txid_hex);
88-
match self
89-
.rpc_client
116+
match rpc_client
90117
.call_method::<GetRawTransactionResponse>("getrawtransaction", &[txid_json])
91118
.await
92119
{
@@ -119,24 +146,33 @@ impl BitcoindRpcClient {
119146
}
120147

121148
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>> {
122154
let verbose_flag_json = serde_json::json!(false);
123-
self.rpc_client
155+
rpc_client
124156
.call_method::<GetRawMempoolResponse>("getrawmempool", &[verbose_flag_json])
125157
.await
126158
.map(|resp| resp.0)
127159
}
128160

129161
pub(crate) async fn get_mempool_entry(
130162
&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,
131170
) -> std::io::Result<Option<MempoolEntry>> {
132171
let txid_hex = bitcoin::consensus::encode::serialize_hex(&txid);
133172
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 })),
140176
Err(e) => match e.into_inner() {
141177
Some(inner) => {
142178
let rpc_error_res: Result<Box<RpcError>, _> = inner.downcast();
@@ -165,9 +201,15 @@ impl BitcoindRpcClient {
165201
}
166202

167203
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<()> {
168210
let mempool_txids = self.get_raw_mempool().await?;
169211

170-
let mut mempool_entries_cache = self.mempool_entries_cache.lock().await;
212+
let mut mempool_entries_cache = mempool_entries_cache.lock().await;
171213
mempool_entries_cache.retain(|txid, _| mempool_txids.contains(txid));
172214

173215
if let Some(difference) = mempool_txids.len().checked_sub(mempool_entries_cache.capacity())
@@ -210,13 +252,28 @@ impl BitcoindRpcClient {
210252
async fn get_mempool_transactions_and_timestamp_at_height(
211253
&self, best_processed_height: u32,
212254
) -> 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);
214271
let mut latest_time = prev_mempool_time;
215272

216273
self.update_mempool_entries_cache().await?;
217274

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;
220277
mempool_txs_cache.retain(|txid, _| mempool_entries_cache.contains_key(txid));
221278

222279
if let Some(difference) =
@@ -260,7 +317,7 @@ impl BitcoindRpcClient {
260317
}
261318

262319
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);
264321
}
265322
Ok(txs_to_emit)
266323
}
@@ -272,8 +329,21 @@ impl BitcoindRpcClient {
272329
async fn get_evicted_mempool_txids_and_timestamp(
273330
&self, unconfirmed_txids: Vec<Txid>,
274331
) -> 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;
277347
let evicted_txids = unconfirmed_txids
278348
.into_iter()
279349
.filter(|txid| mempool_entries_cache.contains_key(txid))

0 commit comments

Comments
 (0)