aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authorAndrew Chow <achow101-github@achow101.com>2021-05-06 13:52:28 -0400
committerAndrew Chow <achow101-github@achow101.com>2021-05-13 16:40:56 -0400
commitaf5867c89688b06173b295b7c32a42845ea455da (patch)
treeaf3c3308cae9c28c2138d0aa2343e3c857116f20 /src/wallet
parent1bf4a62cb61bd4b91d9cd4e379fea2b914786342 (diff)
Move some calculations to common code in SelectCoinsMinConf
To prepare for KnapsackSolver to use effective values, these calculations are moved out of the BnB if block to allow for them to be shared with KnapsackSolver in the future.
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/wallet.cpp32
1 files changed, 19 insertions, 13 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index 35805bc4c9..b6dc867dcb 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -2399,24 +2399,30 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
setCoinsRet.clear();
nValueRet = 0;
- if (coin_selection_params.use_bnb) {
- // Get the feerate for effective value.
- // When subtracting the fee from the outputs, we want the effective feerate to be 0
- CFeeRate effective_feerate{0};
- if (!coin_selection_params.m_subtract_fee_outputs) {
- effective_feerate = coin_selection_params.m_effective_feerate;
- }
+ // Calculate the fees for things that aren't inputs, excluding the change output
+ const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
- std::vector<OutputGroup> groups = GroupOutputs(coins, !coin_selection_params.m_avoid_partial_spends, effective_feerate, coin_selection_params.m_long_term_feerate, eligibility_filter, true /* positive_only */);
+ // Get the feerate for effective value.
+ // When subtracting the fee from the outputs, we want the effective feerate to be 0
+ CFeeRate effective_feerate{0};
+ if (!coin_selection_params.m_subtract_fee_outputs) {
+ effective_feerate = coin_selection_params.m_effective_feerate;
+ }
- // Calculate cost of change
- CAmount cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
+ // Cost of change is the cost of creating the change output + cost of spending the change output in the future.
+ // For creating the change output now, we use the effective feerate.
+ // For spending the change output in the future, we use the discard feerate for now.
+ // So cost of change = (change output size * effective feerate) + (size of spending change output * discard feerate)
+ const CAmount change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
+ const CAmount cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + change_fee;
- // Calculate the fees for things that aren't inputs
- CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
+ if (coin_selection_params.use_bnb) {
+ std::vector<OutputGroup> positive_groups = GroupOutputs(coins, !coin_selection_params.m_avoid_partial_spends, effective_feerate, coin_selection_params.m_long_term_feerate, eligibility_filter, true /* positive_only */);
bnb_used = true;
- return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
+ return SelectCoinsBnB(positive_groups, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
} else {
+ // 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.
+ // The knapsack solver currently does not use effective values, so we give GroupOutputs feerates of 0 so it sets the effective values to be the same as the real value.
std::vector<OutputGroup> groups = GroupOutputs(coins, !coin_selection_params.m_avoid_partial_spends, CFeeRate(0), CFeeRate(0), eligibility_filter, false /* positive_only */);
bnb_used = false;