@@ -510,7 +510,7 @@ std::vector<OutputGroup> GroupOutputs(const CWallet& wallet, const std::vector<C
510510 return groups_out;
511511}
512512
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,
514514 const CoinSelectionParams& coin_selection_params, bool allow_mixed_output_types)
515515{
516516 // Run coin selection on each OutputType and compute the Waste Metric
@@ -534,10 +534,10 @@ std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAm
534534 }
535535 // 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
536536 // find a solution using all available coins
537- return std:: nullopt ;
537+ return util::Error () ;
538538};
539539
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)
541541{
542542 // Vector of results. We will choose the best one based on waste.
543543 std::vector<SelectionResult> results;
@@ -561,7 +561,7 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
561561
562562 if (results.empty ()) {
563563 // No solution found
564- return std:: nullopt ;
564+ return util::Error () ;
565565 }
566566
567567 std::vector<SelectionResult> eligible_results;
@@ -571,7 +571,7 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
571571 });
572572
573573 if (eligible_results.empty ()) {
574- return std:: nullopt ;
574+ return util::Error () ;
575575 }
576576
577577 // Choose the result with the least waste
@@ -580,15 +580,15 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
580580 return best_result;
581581}
582582
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)
586586{
587587 // Deduct preset inputs amount from the search target
588588 CAmount selection_target = nTargetValue - pre_set_inputs.total_amount ;
589589
590590 // 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 () ;
592592
593593 // Return if we can cover the target only with the preset inputs
594594 if (selection_target <= 0 ) {
@@ -603,7 +603,7 @@ std::optional<SelectionResult> SelectCoins(const CWallet& wallet, CoinsResult& a
603603 CAmount available_coins_total_amount = coin_selection_params.m_subtract_fee_outputs ? available_coins.GetTotalAmount () :
604604 (available_coins.GetEffectiveTotalAmount ().has_value () ? *available_coins.GetEffectiveTotalAmount () : 0 );
605605 if (selection_target > available_coins_total_amount) {
606- return std:: nullopt ; // Insufficient funds
606+ return util::Error () ; // Insufficient funds
607607 }
608608
609609 // Start wallet Coin Selection procedure
@@ -627,7 +627,7 @@ struct SelectionFilter {
627627 bool allow_mixed_output_types{true };
628628};
629629
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)
631631{
632632 unsigned int limit_ancestor_count = 0 ;
633633 unsigned int limit_descendant_count = 0 ;
@@ -648,7 +648,7 @@ std::optional<SelectionResult> AutomaticCoinSelection(const CWallet& wallet, Coi
648648 // Coin Selection attempts to select inputs from a pool of eligible UTXOs to fund the
649649 // transaction at a target feerate. If an attempt fails, more attempts may be made using a more
650650 // permissive CoinEligibilityFilter.
651- std::optional <SelectionResult> res = [&] {
651+ util::Result <SelectionResult> res = [&] {
652652 // Place coins eligibility filters on a scope increasing order.
653653 std::vector<SelectionFilter> ordered_filters{
654654 // 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
687687 coin_selection_params, select_filter.allow_mixed_output_types )}) return res;
688688 }
689689 // Coin Selection failed.
690- return std::optional <SelectionResult>();
690+ return util::Result <SelectionResult>(util::Error () );
691691 }();
692692
693693 return res;
@@ -914,13 +914,14 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
914914 }
915915
916916 // 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 ) {
919919 return util::Error{_ (" Insufficient funds" )};
920920 }
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 ());
922923
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 );
924925 if (change_amount > 0 ) {
925926 CTxOut newTxOut (change_amount, scriptChange);
926927 if (nChangePosInOut == -1 ) {
@@ -935,7 +936,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
935936 }
936937
937938 // Shuffle selected coins and fill in final vin
938- std::vector<COutput> selected_coins = result-> GetShuffledInputVector ();
939+ std::vector<COutput> selected_coins = result. GetShuffledInputVector ();
939940
940941 // The sequence number is set to non-maxint so that DiscourageFeeSniping
941942 // works.
@@ -960,7 +961,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
960961 CAmount fee_needed = coin_selection_params.m_effective_feerate .GetFee (nBytes);
961962 const CAmount output_value = CalculateOutputValue (txNew);
962963 Assume (recipients_sum + change_amount == output_value);
963- CAmount current_fee = result-> GetSelectedValue () - output_value;
964+ CAmount current_fee = result. GetSelectedValue () - output_value;
964965
965966 // Sanity check that the fee cannot be negative as that means we have more output value than input value
966967 if (current_fee < 0 ) {
@@ -971,7 +972,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
971972 if (nChangePosInOut != -1 && fee_needed < current_fee) {
972973 auto & change = txNew.vout .at (nChangePosInOut);
973974 change.nValue += current_fee - fee_needed;
974- current_fee = result-> GetSelectedValue () - CalculateOutputValue (txNew);
975+ current_fee = result. GetSelectedValue () - CalculateOutputValue (txNew);
975976 if (fee_needed != current_fee) {
976977 return util::Error{Untranslated (STR_INTERNAL_BUG (" Change adjustment: Fee needed != fee paid" ))};
977978 }
@@ -1010,7 +1011,7 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
10101011 }
10111012 ++i;
10121013 }
1013- current_fee = result-> GetSelectedValue () - CalculateOutputValue (txNew);
1014+ current_fee = result. GetSelectedValue () - CalculateOutputValue (txNew);
10141015 if (fee_needed != current_fee) {
10151016 return util::Error{Untranslated (STR_INTERNAL_BUG (" SFFO: Fee needed != fee paid" ))};
10161017 }
0 commit comments