@@ -451,9 +451,34 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
451451}
452452
453453std::optional<SelectionResult> AttemptSelection (const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const CoinsResult& available_coins,
454- const CoinSelectionParams& coin_selection_params)
454+ const CoinSelectionParams& coin_selection_params, bool allow_mixed_output_types )
455455{
456- std::optional<SelectionResult> result = ChooseSelectionResult (wallet, nTargetValue, eligibility_filter, available_coins.all (), coin_selection_params);
456+ // Run coin selection on each OutputType and compute the Waste Metric
457+ std::vector<SelectionResult> results;
458+ if (auto result{ChooseSelectionResult (wallet, nTargetValue, eligibility_filter, available_coins.legacy , coin_selection_params)}) {
459+ results.push_back (*result);
460+ }
461+ if (auto result{ChooseSelectionResult (wallet, nTargetValue, eligibility_filter, available_coins.P2SH_segwit , coin_selection_params)}) {
462+ results.push_back (*result);
463+ }
464+ if (auto result{ChooseSelectionResult (wallet, nTargetValue, eligibility_filter, available_coins.bech32 , coin_selection_params)}) {
465+ results.push_back (*result);
466+ }
467+ if (auto result{ChooseSelectionResult (wallet, nTargetValue, eligibility_filter, available_coins.bech32m , coin_selection_params)}) {
468+ results.push_back (*result);
469+ }
470+
471+ // If we can't fund the transaction from any individual OutputType, run coin selection
472+ // over all available coins, else pick the best solution from the results
473+ if (results.size () == 0 ) {
474+ if (allow_mixed_output_types) {
475+ if (auto result{ChooseSelectionResult (wallet, nTargetValue, eligibility_filter, available_coins.all (), coin_selection_params)}) {
476+ return result;
477+ }
478+ }
479+ return std::optional<SelectionResult>();
480+ };
481+ std::optional<SelectionResult> result{*std::min_element (results.begin (), results.end ())};
457482 return result;
458483};
459484
@@ -601,34 +626,35 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
601626
602627 // If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
603628 // confirmations on outputs received from other wallets and only spend confirmed change.
604- if (auto r1{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (1 , 6 , 0 ), available_coins, coin_selection_params)}) return r1;
605- if (auto r2{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (1 , 1 , 0 ), available_coins, coin_selection_params)}) return r2;
629+ if (auto r1{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (1 , 6 , 0 ), available_coins, coin_selection_params, /* allow_mixed_output_types=*/ false )}) return r1;
630+ // Allow mixing only if no solution from any single output type can be found
631+ if (auto r2{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (1 , 1 , 0 ), available_coins, coin_selection_params, /* allow_mixed_output_types=*/ true )}) return r2;
606632
607633 // Fall back to using zero confirmation change (but with as few ancestors in the mempool as
608634 // possible) if we cannot fund the transaction otherwise.
609635 if (wallet.m_spend_zero_conf_change ) {
610- if (auto r3{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (0 , 1 , 2 ), available_coins, coin_selection_params)}) return r3;
636+ if (auto r3{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (0 , 1 , 2 ), available_coins, coin_selection_params, /* allow_mixed_output_types= */ true )}) return r3;
611637 if (auto r4{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (0 , 1 , std::min ((size_t )4 , max_ancestors/3 ), std::min ((size_t )4 , max_descendants/3 )),
612- available_coins, coin_selection_params)}) {
638+ available_coins, coin_selection_params, /* allow_mixed_output_types= */ true )}) {
613639 return r4;
614640 }
615641 if (auto r5{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors/2 , max_descendants/2 ),
616- available_coins, coin_selection_params)}) {
642+ available_coins, coin_selection_params, /* allow_mixed_output_types= */ true )}) {
617643 return r5;
618644 }
619645 // If partial groups are allowed, relax the requirement of spending OutputGroups (groups
620646 // of UTXOs sent to the same address, which are obviously controlled by a single wallet)
621647 // in their entirety.
622648 if (auto r6{AttemptSelection (wallet, value_to_select, CoinEligibilityFilter (0 , 1 , max_ancestors-1 , max_descendants-1 , true /* include_partial_groups */ ),
623- available_coins, coin_selection_params)}) {
649+ available_coins, coin_selection_params, /* allow_mixed_output_types= */ true )}) {
624650 return r6;
625651 }
626652 // Try with unsafe inputs if they are allowed. This may spend unconfirmed outputs
627653 // received from other wallets.
628654 if (coin_control.m_include_unsafe_inputs ) {
629655 if (auto r7{AttemptSelection (wallet, value_to_select,
630656 CoinEligibilityFilter (0 /* conf_mine */ , 0 /* conf_theirs */ , max_ancestors-1 , max_descendants-1 , true /* include_partial_groups */ ),
631- available_coins, coin_selection_params)}) {
657+ available_coins, coin_selection_params, /* allow_mixed_output_types= */ true )}) {
632658 return r7;
633659 }
634660 }
@@ -638,7 +664,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
638664 if (!fRejectLongChains ) {
639665 if (auto r8{AttemptSelection (wallet, value_to_select,
640666 CoinEligibilityFilter (0 , 1 , std::numeric_limits<uint64_t >::max (), std::numeric_limits<uint64_t >::max (), true /* include_partial_groups */ ),
641- available_coins, coin_selection_params)}) {
667+ available_coins, coin_selection_params, /* allow_mixed_output_types= */ true )}) {
642668 return r8;
643669 }
644670 }
0 commit comments