mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-01 16:53:52 +02:00
wallet: refactor coin selection algos to return util::Result
so the selection processes can retrieve different errors and not uninformative std::nullopt
This commit is contained in:
@@ -554,25 +554,34 @@ util::Result<SelectionResult> ChooseSelectionResult(const CAmount& nTargetValue,
|
||||
{
|
||||
// Vector of results. We will choose the best one based on waste.
|
||||
std::vector<SelectionResult> results;
|
||||
std::vector<util::Result<SelectionResult>> errors;
|
||||
auto append_error = [&] (const util::Result<SelectionResult>& result) {
|
||||
// If any specific error message appears here, then something different from a simple "no selection found" happened.
|
||||
// Let's save it, so it can be retrieved to the user if no other selection algorithm succeeded.
|
||||
if (HasErrorMsg(result)) {
|
||||
errors.emplace_back(result);
|
||||
}
|
||||
};
|
||||
|
||||
if (auto bnb_result{SelectCoinsBnB(groups.positive_group, nTargetValue, coin_selection_params.m_cost_of_change)}) {
|
||||
results.push_back(*bnb_result);
|
||||
}
|
||||
} else append_error(bnb_result);
|
||||
|
||||
// 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.
|
||||
if (auto knapsack_result{KnapsackSolver(groups.mixed_group, nTargetValue, coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
|
||||
knapsack_result->ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee);
|
||||
results.push_back(*knapsack_result);
|
||||
}
|
||||
} else append_error(knapsack_result);
|
||||
|
||||
if (auto srd_result{SelectCoinsSRD(groups.positive_group, nTargetValue, coin_selection_params.rng_fast)}) {
|
||||
srd_result->ComputeAndSetWaste(coin_selection_params.min_viable_change, coin_selection_params.m_cost_of_change, coin_selection_params.m_change_fee);
|
||||
results.push_back(*srd_result);
|
||||
}
|
||||
} else append_error(srd_result);
|
||||
|
||||
if (results.empty()) {
|
||||
// No solution found
|
||||
return util::Error();
|
||||
// No solution found, retrieve the first explicit error (if any).
|
||||
// future: add 'severity level' to errors so the worst one can be retrieved instead of the first one.
|
||||
return errors.empty() ? util::Error() : errors.front();
|
||||
}
|
||||
|
||||
std::vector<SelectionResult> eligible_results;
|
||||
|
||||
Reference in New Issue
Block a user