mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-10 05:11:20 +02:00
wallet: accurate SelectionResult::m_target
SelectionResult::m_target should be equal to actual selection target. Selection target is the sum of all recipient amounts plus non input fees. So we need to remove change_fee from the m_target. It's safe because change target is always greater than the change fee, so we can always cover fees if change output is created.
This commit is contained in:
parent
c8cf08ea74
commit
06f558e4e2
@ -166,6 +166,12 @@ std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& ut
|
||||
{
|
||||
SelectionResult result(target_value, SelectionAlgorithm::SRD);
|
||||
|
||||
// Include change for SRD as we want to avoid making really small change if the selection just
|
||||
// barely meets the target. Just use the lower bound change target instead of the randomly
|
||||
// generated one, since SRD will result in a random change amount anyway; avoid making the
|
||||
// target needlessly large.
|
||||
target_value += CHANGE_LOWER;
|
||||
|
||||
std::vector<size_t> indexes;
|
||||
indexes.resize(utxo_pool.size());
|
||||
std::iota(indexes.begin(), indexes.end(), 0);
|
||||
|
@ -489,31 +489,19 @@ std::optional<SelectionResult> ChooseSelectionResult(const CWallet& wallet, cons
|
||||
// Vector of results. We will choose the best one based on waste.
|
||||
std::vector<SelectionResult> results;
|
||||
|
||||
// Note that unlike KnapsackSolver, we do not include the fee for creating a change output as BnB will not create a change output.
|
||||
std::vector<OutputGroup> positive_groups = GroupOutputs(wallet, available_coins, coin_selection_params, eligibility_filter, true /* positive_only */);
|
||||
std::vector<OutputGroup> positive_groups = GroupOutputs(wallet, available_coins, coin_selection_params, eligibility_filter, /*positive_only=*/true);
|
||||
if (auto bnb_result{SelectCoinsBnB(positive_groups, nTargetValue, coin_selection_params.m_cost_of_change)}) {
|
||||
results.push_back(*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.
|
||||
std::vector<OutputGroup> all_groups = GroupOutputs(wallet, available_coins, coin_selection_params, eligibility_filter, false /* positive_only */);
|
||||
CAmount target_with_change = nTargetValue;
|
||||
// While nTargetValue includes the transaction fees for non-input things, it does not include the fee for creating a change output.
|
||||
// So we need to include that for KnapsackSolver and SRD as well, as we are expecting to create a change output.
|
||||
if (!coin_selection_params.m_subtract_fee_outputs) {
|
||||
target_with_change += coin_selection_params.m_change_fee;
|
||||
}
|
||||
if (auto knapsack_result{KnapsackSolver(all_groups, target_with_change, coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
|
||||
std::vector<OutputGroup> all_groups = GroupOutputs(wallet, available_coins, coin_selection_params, eligibility_filter, /*positive_only=*/false);
|
||||
if (auto knapsack_result{KnapsackSolver(all_groups, nTargetValue, coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
|
||||
knapsack_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
|
||||
results.push_back(*knapsack_result);
|
||||
}
|
||||
|
||||
// Include change for SRD as we want to avoid making really small change if the selection just
|
||||
// barely meets the target. Just use the lower bound change target instead of the randomly
|
||||
// generated one, since SRD will result in a random change amount anyway; avoid making the
|
||||
// target needlessly large.
|
||||
const CAmount srd_target = target_with_change + CHANGE_LOWER;
|
||||
if (auto srd_result{SelectCoinsSRD(positive_groups, srd_target, coin_selection_params.rng_fast)}) {
|
||||
if (auto srd_result{SelectCoinsSRD(positive_groups, nTargetValue, coin_selection_params.rng_fast)}) {
|
||||
srd_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
|
||||
results.push_back(*srd_result);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user