Skip to content

Commit aeef579

Browse files
committed
test(electrum): fetch_prev_txout does not process coinbase transactions
1 parent 541abe9 commit aeef579

File tree

1 file changed

+49
-0
lines changed

1 file changed

+49
-0
lines changed

crates/electrum/src/bdk_electrum_client.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,52 @@ fn chain_update(
531531
}
532532
Ok(tip)
533533
}
534+
535+
#[cfg(test)]
536+
mod test {
537+
use crate::{bdk_electrum_client::TxUpdate, BdkElectrumClient};
538+
use bdk_chain::bitcoin::{hashes::Hash, OutPoint, Transaction, TxIn, Txid};
539+
use bdk_core::collections::BTreeMap;
540+
use bdk_testenv::{utils::new_tx, TestEnv};
541+
use std::sync::Arc;
542+
543+
#[cfg(feature = "default")]
544+
#[test]
545+
fn test_fetch_prev_txout_with_coinbase() {
546+
let env = TestEnv::new().unwrap();
547+
let electrum_client =
548+
electrum_client::Client::new(env.electrsd.electrum_url.as_str()).unwrap();
549+
let client = BdkElectrumClient::new(electrum_client);
550+
551+
// Calling `fetch_prev_txout` on a coinbase transaction triggers a `fetch_tx` on a
552+
// transaction with a txid of all zeros. However, since the error from Electrum's
553+
// `transaction_get` is propagated upwards and may not interrupt the `sync`/`full_scan`
554+
// process, we have to insert a transaction with a txid of all zeros into the `tx_cache` to
555+
// guarantee a crash.
556+
let mut tx_cache = client.tx_cache.lock().unwrap();
557+
tx_cache.insert(Txid::all_zeros(), new_tx(0).into());
558+
drop(tx_cache);
559+
560+
// Create a coinbase transaction.
561+
let coinbase_tx = Transaction {
562+
input: vec![TxIn {
563+
previous_output: OutPoint::null(),
564+
..Default::default()
565+
}],
566+
..new_tx(0)
567+
};
568+
569+
assert!(coinbase_tx.is_coinbase());
570+
571+
// Test that `fetch_prev_txout` does not process our coinbase transaction. If it attempts to
572+
// fetch our previously inserted transaction with a txid of all zeros, this test will crash.
573+
let mut tx_update = TxUpdate {
574+
txs: vec![Arc::new(coinbase_tx)],
575+
..Default::default()
576+
};
577+
let _ = client.fetch_prev_txout(&mut tx_update);
578+
579+
// Ensure that the txouts are empty.
580+
assert_eq!(tx_update.txouts, BTreeMap::default());
581+
}
582+
}

0 commit comments

Comments
 (0)