aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorS3RK <1466284+S3RK@users.noreply.github.com>2022-07-06 09:00:57 +0200
committerS3RK <1466284+S3RK@users.noreply.github.com>2022-08-15 09:35:13 +0200
commit72cad28da05cfce9e4950f2dc5a709da41d251f4 (patch)
tree7e105850c752c95299e4105b79b021966672428e
parente3210a722542a9cb5f7e4be72470dbe488c281fd (diff)
downloadbitcoin-72cad28da05cfce9e4950f2dc5a709da41d251f4.tar.xz
wallet: calculate and store min_viable_change
-rw-r--r--src/wallet/coinselection.h4
-rw-r--r--src/wallet/spend.cpp7
2 files changed, 11 insertions, 0 deletions
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index fa24fec6e9..d1038a117a 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -123,6 +123,10 @@ struct CoinSelectionParams {
/** Mininmum change to target in Knapsack solver: select coins to cover the payment and
* at least this value of change. */
CAmount m_min_change_target{0};
+ /** Minimum amount for creating a change output.
+ * If change budget is smaller than min_change then we forgo creation of change output.
+ */
+ CAmount min_viable_change{0};
/** Cost of creating the change output. */
CAmount m_change_fee{0};
/** Cost of creating the change output + cost of spending the change output in the future. */
diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp
index cbb03dc177..d1fa3dbcb6 100644
--- a/src/wallet/spend.cpp
+++ b/src/wallet/spend.cpp
@@ -855,6 +855,13 @@ static util::Result<CreatedTransactionResult> CreateTransactionInternal(
coin_selection_params.m_min_change_target = GenerateChangeTarget(std::floor(recipients_sum / vecSend.size()), coin_selection_params.m_change_fee, rng_fast);
+ // The smallest change amount should be:
+ // 1. at least equal to dust threshold
+ // 2. at least 1 sat greater than fees to spend it at m_discard_feerate
+ const auto dust = GetDustThreshold(change_prototype_txout, coin_selection_params.m_discard_feerate);
+ const auto change_spend_fee = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size);
+ coin_selection_params.min_viable_change = std::max(change_spend_fee + 1, dust);
+
// vouts to the payees
if (!coin_selection_params.m_subtract_fee_outputs) {
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)