Skip to content

Commit aeab1b4

Browse files
committed
Merge bitcoin/bitcoin#25507: wallet: don't add change fee to target if subtracting fees from output
140d942 wallet: don't add change fee to target if subtracting fees from output (S3RK) Pull request description: Change fee is payed by the recipient, so we don't need to add it to our target for coin selection. ACKs for top commit: achow101: ACK 140d942 ishaanam: ACK 140d942 furszy: Code review ACK 140d942 Tree-SHA512: b5efd0264c47ecee9204a3fd039bad24c69f9e614c6e1d9bb240ee5be6356b175aa074f3be123e6cfb8becd4d7bd1028eebe18801662cc69d19413d8d5a9dd5c
2 parents 691a087 + 140d942 commit aeab1b4

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

src/wallet/spend.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,10 +397,13 @@ std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAm
397397

398398
// 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.
399399
std::vector<OutputGroup> all_groups = GroupOutputs(wallet, coins, coin_selection_params, eligibility_filter, false /* positive_only */);
400+
CAmount target_with_change = nTargetValue;
400401
// While nTargetValue includes the transaction fees for non-input things, it does not include the fee for creating a change output.
401-
// So we need to include that for KnapsackSolver as well, as we are expecting to create a change output.
402-
if (auto knapsack_result{KnapsackSolver(all_groups, nTargetValue + coin_selection_params.m_change_fee,
403-
coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
402+
// So we need to include that for KnapsackSolver and SRD as well, as we are expecting to create a change output.
403+
if (!coin_selection_params.m_subtract_fee_outputs) {
404+
target_with_change += coin_selection_params.m_change_fee;
405+
}
406+
if (auto knapsack_result{KnapsackSolver(all_groups, target_with_change, coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
404407
knapsack_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
405408
results.push_back(*knapsack_result);
406409
}
@@ -409,7 +412,7 @@ std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAm
409412
// barely meets the target. Just use the lower bound change target instead of the randomly
410413
// generated one, since SRD will result in a random change amount anyway; avoid making the
411414
// target needlessly large.
412-
const CAmount srd_target = nTargetValue + coin_selection_params.m_change_fee + CHANGE_LOWER;
415+
const CAmount srd_target = target_with_change + CHANGE_LOWER;
413416
if (auto srd_result{SelectCoinsSRD(positive_groups, srd_target, coin_selection_params.rng_fast)}) {
414417
srd_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
415418
results.push_back(*srd_result);

0 commit comments

Comments
 (0)