]> Untitled Git - bdk/commitdiff
refactor(wallet): remove coin_selection::filter_duplicates
authornymius <155548262+nymius@users.noreply.github.com>
Mon, 13 Jan 2025 19:52:29 +0000 (16:52 -0300)
committernymius <155548262+nymius@users.noreply.github.com>
Wed, 5 Mar 2025 23:47:38 +0000 (10:47 +1100)
crates/wallet/src/wallet/coin_selection.rs

index 4429fae73e0788be48679a71088da4c8e4c3c0fd..e5654fb4dec416f2de5562b5d0bb1a52b18c8169 100644 (file)
 //! # Ok::<(), anyhow::Error>(())
 //! ```
 
-use crate::chain::collections::HashSet;
 use crate::wallet::utils::IsDust;
 use crate::Utxo;
 use crate::WeightedUtxo;
@@ -109,7 +108,6 @@ use bitcoin::{Amount, FeeRate, SignedAmount};
 
 use alloc::vec::Vec;
 use bitcoin::consensus::encode::serialize;
-use bitcoin::OutPoint;
 use bitcoin::TxIn;
 use bitcoin::{Script, Weight};
 
@@ -720,30 +718,12 @@ fn calculate_cs_result(
     }
 }
 
-/// Remove duplicate UTXOs.
-///
-/// If a UTXO appears in both `required` and `optional`, the appearance in `required` is kept.
-pub(crate) fn filter_duplicates<I>(required: I, optional: I) -> (I, I)
-where
-    I: IntoIterator<Item = WeightedUtxo> + FromIterator<WeightedUtxo>,
-{
-    let mut visited = HashSet::<OutPoint>::new();
-    let required = required
-        .into_iter()
-        .filter(|utxo| visited.insert(utxo.utxo.outpoint()))
-        .collect::<I>();
-    let optional = optional
-        .into_iter()
-        .filter(|utxo| visited.insert(utxo.utxo.outpoint()))
-        .collect::<I>();
-    (required, optional)
-}
-
 #[cfg(test)]
 mod test {
     use assert_matches::assert_matches;
     use bitcoin::hashes::Hash;
-    use chain::{BlockId, ChainPosition, ConfirmationBlockTime};
+    use bitcoin::OutPoint;
+    use chain::{ChainPosition, ConfirmationBlockTime};
     use core::str::FromStr;
     use rand::rngs::StdRng;
 
@@ -751,7 +731,6 @@ mod test {
 
     use super::*;
     use crate::types::*;
-    use crate::wallet::coin_selection::filter_duplicates;
 
     use rand::prelude::SliceRandom;
     use rand::{thread_rng, Rng, RngCore, SeedableRng};
@@ -1618,102 +1597,6 @@ mod test {
         assert_eq!(res.selected_amount(), Amount::from_sat(200_000));
     }
 
-    #[test]
-    fn test_filter_duplicates() {
-        fn utxo(txid: &str, value: u64) -> WeightedUtxo {
-            WeightedUtxo {
-                satisfaction_weight: Weight::ZERO,
-                utxo: Utxo::Local(LocalOutput {
-                    outpoint: OutPoint::new(bitcoin::hashes::Hash::hash(txid.as_bytes()), 0),
-                    txout: TxOut {
-                        value: Amount::from_sat(value),
-                        script_pubkey: ScriptBuf::new(),
-                    },
-                    keychain: KeychainKind::External,
-                    is_spent: false,
-                    derivation_index: 0,
-                    chain_position: ChainPosition::Confirmed {
-                        anchor: ConfirmationBlockTime {
-                            block_id: BlockId {
-                                height: 12345,
-                                hash: BlockHash::all_zeros(),
-                            },
-                            confirmation_time: 12345,
-                        },
-                        transitively: None,
-                    },
-                }),
-            }
-        }
-
-        fn to_utxo_vec(utxos: &[(&str, u64)]) -> Vec<WeightedUtxo> {
-            let mut v = utxos
-                .iter()
-                .map(|&(txid, value)| utxo(txid, value))
-                .collect::<Vec<_>>();
-            v.sort_by_key(|u| u.utxo.outpoint());
-            v
-        }
-
-        struct TestCase<'a> {
-            name: &'a str,
-            required: &'a [(&'a str, u64)],
-            optional: &'a [(&'a str, u64)],
-            exp_required: &'a [(&'a str, u64)],
-            exp_optional: &'a [(&'a str, u64)],
-        }
-
-        let test_cases = [
-            TestCase {
-                name: "no_duplicates",
-                required: &[("A", 1000), ("B", 2100)],
-                optional: &[("C", 1000)],
-                exp_required: &[("A", 1000), ("B", 2100)],
-                exp_optional: &[("C", 1000)],
-            },
-            TestCase {
-                name: "duplicate_required_utxos",
-                required: &[("A", 3000), ("B", 1200), ("C", 1234), ("A", 3000)],
-                optional: &[("D", 2100)],
-                exp_required: &[("A", 3000), ("B", 1200), ("C", 1234)],
-                exp_optional: &[("D", 2100)],
-            },
-            TestCase {
-                name: "duplicate_optional_utxos",
-                required: &[("A", 3000), ("B", 1200)],
-                optional: &[("C", 5000), ("D", 1300), ("C", 5000)],
-                exp_required: &[("A", 3000), ("B", 1200)],
-                exp_optional: &[("C", 5000), ("D", 1300)],
-            },
-            TestCase {
-                name: "duplicate_across_required_and_optional_utxos",
-                required: &[("A", 3000), ("B", 1200), ("C", 2100)],
-                optional: &[("A", 3000), ("D", 1200), ("E", 5000)],
-                exp_required: &[("A", 3000), ("B", 1200), ("C", 2100)],
-                exp_optional: &[("D", 1200), ("E", 5000)],
-            },
-        ];
-
-        for (i, t) in test_cases.into_iter().enumerate() {
-            let (required, optional) =
-                filter_duplicates(to_utxo_vec(t.required), to_utxo_vec(t.optional));
-            assert_eq!(
-                required,
-                to_utxo_vec(t.exp_required),
-                "[{}:{}] unexpected `required` result",
-                i,
-                t.name
-            );
-            assert_eq!(
-                optional,
-                to_utxo_vec(t.exp_optional),
-                "[{}:{}] unexpected `optional` result",
-                i,
-                t.name
-            );
-        }
-    }
-
     #[test]
     fn test_deterministic_coin_selection_picks_same_utxos() {
         enum CoinSelectionAlgo {