From: nymius <155548262+nymius@users.noreply.github.com> Date: Mon, 13 Jan 2025 19:52:29 +0000 (-0300) Subject: refactor(wallet): remove coin_selection::filter_duplicates X-Git-Tag: wallet-1.2.0~19^2~1 X-Git-Url: http://internal-gitweb-vhost/?a=commitdiff_plain;h=39df2b940a161d6b5468e6a6c36f888c14a3e24e;p=bdk refactor(wallet): remove coin_selection::filter_duplicates --- diff --git a/crates/wallet/src/wallet/coin_selection.rs b/crates/wallet/src/wallet/coin_selection.rs index 4429fae7..e5654fb4 100644 --- a/crates/wallet/src/wallet/coin_selection.rs +++ b/crates/wallet/src/wallet/coin_selection.rs @@ -101,7 +101,6 @@ //! # 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(required: I, optional: I) -> (I, I) -where - I: IntoIterator + FromIterator, -{ - let mut visited = HashSet::::new(); - let required = required - .into_iter() - .filter(|utxo| visited.insert(utxo.utxo.outpoint())) - .collect::(); - let optional = optional - .into_iter() - .filter(|utxo| visited.insert(utxo.utxo.outpoint())) - .collect::(); - (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 { - let mut v = utxos - .iter() - .map(|&(txid, value)| utxo(txid, value)) - .collect::>(); - 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 {