@@ -378,16 +378,14 @@ bool AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const
378378{
379379 setCoinsRet.clear ();
380380 nValueRet = 0 ;
381- // Vector of results for use with waste calculation
382- // In order: calculated waste, selected inputs, selected input value (sum of input values)
383- // TODO: Use a struct representing the selection result
384- std::vector<std::tuple<CAmount, std::set<CInputCoin>, CAmount>> results;
381+ // Vector of results. We will choose the best one based on waste.
382+ std::vector<SelectionResult> results;
385383
386384 // Note that unlike KnapsackSolver, we do not include the fee for creating a change output as BnB will not create a change output.
387385 std::vector<OutputGroup> positive_groups = GroupOutputs (wallet, coins, coin_selection_params, eligibility_filter, true /* positive_only */ );
388386 if (auto bnb_result{SelectCoinsBnB (positive_groups, nTargetValue, coin_selection_params.m_cost_of_change )}) {
389387 bnb_result->ComputeAndSetWaste (CAmount (0 ));
390- results.emplace_back ( std::make_tuple ( bnb_result-> GetWaste (), bnb_result-> GetInputSet (), bnb_result-> GetSelectedValue ()) );
388+ results.push_back (* bnb_result);
391389 }
392390
393391 // The knapsack solver has some legacy behavior where it will spend dust outputs. We retain this behavior, so don't filter for positive only here.
@@ -396,15 +394,15 @@ bool AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const
396394 // So we need to include that for KnapsackSolver as well, as we are expecting to create a change output.
397395 if (auto knapsack_result{KnapsackSolver (all_groups, nTargetValue + coin_selection_params.m_change_fee )}) {
398396 knapsack_result->ComputeAndSetWaste (coin_selection_params.m_cost_of_change );
399- results.emplace_back ( std::make_tuple ( knapsack_result-> GetWaste (), knapsack_result-> GetInputSet (), knapsack_result-> GetSelectedValue ()) );
397+ results.push_back (* knapsack_result);
400398 }
401399
402400 // We include the minimum final change for SRD as we do want to avoid making really small change.
403401 // KnapsackSolver does not need this because it includes MIN_CHANGE internally.
404402 const CAmount srd_target = nTargetValue + coin_selection_params.m_change_fee + MIN_FINAL_CHANGE;
405403 if (auto srd_result{SelectCoinsSRD (positive_groups, srd_target)}) {
406404 srd_result->ComputeAndSetWaste (coin_selection_params.m_cost_of_change );
407- results.emplace_back ( std::make_tuple ( srd_result-> GetWaste (), srd_result-> GetInputSet (), srd_result-> GetSelectedValue ()) );
405+ results.push_back (* srd_result);
408406 }
409407
410408 if (results.size () == 0 ) {
@@ -414,11 +412,9 @@ bool AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const
414412
415413 // Choose the result with the least waste
416414 // If the waste is the same, choose the one which spends more inputs.
417- const auto & best_result = std::min_element (results.begin (), results.end (), [](const auto & a, const auto & b) {
418- return std::get<0 >(a) < std::get<0 >(b) || (std::get<0 >(a) == std::get<0 >(b) && std::get<1 >(a).size () > std::get<1 >(b).size ());
419- });
420- setCoinsRet = std::get<1 >(*best_result);
421- nValueRet = std::get<2 >(*best_result);
415+ auto & best_result = *std::min_element (results.begin (), results.end ());
416+ setCoinsRet = best_result.GetInputSet ();
417+ nValueRet = best_result.GetSelectedValue ();
422418 return true ;
423419}
424420
0 commit comments