Skip to content

Commit 7502052

Browse files
committed
fix(electrum): Handle negative heights properly
In electrum, heights returned alongside txs may be 0 or -1. 0 means the tx is unconfirmed. -1 means the tx is unconfirmed and spends an unconfirmed tx. Previously, the codebase assumed that heights cannot be negative and used a `i32 as usize` cast (which would lead to panic if the i32 is negative).
1 parent a41db82 commit 7502052

File tree

1 file changed

+14
-6
lines changed

1 file changed

+14
-6
lines changed

crates/electrum/src/bdk_electrum_client.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
276276

277277
for tx_res in spk_history {
278278
tx_update.txs.push(self.fetch_tx(tx_res.tx_hash)?);
279-
self.validate_merkle_for_anchor(tx_update, tx_res.tx_hash, tx_res.height)?;
279+
if let Ok(height) = tx_res.height.try_into() {
280+
self.validate_merkle_for_anchor(tx_update, tx_res.tx_hash, height)?;
281+
}
280282
}
281283
}
282284
}
@@ -312,7 +314,9 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
312314
if !has_residing && res.tx_hash == op_txid {
313315
has_residing = true;
314316
tx_update.txs.push(Arc::clone(&op_tx));
315-
self.validate_merkle_for_anchor(tx_update, res.tx_hash, res.height)?;
317+
if let Ok(height) = res.height.try_into() {
318+
self.validate_merkle_for_anchor(tx_update, res.tx_hash, height)?;
319+
}
316320
}
317321

318322
if !has_spending && res.tx_hash != op_txid {
@@ -326,7 +330,9 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
326330
continue;
327331
}
328332
tx_update.txs.push(Arc::clone(&res_tx));
329-
self.validate_merkle_for_anchor(tx_update, res.tx_hash, res.height)?;
333+
if let Ok(height) = res.height.try_into() {
334+
self.validate_merkle_for_anchor(tx_update, res.tx_hash, height)?;
335+
}
330336
}
331337
}
332338
}
@@ -360,7 +366,9 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
360366
.into_iter()
361367
.find(|r| r.tx_hash == txid)
362368
{
363-
self.validate_merkle_for_anchor(tx_update, txid, r.height)?;
369+
if let Ok(height) = r.height.try_into() {
370+
self.validate_merkle_for_anchor(tx_update, txid, height)?;
371+
}
364372
}
365373

366374
tx_update.txs.push(tx);
@@ -374,11 +382,11 @@ impl<E: ElectrumApi> BdkElectrumClient<E> {
374382
&self,
375383
tx_update: &mut TxUpdate<ConfirmationBlockTime>,
376384
txid: Txid,
377-
confirmation_height: i32,
385+
confirmation_height: usize,
378386
) -> Result<(), Error> {
379387
if let Ok(merkle_res) = self
380388
.inner
381-
.transaction_get_merkle(&txid, confirmation_height as usize)
389+
.transaction_get_merkle(&txid, confirmation_height)
382390
{
383391
let mut header = self.fetch_header(merkle_res.block_height as u32)?;
384392
let mut is_confirmed_tx = electrum_client::utils::validate_merkle_proof(

0 commit comments

Comments
 (0)