@@ -451,9 +451,34 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
451
451
}
452
452
453
453
std::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 )
455
455
{
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 ())};
457
482
return result;
458
483
};
459
484
@@ -601,34 +626,35 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
601
626
602
627
// If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
603
628
// 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;
606
632
607
633
// Fall back to using zero confirmation change (but with as few ancestors in the mempool as
608
634
// possible) if we cannot fund the transaction otherwise.
609
635
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;
611
637
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 )}) {
613
639
return r4;
614
640
}
615
641
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 )}) {
617
643
return r5;
618
644
}
619
645
// If partial groups are allowed, relax the requirement of spending OutputGroups (groups
620
646
// of UTXOs sent to the same address, which are obviously controlled by a single wallet)
621
647
// in their entirety.
622
648
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 )}) {
624
650
return r6;
625
651
}
626
652
// Try with unsafe inputs if they are allowed. This may spend unconfirmed outputs
627
653
// received from other wallets.
628
654
if (coin_control.m_include_unsafe_inputs ) {
629
655
if (auto r7{AttemptSelection (wallet, value_to_select,
630
656
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 )}) {
632
658
return r7;
633
659
}
634
660
}
@@ -638,7 +664,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
638
664
if (!fRejectLongChains ) {
639
665
if (auto r8{AttemptSelection (wallet, value_to_select,
640
666
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 )}) {
642
668
return r8;
643
669
}
644
670
}
0 commit comments