@@ -378,16 +378,14 @@ bool AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const
378
378
{
379
379
setCoinsRet.clear ();
380
380
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;
385
383
386
384
// Note that unlike KnapsackSolver, we do not include the fee for creating a change output as BnB will not create a change output.
387
385
std::vector<OutputGroup> positive_groups = GroupOutputs (wallet, coins, coin_selection_params, eligibility_filter, true /* positive_only */ );
388
386
if (auto bnb_result{SelectCoinsBnB (positive_groups, nTargetValue, coin_selection_params.m_cost_of_change )}) {
389
387
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);
391
389
}
392
390
393
391
// 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
396
394
// So we need to include that for KnapsackSolver as well, as we are expecting to create a change output.
397
395
if (auto knapsack_result{KnapsackSolver (all_groups, nTargetValue + coin_selection_params.m_change_fee )}) {
398
396
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);
400
398
}
401
399
402
400
// We include the minimum final change for SRD as we do want to avoid making really small change.
403
401
// KnapsackSolver does not need this because it includes MIN_CHANGE internally.
404
402
const CAmount srd_target = nTargetValue + coin_selection_params.m_change_fee + MIN_FINAL_CHANGE;
405
403
if (auto srd_result{SelectCoinsSRD (positive_groups, srd_target)}) {
406
404
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);
408
406
}
409
407
410
408
if (results.size () == 0 ) {
@@ -414,11 +412,9 @@ bool AttemptSelection(const CWallet& wallet, const CAmount& nTargetValue, const
414
412
415
413
// Choose the result with the least waste
416
414
// 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 ();
422
418
return true ;
423
419
}
424
420
0 commit comments