Skip to content

Commit d4ef266

Browse files
committed
test(electrum): fetch_prev_txout does not process coinbase transactions
1 parent 0944b35 commit d4ef266

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

crates/electrum/src/bdk_electrum_client.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,45 @@ 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::{OutPoint, Transaction, TxIn};
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+
// Create a coinbase transaction.
552+
let coinbase_tx = Transaction {
553+
input: vec![TxIn {
554+
previous_output: OutPoint::null(),
555+
..Default::default()
556+
}],
557+
..new_tx(0)
558+
};
559+
560+
assert!(coinbase_tx.is_coinbase());
561+
562+
// Test that `fetch_prev_txout` does not process coinbase transactions. Calling
563+
// `fetch_prev_txout` on a coinbase transaction will trigger a `fetch_tx` on a transaction
564+
// with a txid of all zeros. If `fetch_prev_txout` attempts to fetch this transaction, this
565+
// assertion will fail.
566+
let mut tx_update = TxUpdate {
567+
txs: vec![Arc::new(coinbase_tx)],
568+
..Default::default()
569+
};
570+
assert!(client.fetch_prev_txout(&mut tx_update).is_ok());
571+
572+
// Ensure that the txouts are empty.
573+
assert_eq!(tx_update.txouts, BTreeMap::default());
574+
}
575+
}

crates/electrum/tests/test_electrum.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,3 +525,37 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
525525

526526
Ok(())
527527
}
528+
529+
#[test]
530+
fn test_sync_with_coinbase() -> anyhow::Result<()> {
531+
let env = TestEnv::new()?;
532+
let electrum_client = electrum_client::Client::new(env.electrsd.electrum_url.as_str())?;
533+
let client = BdkElectrumClient::new(electrum_client);
534+
535+
// Setup address.
536+
let spk_to_track = ScriptBuf::new_p2wsh(&WScriptHash::all_zeros());
537+
let addr_to_track = Address::from_script(&spk_to_track, bdk_chain::bitcoin::Network::Regtest)?;
538+
539+
// Setup receiver.
540+
let (mut recv_chain, _) = LocalChain::from_genesis_hash(env.bitcoind.client.get_block_hash(0)?);
541+
let mut recv_graph = IndexedTxGraph::<ConfirmationBlockTime, _>::new({
542+
let mut recv_index = SpkTxOutIndex::default();
543+
recv_index.insert_spk((), spk_to_track.clone());
544+
recv_index
545+
});
546+
547+
// Mine some blocks.
548+
env.mine_blocks(101, Some(addr_to_track))?;
549+
env.wait_until_electrum_sees_block(Duration::from_secs(6))?;
550+
551+
// Check to see if electrum syncs properly.
552+
assert!(sync_with_electrum(
553+
&client,
554+
[spk_to_track.clone()],
555+
&mut recv_chain,
556+
&mut recv_graph,
557+
)
558+
.is_ok());
559+
560+
Ok(())
561+
}

0 commit comments

Comments
 (0)