@@ -71,11 +71,13 @@ struct {
71
71
72
72
static const size_t TOTAL_TRIES = 100000 ;
73
73
74
- util::Result<SelectionResult> SelectCoinsBnB (std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change)
74
+ util::Result<SelectionResult> SelectCoinsBnB (std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change,
75
+ int max_weight)
75
76
{
76
77
SelectionResult result (selection_target, SelectionAlgorithm::BNB);
77
78
CAmount curr_value = 0 ;
78
79
std::vector<size_t > curr_selection; // selected utxo indexes
80
+ int curr_selection_weight = 0 ; // sum of selected utxo weight
79
81
80
82
// Calculate curr_available_value
81
83
CAmount curr_available_value = 0 ;
@@ -97,6 +99,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
97
99
CAmount best_waste = MAX_MONEY;
98
100
99
101
bool is_feerate_high = utxo_pool.at (0 ).fee > utxo_pool.at (0 ).long_term_fee ;
102
+ bool max_tx_weight_exceeded = false ;
100
103
101
104
// Depth First search loop for choosing the UTXOs
102
105
for (size_t curr_try = 0 , utxo_pool_index = 0 ; curr_try < TOTAL_TRIES; ++curr_try, ++utxo_pool_index) {
@@ -106,6 +109,9 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
106
109
curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch
107
110
(curr_waste > best_waste && is_feerate_high)) { // Don't select things which we know will be more wasteful if the waste is increasing
108
111
backtrack = true ;
112
+ } else if (curr_selection_weight > max_weight) { // Exceeding weight for standard tx, cannot find more solutions by adding more inputs
113
+ max_tx_weight_exceeded = true ; // at least one selection attempt exceeded the max weight
114
+ backtrack = true ;
109
115
} else if (curr_value >= selection_target) { // Selected value is within range
110
116
curr_waste += (curr_value - selection_target); // This is the excess value which is added to the waste for the below comparison
111
117
// Adding another UTXO after this check could bring the waste down if the long term fee is higher than the current fee.
@@ -135,6 +141,7 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
135
141
OutputGroup& utxo = utxo_pool.at (utxo_pool_index);
136
142
curr_value -= utxo.GetSelectionAmount ();
137
143
curr_waste -= utxo.fee - utxo.long_term_fee ;
144
+ curr_selection_weight -= utxo.m_weight ;
138
145
curr_selection.pop_back ();
139
146
} else { // Moving forwards, continuing down this branch
140
147
OutputGroup& utxo = utxo_pool.at (utxo_pool_index);
@@ -154,13 +161,14 @@ util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool
154
161
curr_selection.push_back (utxo_pool_index);
155
162
curr_value += utxo.GetSelectionAmount ();
156
163
curr_waste += utxo.fee - utxo.long_term_fee ;
164
+ curr_selection_weight += utxo.m_weight ;
157
165
}
158
166
}
159
167
}
160
168
161
169
// Check for solution
162
170
if (best_selection.empty ()) {
163
- return util::Error ();
171
+ return max_tx_weight_exceeded ? ErrorMaxWeightExceeded () : util::Error ();
164
172
}
165
173
166
174
// Set output set
0 commit comments