@@ -2557,3 +2557,137 @@ macro_rules! doctest_wallet {
25572557 wallet
25582558 } }
25592559}
2560+
2561+ #[ cfg( test) ]
2562+ mod test {
2563+ use super :: * ;
2564+ use crate :: test_utils:: get_test_tr_single_sig_xprv_and_change_desc;
2565+ use crate :: test_utils:: insert_anchor;
2566+ use crate :: test_utils:: insert_tx;
2567+
2568+ #[ test]
2569+ fn not_duplicated_utxos_across_optional_and_required ( ) {
2570+ let ( external_desc, internal_desc) = get_test_tr_single_sig_xprv_and_change_desc ( ) ;
2571+
2572+ // create new wallet
2573+ let mut wallet = Wallet :: create ( external_desc, internal_desc)
2574+ . network ( Network :: Testnet )
2575+ . create_wallet_no_persist ( )
2576+ . unwrap ( ) ;
2577+
2578+ let two_output_tx = Transaction {
2579+ input : vec ! [ ] ,
2580+ output : vec ! [
2581+ TxOut {
2582+ script_pubkey: wallet
2583+ . next_unused_address( KeychainKind :: External )
2584+ . script_pubkey( ) ,
2585+ value: Amount :: from_sat( 25_000 ) ,
2586+ } ,
2587+ TxOut {
2588+ script_pubkey: wallet
2589+ . next_unused_address( KeychainKind :: External )
2590+ . script_pubkey( ) ,
2591+ value: Amount :: from_sat( 75_000 ) ,
2592+ } ,
2593+ ] ,
2594+ version : transaction:: Version :: non_standard ( 0 ) ,
2595+ lock_time : absolute:: LockTime :: ZERO ,
2596+ } ;
2597+
2598+ let txid = two_output_tx. compute_txid ( ) ;
2599+ insert_tx ( & mut wallet, two_output_tx) ;
2600+
2601+ let expected_anchor = ConfirmationBlockTime {
2602+ block_id : wallet. latest_checkpoint ( ) . block_id ( ) ,
2603+ confirmation_time : 200 ,
2604+ } ;
2605+
2606+ insert_anchor ( & mut wallet, txid, expected_anchor) ;
2607+
2608+ let mut params = TxParams :: default ( ) ;
2609+ wallet
2610+ . get_utxo ( OutPoint { txid, vout : 0 } )
2611+ . map ( |outpoint| {
2612+ params. utxos . insert ( outpoint) ;
2613+ } )
2614+ . unwrap ( ) ;
2615+ // enforce selection of first output in transaction
2616+ let received = wallet. filter_utxos ( & params, wallet. latest_checkpoint ( ) . block_id ( ) . height ) ;
2617+ // notice expected doesn't include the first output from two_output_tx as it should be
2618+ // filtered out
2619+ let expected = vec ! [ wallet
2620+ . get_utxo( OutPoint { txid, vout: 1 } )
2621+ . map( |utxo| WeightedUtxo {
2622+ satisfaction_weight: wallet
2623+ . public_descriptor( utxo. keychain)
2624+ . max_weight_to_satisfy( )
2625+ . unwrap( ) ,
2626+ utxo: Utxo :: Local ( utxo) ,
2627+ } )
2628+ . unwrap( ) ] ;
2629+
2630+ assert_eq ! ( expected, received) ;
2631+ }
2632+
2633+ #[ test]
2634+ fn not_duplicated_utxos_in_optional_list ( ) {
2635+ let ( external_desc, internal_desc) = get_test_tr_single_sig_xprv_and_change_desc ( ) ;
2636+
2637+ // create new wallet
2638+ let mut wallet = Wallet :: create ( external_desc, internal_desc)
2639+ . network ( Network :: Testnet )
2640+ . create_wallet_no_persist ( )
2641+ . unwrap ( ) ;
2642+
2643+ let two_output_tx = Transaction {
2644+ input : vec ! [ ] ,
2645+ output : vec ! [
2646+ TxOut {
2647+ script_pubkey: wallet
2648+ . next_unused_address( KeychainKind :: External )
2649+ . script_pubkey( ) ,
2650+ value: Amount :: from_sat( 25_000 ) ,
2651+ } ,
2652+ TxOut {
2653+ script_pubkey: wallet
2654+ . next_unused_address( KeychainKind :: External )
2655+ . script_pubkey( ) ,
2656+ value: Amount :: from_sat( 75_000 ) ,
2657+ } ,
2658+ ] ,
2659+ version : transaction:: Version :: non_standard ( 0 ) ,
2660+ lock_time : absolute:: LockTime :: ZERO ,
2661+ } ;
2662+
2663+ let txid = two_output_tx. compute_txid ( ) ;
2664+
2665+ for _ in 0 ..3 {
2666+ insert_tx ( & mut wallet, two_output_tx. clone ( ) ) ;
2667+ }
2668+
2669+ let expected_anchor = ConfirmationBlockTime {
2670+ block_id : wallet. latest_checkpoint ( ) . block_id ( ) ,
2671+ confirmation_time : 200 ,
2672+ } ;
2673+
2674+ insert_anchor ( & mut wallet, txid, expected_anchor) ;
2675+
2676+ // enforce selection of first output in transaction
2677+ let received = wallet
2678+ . indexed_graph
2679+ . graph ( )
2680+ . filter_chain_unspents (
2681+ & wallet. chain ,
2682+ wallet. chain . tip ( ) . block_id ( ) ,
2683+ wallet. indexed_graph . index . outpoints ( ) . iter ( ) . cloned ( ) ,
2684+ )
2685+ . map ( |( _, full_txout) | full_txout. outpoint )
2686+ . collect :: < Vec < _ > > ( ) ;
2687+ // notice expected doesn't include the first output from two_output_tx as it should be
2688+ // filtered out
2689+ let expected = vec ! [ OutPoint { txid, vout: 0 } , OutPoint { txid, vout: 1 } ] ;
2690+
2691+ assert_eq ! ( expected, received) ;
2692+ }
2693+ }
0 commit comments