aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/coinselection.h
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2021-04-23 15:14:41 -0400
committerAndrew Chow <achow101-github@achow101.com>2021-05-19 15:35:11 -0400
commit51a3ac242c92e69b59df26f8f9e287b31e5c3b0f (patch)
treebcdd8ea4f69744deab78032d16d448971b587411 /src/wallet/coinselection.h
parent6d6d2784759878ef0c4ac128d12aac68add1edca (diff)
downloadbitcoin-51a3ac242c92e69b59df26f8f9e287b31e5c3b0f.tar.xz
Have OutputGroup determine the value to use
Instead of hijacking the effective_feerate to use the correct value during coin selection, have OutputGroup be aware of whether we are subtracting the fee from the outputs and provide the correct value to use for selection. To do this, OutputGroup now takes CoinSelectionParams and has a new function GetSelectionAmount().
Diffstat (limited to 'src/wallet/coinselection.h')
-rw-r--r--src/wallet/coinselection.h52
1 files changed, 49 insertions, 3 deletions
diff --git a/src/wallet/coinselection.h b/src/wallet/coinselection.h
index af23178d04..7a3fb82139 100644
--- a/src/wallet/coinselection.h
+++ b/src/wallet/coinselection.h
@@ -57,6 +57,47 @@ public:
}
};
+/** Parameters for one iteration of Coin Selection. */
+struct CoinSelectionParams
+{
+ /** Size of a change output in bytes, determined by the output type. */
+ size_t change_output_size = 0;
+ /** Size of the input to spend a change output in virtual bytes. */
+ size_t change_spend_size = 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. */
+ CAmount m_cost_of_change{0};
+ /** The targeted feerate of the transaction being built. */
+ CFeeRate m_effective_feerate;
+ /** The feerate estimate used to estimate an upper bound on what should be sufficient to spend
+ * the change output sometime in the future. */
+ CFeeRate m_long_term_feerate;
+ /** If the cost to spend a change output at the discard feerate exceeds its value, drop it to fees. */
+ CFeeRate m_discard_feerate;
+ /** Size of the transaction before coin selection, consisting of the header and recipient
+ * output(s), excluding the inputs and change output(s). */
+ size_t tx_noinputs_size = 0;
+ /** Indicate that we are subtracting the fee from outputs */
+ bool m_subtract_fee_outputs = false;
+ /** When true, always spend all (up to OUTPUT_GROUP_MAX_ENTRIES) or none of the outputs
+ * associated with the same address. This helps reduce privacy leaks resulting from address
+ * reuse. Dust outputs are not eligible to be added to output groups and thus not considered. */
+ bool m_avoid_partial_spends = false;
+
+ CoinSelectionParams(size_t change_output_size, size_t change_spend_size, CFeeRate effective_feerate,
+ CFeeRate long_term_feerate, CFeeRate discard_feerate, size_t tx_noinputs_size, bool avoid_partial) :
+ change_output_size(change_output_size),
+ change_spend_size(change_spend_size),
+ m_effective_feerate(effective_feerate),
+ m_long_term_feerate(long_term_feerate),
+ m_discard_feerate(discard_feerate),
+ tx_noinputs_size(tx_noinputs_size),
+ m_avoid_partial_spends(avoid_partial)
+ {}
+ CoinSelectionParams() {}
+};
+
/** Parameters for filtering which OutputGroups we may use in coin selection.
* We start by being very selective and requiring multiple confirmations and
* then get more permissive if we cannot fund the transaction. */
@@ -109,15 +150,20 @@ struct OutputGroup
* a lower feerate). Calculated using long term fee estimate. This is used to decide whether
* it could be economical to create a change output. */
CFeeRate m_long_term_feerate{0};
+ /** Indicate that we are subtracting the fee from outputs.
+ * When true, the value that is used for coin selection is the UTXO's real value rather than effective value */
+ bool m_subtract_fee_outputs{false};
OutputGroup() {}
- OutputGroup(const CFeeRate& effective_feerate, const CFeeRate& long_term_feerate) :
- m_effective_feerate(effective_feerate),
- m_long_term_feerate(long_term_feerate)
+ OutputGroup(const CoinSelectionParams& params) :
+ m_effective_feerate(params.m_effective_feerate),
+ m_long_term_feerate(params.m_long_term_feerate),
+ m_subtract_fee_outputs(params.m_subtract_fee_outputs)
{}
void Insert(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants, bool positive_only);
bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const;
+ CAmount GetSelectionAmount() const;
};
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret);