diff --git a/src/testutils/blockchain_tests.rs b/src/testutils/blockchain_tests.rs index a3d7c2b17..392475cf0 100644 --- a/src/testutils/blockchain_tests.rs +++ b/src/testutils/blockchain_tests.rs @@ -455,7 +455,7 @@ macro_rules! bdk_blockchain_tests { assert!(wallet.database().deref().get_sync_time().unwrap().is_some(), "sync_time hasn't been updated"); assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 50_000, "incorrect balance"); - assert_eq!(wallet.list_unspent().unwrap()[0].keychain, KeychainKind::External, "incorrect keychain kind"); + assert_eq!(wallet.iter_unspent().unwrap().next().unwrap().keychain, KeychainKind::External, "incorrect keychain kind"); let list_tx_item = &wallet.list_transactions(false).unwrap()[0]; assert_eq!(list_tx_item.txid, txid, "incorrect txid"); @@ -518,7 +518,7 @@ macro_rules! bdk_blockchain_tests { assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 105_000, "incorrect balance"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); - assert_eq!(wallet.list_unspent().unwrap().len(), 3, "incorrect number of unspents"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 3, "incorrect number of unspents"); let list_tx_item = &wallet.list_transactions(false).unwrap()[0]; assert_eq!(list_tx_item.txid, txid, "incorrect txid"); @@ -542,7 +542,7 @@ macro_rules! bdk_blockchain_tests { assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 75_000, "incorrect balance"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs"); - assert_eq!(wallet.list_unspent().unwrap().len(), 2, "incorrect number of unspent"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 2, "incorrect number of unspent"); } #[test] @@ -576,7 +576,7 @@ macro_rules! bdk_blockchain_tests { assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 50_000, "incorrect balance"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); - assert_eq!(wallet.list_unspent().unwrap().len(), 1, "incorrect unspent"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 1, "incorrect unspent"); let list_tx_item = &wallet.list_transactions(false).unwrap()[0]; assert_eq!(list_tx_item.txid, txid, "incorrect txid"); @@ -590,7 +590,7 @@ macro_rules! bdk_blockchain_tests { assert_eq!(wallet.get_balance().unwrap().untrusted_pending, 50_000, "incorrect balance after bump"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs after bump"); - assert_eq!(wallet.list_unspent().unwrap().len(), 1, "incorrect unspent after bump"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 1, "incorrect unspent after bump"); let list_tx_item = &wallet.list_transactions(false).unwrap()[0]; assert_eq!(list_tx_item.txid, new_txid, "incorrect txid after bump"); @@ -613,7 +613,7 @@ macro_rules! bdk_blockchain_tests { wallet.sync(&blockchain, SyncOptions::default()).unwrap(); assert_eq!(wallet.get_balance().unwrap().get_spendable(), 50_000, "incorrect balance"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 1, "incorrect number of txs"); - assert_eq!(wallet.list_unspent().unwrap().len(), 1, "incorrect number of unspents"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 1, "incorrect number of unspents"); let list_tx_item = &wallet.list_transactions(false).unwrap()[0]; assert_eq!(list_tx_item.txid, txid, "incorrect txid"); @@ -661,7 +661,7 @@ macro_rules! bdk_blockchain_tests { assert_eq!(wallet.get_balance().unwrap().confirmed, details.received, "incorrect balance after send"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "incorrect number of txs"); - assert_eq!(wallet.list_unspent().unwrap().len(), 1, "incorrect number of unspents"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 1, "incorrect number of unspents"); } // Syncing wallet should not result in wallet address index to decrement. @@ -1178,7 +1178,7 @@ macro_rules! bdk_blockchain_tests { wallet.sync(&blockchain, SyncOptions::default()).unwrap(); assert_eq!(wallet.get_balance().unwrap().get_spendable(), details.received, "wallet has incorrect balance after send"); assert_eq!(wallet.list_transactions(false).unwrap().len(), 2, "wallet has incorrect number of txs"); - assert_eq!(wallet.list_unspent().unwrap().len(), 1, "wallet has incorrect number of unspents"); + assert_eq!(wallet.iter_unspent().unwrap().count(), 1, "wallet has incorrect number of unspents"); test_client.generate(1, None); // 5. Verify 25_000 sats are received by test bitcoind node taproot wallet @@ -1249,7 +1249,7 @@ macro_rules! bdk_blockchain_tests { let initial_tx = psbt.extract_tx(); let _sent_txid = blockchain.broadcast(&initial_tx).unwrap(); wallet.sync(&blockchain, SyncOptions::default()).unwrap(); - for utxo in wallet.list_unspent().unwrap() { + for utxo in wallet.iter_unspent().unwrap() { // Making sure the TXO we just spent is not returned by list_unspent assert!(utxo.outpoint != initial_tx.input[0].previous_output, "wallet displays spent txo in unspents"); } @@ -1265,7 +1265,7 @@ macro_rules! bdk_blockchain_tests { builder .add_utxo(initial_tx.input[0].previous_output) .expect("Can't manually add an UTXO spent"); - for utxo in wallet.list_unspent().unwrap() { + for utxo in wallet.iter_unspent().unwrap() { // Making sure the TXO we just spent is not returned by list_unspent assert!(utxo.outpoint != initial_tx.input[0].previous_output, "wallet displays spent txo in unspents"); } diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index 2e3d9fdff..bd30164f1 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -411,14 +411,22 @@ where /// /// Note that this method only operates on the internal database, which first needs to be /// [`Wallet::sync`] manually. + #[deprecated = "Use Wallet::iter_unspent"] pub fn list_unspent(&self) -> Result, Error> { + self.iter_unspent().map(|iter| iter.collect()) + } + + /// Returns an iterator of unspent outputs (UTXOs) of this wallet. + /// + /// Note that this method only operates on the internal database, which first needs to be + /// [`Wallet::sync`] manually. + pub fn iter_unspent(&self) -> Result + '_, Error> { Ok(self .database .borrow() .iter_utxos()? .into_iter() - .filter(|l| !l.is_spent) - .collect()) + .filter(|l| !l.is_spent)) } /// Returns the `UTXO` owned by this wallet corresponding to `outpoint` if it exists in the @@ -474,7 +482,7 @@ where let mut trusted_pending = 0; let mut untrusted_pending = 0; let mut confirmed = 0; - let utxos = self.list_unspent()?; + let database = self.database.borrow(); let last_sync_height = match database .get_sync_time()? @@ -484,7 +492,7 @@ where // None means database was never synced None => return Ok(Balance::default()), }; - for u in utxos { + for u in self.iter_unspent()? { // Unwrap used since utxo set is created from database let tx = database .get_tx(&u.outpoint.txid, true)? @@ -1420,8 +1428,7 @@ where fn get_available_utxos(&self) -> Result, Error> { Ok(self - .list_unspent()? - .into_iter() + .iter_unspent()? .map(|utxo| { let keychain = utxo.keychain; ( @@ -3010,7 +3017,7 @@ pub(crate) mod test { get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)"); let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap(); - let utxo = wallet2.list_unspent().unwrap().remove(0); + let utxo = wallet2.iter_unspent().unwrap().next().unwrap(); let foreign_utxo_satisfaction = wallet2 .get_descriptor_for_keychain(KeychainKind::External) .max_satisfaction_weight() @@ -3075,7 +3082,7 @@ pub(crate) mod test { fn test_add_foreign_utxo_invalid_psbt_input() { let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); let mut builder = wallet.build_tx(); - let outpoint = wallet.list_unspent().unwrap()[0].outpoint; + let outpoint = wallet.iter_unspent().unwrap().next().unwrap().outpoint; let foreign_utxo_satisfaction = wallet .get_descriptor_for_keychain(KeychainKind::External) .max_satisfaction_weight() @@ -3091,7 +3098,7 @@ pub(crate) mod test { let (wallet2, _, txid2) = get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)"); - let utxo2 = wallet2.list_unspent().unwrap().remove(0); + let utxo2 = wallet2.iter_unspent().unwrap().next().unwrap(); let tx1 = wallet1 .database .borrow() @@ -3149,7 +3156,7 @@ pub(crate) mod test { let (wallet2, _, txid2) = get_funded_wallet("wpkh(cVbZ8ovhye9AoAHFsqobCf7LxbXDAECy9Kb8TZdfsDYMZGBUyCnm)"); let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap(); - let utxo2 = wallet2.list_unspent().unwrap().remove(0); + let utxo2 = wallet2.iter_unspent().unwrap().next().unwrap(); let satisfaction_weight = wallet2 .get_descriptor_for_keychain(KeychainKind::External) @@ -3218,7 +3225,7 @@ pub(crate) mod test { fn test_get_psbt_input() { // this should grab a known good utxo and set the input let (wallet, _, _) = get_funded_wallet(get_test_wpkh()); - for utxo in wallet.list_unspent().unwrap() { + for utxo in wallet.iter_unspent().unwrap() { let psbt_input = wallet.get_psbt_input(utxo, None, false).unwrap(); assert!(psbt_input.witness_utxo.is_some() || psbt_input.non_witness_utxo.is_some()); } @@ -5013,7 +5020,7 @@ pub(crate) mod test { let (wallet2, _, _) = get_funded_wallet(get_test_tr_single_sig()); let addr = Address::from_str("2N1Ffz3WaNzbeLFBb51xyFMHYSEUXcbiSoX").unwrap(); - let utxo = wallet2.list_unspent().unwrap().remove(0); + let utxo = wallet2.iter_unspent().unwrap().next().unwrap(); let psbt_input = wallet2.get_psbt_input(utxo.clone(), None, false).unwrap(); let foreign_utxo_satisfaction = wallet2 .get_descriptor_for_keychain(KeychainKind::External)