]> Untitled Git - bdk/commitdiff
test(electrum): `fetch_prev_txout` does not process coinbase transactions
authorWei Chen <wzc110@gmail.com>
Wed, 4 Dec 2024 05:45:45 +0000 (13:45 +0800)
committerWei Chen <wzc110@gmail.com>
Fri, 6 Dec 2024 06:03:27 +0000 (14:03 +0800)
crates/electrum/src/bdk_electrum_client.rs
crates/electrum/tests/test_electrum.rs

index eb1d43e35f3b325e99f1eee597123f90c3bf9cdb..4034a7fa6973acbf08e6346d8385ef058dc86608 100644 (file)
@@ -531,3 +531,45 @@ fn chain_update(
     }
     Ok(tip)
 }
+
+#[cfg(test)]
+mod test {
+    use crate::{bdk_electrum_client::TxUpdate, BdkElectrumClient};
+    use bdk_chain::bitcoin::{OutPoint, Transaction, TxIn};
+    use bdk_core::collections::BTreeMap;
+    use bdk_testenv::{utils::new_tx, TestEnv};
+    use std::sync::Arc;
+
+    #[cfg(feature = "default")]
+    #[test]
+    fn test_fetch_prev_txout_with_coinbase() {
+        let env = TestEnv::new().unwrap();
+        let electrum_client =
+            electrum_client::Client::new(env.electrsd.electrum_url.as_str()).unwrap();
+        let client = BdkElectrumClient::new(electrum_client);
+
+        // Create a coinbase transaction.
+        let coinbase_tx = Transaction {
+            input: vec![TxIn {
+                previous_output: OutPoint::null(),
+                ..Default::default()
+            }],
+            ..new_tx(0)
+        };
+
+        assert!(coinbase_tx.is_coinbase());
+
+        // Test that `fetch_prev_txout` does not process coinbase transactions. Calling
+        // `fetch_prev_txout` on a coinbase transaction will trigger a `fetch_tx` on a transaction
+        // with a txid of all zeros. If `fetch_prev_txout` attempts to fetch this transaction, this
+        // assertion will fail.
+        let mut tx_update = TxUpdate {
+            txs: vec![Arc::new(coinbase_tx)],
+            ..Default::default()
+        };
+        assert!(client.fetch_prev_txout(&mut tx_update).is_ok());
+
+        // Ensure that the txouts are empty.
+        assert_eq!(tx_update.txouts, BTreeMap::default());
+    }
+}
index d2dba9d8de96f7ae9e18def57d81bd27973c76ea..a5abbd2b5bea14a671f98e82fde08152e981f9ff 100644 (file)
@@ -525,3 +525,37 @@ fn tx_can_become_unconfirmed_after_reorg() -> anyhow::Result<()> {
 
     Ok(())
 }
+
+#[test]
+fn test_sync_with_coinbase() -> anyhow::Result<()> {
+    let env = TestEnv::new()?;
+    let electrum_client = electrum_client::Client::new(env.electrsd.electrum_url.as_str())?;
+    let client = BdkElectrumClient::new(electrum_client);
+
+    // Setup address.
+    let spk_to_track = ScriptBuf::new_p2wsh(&WScriptHash::all_zeros());
+    let addr_to_track = Address::from_script(&spk_to_track, bdk_chain::bitcoin::Network::Regtest)?;
+
+    // Setup receiver.
+    let (mut recv_chain, _) = LocalChain::from_genesis_hash(env.bitcoind.client.get_block_hash(0)?);
+    let mut recv_graph = IndexedTxGraph::<ConfirmationBlockTime, _>::new({
+        let mut recv_index = SpkTxOutIndex::default();
+        recv_index.insert_spk((), spk_to_track.clone());
+        recv_index
+    });
+
+    // Mine some blocks.
+    env.mine_blocks(101, Some(addr_to_track))?;
+    env.wait_until_electrum_sees_block(Duration::from_secs(6))?;
+
+    // Check to see if electrum syncs properly.
+    assert!(sync_with_electrum(
+        &client,
+        [spk_to_track.clone()],
+        &mut recv_chain,
+        &mut recv_graph,
+    )
+    .is_ok());
+
+    Ok(())
+}