@@ -510,7 +510,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
510
510
return groups_out;
511
511
}
512
512
513
- std::optional <SelectionResult> AttemptSelection (const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const CoinsResult& available_coins,
513
+ util::Result <SelectionResult> AttemptSelection (const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const CoinsResult& available_coins,
514
514
const CoinSelectionParams& coin_selection_params, bool allow_mixed_output_types)
515
515
{
516
516
// Run coin selection on each OutputType and compute the Waste Metric
@@ -534,10 +534,10 @@ std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAm
534
534
}
535
535
// Either mixing is not allowed and we couldn't find a solution from any single OutputType, or mixing was allowed and we still couldn't
536
536
// find a solution using all available coins
537
- return std::nullopt ;
537
+ return util::Error () ;
538
538
};
539
539
540
- std::optional <SelectionResult> ChooseSelectionResult (const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const std::vector<COutput>& available_coins, const CoinSelectionParams& coin_selection_params)
540
+ util::Result <SelectionResult> ChooseSelectionResult (const CWallet& wallet, const CAmount& nTargetValue, const CoinEligibilityFilter& eligibility_filter, const std::vector<COutput>& available_coins, const CoinSelectionParams& coin_selection_params)
541
541
{
542
542
// Vector of results. We will choose the best one based on waste.
543
543
std::vector<SelectionResult> results;
@@ -561,7 +561,7 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
561
561
562
562
if (results.empty ()) {
563
563
// No solution found
564
- return std::nullopt ;
564
+ return util::Error () ;
565
565
}
566
566
567
567
std::vector<SelectionResult> eligible_results;
@@ -571,7 +571,7 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
571
571
});
572
572
573
573
if (eligible_results.empty ()) {
574
- return std::nullopt ;
574
+ return util::Error () ;
575
575
}
576
576
577
577
// Choose the result with the least waste
@@ -580,15 +580,15 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
580
580
return best_result;
581
581
}
582
582
583
- std::optional <SelectionResult> SelectCoins (const CWallet& wallet, CoinsResult& available_coins, const PreSelectedInputs& pre_set_inputs,
584
- const CAmount& nTargetValue, const CCoinControl& coin_control,
585
- const CoinSelectionParams& coin_selection_params)
583
+ util::Result <SelectionResult> SelectCoins (const CWallet& wallet, CoinsResult& available_coins, const PreSelectedInputs& pre_set_inputs,
584
+ const CAmount& nTargetValue, const CCoinControl& coin_control,
585
+ const CoinSelectionParams& coin_selection_params)
586
586
{
587
587
// Deduct preset inputs amount from the search target
588
588
CAmount selection_target = nTargetValue - pre_set_inputs.total_amount ;
589
589
590
590
// Return if automatic coin selection is disabled, and we don't cover the selection target
591
- if (!coin_control.m_allow_other_inputs && selection_target > 0 ) return std::nullopt ;
591
+ if (!coin_control.m_allow_other_inputs && selection_target > 0 ) return util::Error () ;
592
592
593
593
// Return if we can cover the target only with the preset inputs
594
594
if (selection_target <= 0 ) {
@@ -603,7 +603,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
603
603
CAmount available_coins_total_amount = coin_selection_params.m_subtract_fee_outputs ? available_coins.GetTotalAmount () :
604
604
(available_coins.GetEffectiveTotalAmount ().has_value () ? *available_coins.GetEffectiveTotalAmount () : 0 );
605
605
if (selection_target > available_coins_total_amount) {
606
- return std::nullopt ; // Insufficient funds
606
+ return util::Error () ; // Insufficient funds
607
607
}
608
608
609
609
// Start wallet Coin Selection procedure
@@ -627,7 +627,7 @@ struct SelectionFilter {
627
627
bool allow_mixed_output_types{true };
628
628
};
629
629
630
- std::optional <SelectionResult> AutomaticCoinSelection (const CWallet& wallet, CoinsResult& available_coins, const CAmount& value_to_select, const CCoinControl& coin_control, const CoinSelectionParams& coin_selection_params)
630
+ util::Result <SelectionResult> AutomaticCoinSelection (const CWallet& wallet, CoinsResult& available_coins, const CAmount& value_to_select, const CCoinControl& coin_control, const CoinSelectionParams& coin_selection_params)
631
631
{
632
632
unsigned int limit_ancestor_count = 0 ;
633
633
unsigned int limit_descendant_count = 0 ;
@@ -648,7 +648,7 @@ std::optional<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, Coi
648
648
// Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the
649
649
// transaction at a target feerate. If an attempt fails, more attempts may be made using a more
650
650
// permissive CoinEligibilityFilter.
651
- std::optional <SelectionResult> res = [&] {
651
+ util::Result <SelectionResult> res = [&] {
652
652
// Place coins eligibility filters on a scope increasing order.
653
653
std::vector<SelectionFilter> ordered_filters{
654
654
// If possible, fund the transaction with confirmed UTXOs only. Prefer at least six
@@ -687,7 +687,7 @@ std::optional<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, Coi
687
687
coin_selection_params, select_filter.allow_mixed_output_types )}) return res;
688
688
}
689
689
// Coin Selection failed.
690
- return std::optional <SelectionResult>();
690
+ return util::Result <SelectionResult>(util::Error () );
691
691
}();
692
692
693
693
return res;
@@ -914,13 +914,14 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
914
914
}
915
915
916
916
// Choose coins to use
917
- std::optional<SelectionResult> result = SelectCoins (wallet, available_coins, preset_inputs, /* nTargetValue=*/ selection_target, coin_control, coin_selection_params);
918
- if (!result ) {
917
+ auto select_coins_res = SelectCoins (wallet, available_coins, preset_inputs, /* nTargetValue=*/ selection_target, coin_control, coin_selection_params);
918
+ if (!select_coins_res ) {
919
919
return util::Error{_ (" Insufficient funds" )};
920
920
}
921
- TRACE5 (coin_selection, selected_coins, wallet.GetName ().c_str (), GetAlgorithmName (result->GetAlgo ()).c_str (), result->GetTarget (), result->GetWaste (), result->GetSelectedValue ());
921
+ const SelectionResult& result = *select_coins_res;
922
+ TRACE5 (coin_selection, selected_coins, wallet.GetName ().c_str (), GetAlgorithmName (result.GetAlgo ()).c_str (), result.GetTarget (), result.GetWaste (), result.GetSelectedValue ());
922
923
923
- const CAmount change_amount = result-> GetChange (coin_selection_params.min_viable_change , coin_selection_params.m_change_fee );
924
+ const CAmount change_amount = result. GetChange (coin_selection_params.min_viable_change , coin_selection_params.m_change_fee );
924
925
if (change_amount > 0 ) {
925
926
CTxOut newTxOut (change_amount, scriptChange);
926
927
if (nChangePosInOut == -1 ) {
@@ -935,7 +936,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
935
936
}
936
937
937
938
// Shuffle selected coins and fill in final vin
938
- std::vector<COutput> selected_coins = result-> GetShuffledInputVector ();
939
+ std::vector<COutput> selected_coins = result. GetShuffledInputVector ();
939
940
940
941
// The sequence number is set to non-maxint so that DiscourageFeeSniping
941
942
// works.
@@ -960,7 +961,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
960
961
CAmount fee_needed = coin_selection_params.m_effective_feerate .GetFee (nBytes);
961
962
const CAmount output_value = CalculateOutputValue (txNew);
962
963
Assume (recipients_sum + change_amount == output_value);
963
- CAmount current_fee = result-> GetSelectedValue () - output_value;
964
+ CAmount current_fee = result. GetSelectedValue () - output_value;
964
965
965
966
// Sanity check that the fee cannot be negative as that means we have more output value than input value
966
967
if (current_fee < 0 ) {
@@ -971,7 +972,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
971
972
if (nChangePosInOut != -1 && fee_needed < current_fee) {
972
973
auto & change = txNew.vout .at (nChangePosInOut);
973
974
change.nValue += current_fee - fee_needed;
974
- current_fee = result-> GetSelectedValue () - CalculateOutputValue (txNew);
975
+ current_fee = result. GetSelectedValue () - CalculateOutputValue (txNew);
975
976
if (fee_needed != current_fee) {
976
977
return util::Error{Untranslated (STR_INTERNAL_BUG (" Change adjustment: Fee needed != fee paid" ))};
977
978
}
@@ -1010,7 +1011,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
1010
1011
}
1011
1012
++i;
1012
1013
}
1013
- current_fee = result-> GetSelectedValue () - CalculateOutputValue (txNew);
1014
+ current_fee = result. GetSelectedValue () - CalculateOutputValue (txNew);
1014
1015
if (fee_needed != current_fee) {
1015
1016
return util::Error{Untranslated (STR_INTERNAL_BUG (" SFFO: Fee needed != fee paid" ))};
1016
1017
}
0 commit comments