aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/spend.cpp
diff options
context:
space:
mode:
authorS3RK <1466284+S3RK@users.noreply.github.com>2022-07-06 08:51:22 +0200
committerS3RK <1466284+S3RK@users.noreply.github.com>2022-08-15 09:34:38 +0200
commit06f558e4e2164d1916f258c731efe4586728a23b (patch)
treeb6331a743c0454d1120293f6ade842503714609e /src/wallet/spend.cpp
parentc8cf08ea743e430c2bf3fe46439594257b0937e5 (diff)
downloadbitcoin-06f558e4e2164d1916f258c731efe4586728a23b.tar.xz
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.
Diffstat (limited to 'src/wallet/spend.cpp')
-rw-r--r--src/wallet/spend.cpp20
1 files changed, 4 insertions, 16 deletions
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index 9babb5e04e..aed6dc89d2 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -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);
}