Skip to content

Commit af5867c

Browse files
committed
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.
1 parent 1bf4a62 commit af5867c

File tree

1 file changed

+19
-13
lines changed

1 file changed

+19
-13
lines changed

src/wallet/wallet.cpp

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2399,24 +2399,30 @@ bool CWallet::SelectCoinsMinConf(const CAmount& nTargetValue, const CoinEligibil
23992399
setCoinsRet.clear();
24002400
nValueRet = 0;
24012401

2402-
if (coin_selection_params.use_bnb) {
2403-
// Get the feerate for effective value.
2404-
// When subtracting the fee from the outputs, we want the effective feerate to be 0
2405-
CFeeRate effective_feerate{0};
2406-
if (!coin_selection_params.m_subtract_fee_outputs) {
2407-
effective_feerate = coin_selection_params.m_effective_feerate;
2408-
}
2402+
// Calculate the fees for things that aren't inputs, excluding the change output
2403+
const CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
24092404

2410-
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 */);
2405+
// Get the feerate for effective value.
2406+
// When subtracting the fee from the outputs, we want the effective feerate to be 0
2407+
CFeeRate effective_feerate{0};
2408+
if (!coin_selection_params.m_subtract_fee_outputs) {
2409+
effective_feerate = coin_selection_params.m_effective_feerate;
2410+
}
24112411

2412-
// Calculate cost of change
2413-
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);
2412+
// Cost of change is the cost of creating the change output + cost of spending the change output in the future.
2413+
// For creating the change output now, we use the effective feerate.
2414+
// For spending the change output in the future, we use the discard feerate for now.
2415+
// So cost of change = (change output size * effective feerate) + (size of spending change output * discard feerate)
2416+
const CAmount change_fee = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.change_output_size);
2417+
const CAmount cost_of_change = coin_selection_params.m_discard_feerate.GetFee(coin_selection_params.change_spend_size) + change_fee;
24142418

2415-
// Calculate the fees for things that aren't inputs
2416-
CAmount not_input_fees = coin_selection_params.m_effective_feerate.GetFee(coin_selection_params.tx_noinputs_size);
2419+
if (coin_selection_params.use_bnb) {
2420+
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 */);
24172421
bnb_used = true;
2418-
return SelectCoinsBnB(groups, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
2422+
return SelectCoinsBnB(positive_groups, nTargetValue, cost_of_change, setCoinsRet, nValueRet, not_input_fees);
24192423
} else {
2424+
// 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.
2425+
// 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.
24202426
std::vector<OutputGroup> groups = GroupOutputs(coins, !coin_selection_params.m_avoid_partial_spends, CFeeRate(0), CFeeRate(0), eligibility_filter, false /* positive_only */);
24212427

24222428
bnb_used = false;

0 commit comments

Comments
 (0)