1616struct {
1717 bool operator ()(const OutputGroup& a, const OutputGroup& b) const
1818 {
19- return a.effective_value > b.effective_value ;
19+ return a.GetSelectionAmount () > b.GetSelectionAmount () ;
2020 }
2121} descending;
2222
@@ -51,35 +51,32 @@ struct {
5151 * @param const std::vector<CInputCoin>& utxo_pool The set of UTXOs that we are choosing from.
5252 * These UTXOs will be sorted in descending order by effective value and the CInputCoins'
5353 * values are their effective values.
54- * @param const CAmount& target_value This is the value that we want to select. It is the lower
54+ * @param const CAmount& selection_target This is the value that we want to select. It is the lower
5555 * bound of the range.
5656 * @param const CAmount& cost_of_change This is the cost of creating and spending a change output.
57- * This plus target_value is the upper bound of the range.
57+ * This plus selection_target is the upper bound of the range.
5858 * @param std::set<CInputCoin>& out_set -> This is an output parameter for the set of CInputCoins
5959 * that have been selected.
6060 * @param CAmount& value_ret -> This is an output parameter for the total value of the CInputCoins
6161 * that were selected.
62- * @param CAmount not_input_fees -> The fees that need to be paid for the outputs and fixed size
63- * overhead (version, locktime, marker and flag)
6462 */
6563
6664static const size_t TOTAL_TRIES = 100000 ;
6765
68- bool SelectCoinsBnB (std::vector<OutputGroup>& utxo_pool, const CAmount& target_value , const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret, CAmount not_input_fees )
66+ bool SelectCoinsBnB (std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target , const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret)
6967{
7068 out_set.clear ();
7169 CAmount curr_value = 0 ;
7270
7371 std::vector<bool > curr_selection; // select the utxo at this index
7472 curr_selection.reserve (utxo_pool.size ());
75- CAmount selection_target = not_input_fees + target_value;
7673
7774 // Calculate curr_available_value
7875 CAmount curr_available_value = 0 ;
7976 for (const OutputGroup& utxo : utxo_pool) {
8077 // Assert that this utxo is not negative. It should never be negative, effective value calculation should have removed it
81- assert (utxo.effective_value > 0 );
82- curr_available_value += utxo.effective_value ;
78+ assert (utxo.GetSelectionAmount () > 0 );
79+ curr_available_value += utxo.GetSelectionAmount () ;
8380 }
8481 if (curr_available_value < selection_target) {
8582 return false ;
@@ -123,7 +120,7 @@ bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& target_v
123120 // Walk backwards to find the last included UTXO that still needs to have its omission branch traversed.
124121 while (!curr_selection.empty () && !curr_selection.back ()) {
125122 curr_selection.pop_back ();
126- curr_available_value += utxo_pool.at (curr_selection.size ()).effective_value ;
123+ curr_available_value += utxo_pool.at (curr_selection.size ()).GetSelectionAmount () ;
127124 }
128125
129126 if (curr_selection.empty ()) { // We have walked back to the first utxo and no branch is untraversed. All solutions searched
@@ -133,24 +130,24 @@ bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& target_v
133130 // Output was included on previous iterations, try excluding now.
134131 curr_selection.back () = false ;
135132 OutputGroup& utxo = utxo_pool.at (curr_selection.size () - 1 );
136- curr_value -= utxo.effective_value ;
133+ curr_value -= utxo.GetSelectionAmount () ;
137134 curr_waste -= utxo.fee - utxo.long_term_fee ;
138135 } else { // Moving forwards, continuing down this branch
139136 OutputGroup& utxo = utxo_pool.at (curr_selection.size ());
140137
141138 // Remove this utxo from the curr_available_value utxo amount
142- curr_available_value -= utxo.effective_value ;
139+ curr_available_value -= utxo.GetSelectionAmount () ;
143140
144141 // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded. Since the ratio of fee to
145142 // long term fee is the same, we only need to check if one of those values match in order to know that the waste is the same.
146143 if (!curr_selection.empty () && !curr_selection.back () &&
147- utxo.effective_value == utxo_pool.at (curr_selection.size () - 1 ).effective_value &&
144+ utxo.GetSelectionAmount () == utxo_pool.at (curr_selection.size () - 1 ).GetSelectionAmount () &&
148145 utxo.fee == utxo_pool.at (curr_selection.size () - 1 ).fee ) {
149146 curr_selection.push_back (false );
150147 } else {
151148 // Inclusion branch first (Largest First Exploration)
152149 curr_selection.push_back (true );
153- curr_value += utxo.effective_value ;
150+ curr_value += utxo.GetSelectionAmount () ;
154151 curr_waste += utxo.fee - utxo.long_term_fee ;
155152 }
156153 }
@@ -283,14 +280,14 @@ bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& group
283280 if (tryDenom == 0 && CoinJoin::IsDenominatedAmount (group.m_value )) {
284281 continue ; // we don't want denom values on first run
285282 }
286- if (group.m_value == nTargetValue) {
283+ if (group.GetSelectionAmount () == nTargetValue) {
287284 util::insert (setCoinsRet, group.m_outputs );
288285 nValueRet += group.m_value ;
289286 return true ;
290- } else if (group.m_value < nTargetValue + nMinChange) {
287+ } else if (group.GetSelectionAmount () < nTargetValue + nMinChange) {
291288 applicable_groups.push_back (group);
292- nTotalLower += group.m_value ;
293- } else if (!lowest_larger || group.m_value < lowest_larger->m_value ) {
289+ nTotalLower += group.GetSelectionAmount () ;
290+ } else if (!lowest_larger || group.GetSelectionAmount () < lowest_larger->GetSelectionAmount () ) {
294291 lowest_larger = group;
295292 }
296293 }
@@ -336,7 +333,7 @@ bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& group
336333 // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
337334 // or the next bigger coin is closer), return the bigger coin
338335 if (lowest_larger &&
339- ((nBest != nTargetValue && nBest < nTargetValue + nMinChange) || lowest_larger->m_value <= nBest)) {
336+ ((nBest != nTargetValue && nBest < nTargetValue + nMinChange) || lowest_larger->GetSelectionAmount () <= nBest)) {
340337 util::insert (setCoinsRet, lowest_larger->m_outputs );
341338 nValueRet += lowest_larger->m_value ;
342339 } else {
@@ -400,3 +397,8 @@ bool OutputGroup::EligibleForSpending(const CoinEligibilityFilter& eligibility_f
400397 && m_ancestors <= eligibility_filter.max_ancestors
401398 && m_descendants <= eligibility_filter.max_descendants ;
402399}
400+
401+ CAmount OutputGroup::GetSelectionAmount () const
402+ {
403+ return m_subtract_fee_outputs ? m_value : effective_value;
404+ }
0 commit comments