aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/spend.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/spend.cpp')
-rw-r--r--src/wallet/spend.cpp14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index 583c021b8f..21007f5a92 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -393,10 +393,13 @@ std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAm
// 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, 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 as well, as we are expecting to create a change output.
- if (auto knapsack_result{KnapsackSolver(all_groups, nTargetValue + coin_selection_params.m_change_fee,
- coin_selection_params.m_min_change_target, coin_selection_params.rng_fast)}) {
+ // 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)}) {
knapsack_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
results.push_back(*knapsack_result);
}
@@ -405,7 +408,7 @@ std::optional<SelectionResult> AttemptSelection(const CWallet& wallet, const CAm
// 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 = nTargetValue + coin_selection_params.m_change_fee + CHANGE_LOWER;
+ const CAmount srd_target = target_with_change + CHANGE_LOWER;
if (auto srd_result{SelectCoinsSRD(positive_groups, srd_target, coin_selection_params.rng_fast)}) {
srd_result->ComputeAndSetWaste(coin_selection_params.m_cost_of_change);
results.push_back(*srd_result);
@@ -756,7 +759,8 @@ static std::optional<CreatedTransactionResult> CreateTransactionInternal(
// vouts to the payees
if (!coin_selection_params.m_subtract_fee_outputs) {
- coin_selection_params.tx_noinputs_size = 11; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 output count, 1 witness overhead (dummy, flag, stack size)
+ coin_selection_params.tx_noinputs_size = 10; // Static vsize overhead + outputs vsize. 4 nVersion, 4 nLocktime, 1 input count, 1 witness overhead (dummy, flag, stack size)
+ coin_selection_params.tx_noinputs_size += GetSizeOfCompactSize(vecSend.size()); // bytes for output count
}
for (const auto& recipient : vecSend)
{