Skip to content

Commit 11008ee

Browse files
committed
Don't error out on dropped mempool entries
Querying the mempool unfortunately takes multiple sequential steps: first we call `getrawmempool` to retrieve a list of all entries and then retrieve all of them via `getmempoolentry`. Previously, we would error out if a previously retrieved `Txid` wouldn't be available anymore at the second step. Here, we ensure smooth continuation by simply skipping any entries we can't retrieve anymore.
1 parent 9f8d30a commit 11008ee

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

src/chain/bitcoind_rpc.rs

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,21 +122,52 @@ impl BitcoindRpcClient {
122122
.map(|resp| resp.0)
123123
}
124124

125-
pub(crate) async fn get_mempool_entry(&self, txid: Txid) -> std::io::Result<MempoolEntry> {
125+
pub(crate) async fn get_mempool_entry(
126+
&self, txid: Txid,
127+
) -> std::io::Result<Option<MempoolEntry>> {
126128
let txid_hex = bitcoin::consensus::encode::serialize_hex(&txid);
127129
let txid_json = serde_json::json!(txid_hex);
128-
self.rpc_client
130+
match self
131+
.rpc_client
129132
.call_method::<GetMempoolEntryResponse>("getmempoolentry", &[txid_json])
130133
.await
131-
.map(|resp| MempoolEntry { txid, height: resp.height, time: resp.time })
134+
{
135+
Ok(resp) => Ok(Some(MempoolEntry { txid, height: resp.height, time: resp.time })),
136+
Err(e) => match e.into_inner() {
137+
Some(inner) => {
138+
let rpc_error_res: Result<Box<RpcError>, _> = inner.downcast();
139+
140+
match rpc_error_res {
141+
Ok(rpc_error) => {
142+
// Check if it's the 'not found' error code.
143+
if rpc_error.code == -5 {
144+
Ok(None)
145+
} else {
146+
Err(std::io::Error::new(std::io::ErrorKind::Other, rpc_error))
147+
}
148+
},
149+
Err(_) => Err(std::io::Error::new(
150+
std::io::ErrorKind::Other,
151+
"Failed to process getmempoolentry response",
152+
)),
153+
}
154+
},
155+
None => Err(std::io::Error::new(
156+
std::io::ErrorKind::Other,
157+
"Failed to process getmempoolentry response",
158+
)),
159+
},
160+
}
132161
}
133162

134163
pub(crate) async fn get_mempool_entries(&self) -> std::io::Result<Vec<MempoolEntry>> {
135164
let mempool_txids = self.get_raw_mempool().await?;
136165
let mut mempool_entries = Vec::with_capacity(mempool_txids.len());
137166
for txid in mempool_txids {
138-
let entry = self.get_mempool_entry(txid).await?;
139-
mempool_entries.push(entry);
167+
// Push any entries that haven't been dropped since `getrawmempool`
168+
if let Some(entry) = self.get_mempool_entry(txid).await? {
169+
mempool_entries.push(entry);
170+
}
140171
}
141172
Ok(mempool_entries)
142173
}

0 commit comments

Comments
 (0)