Bitcoin Core  22.99.0
P2P Digital Currency
coinselection.cpp
Go to the documentation of this file.
1 // Copyright (c) 2017-2021 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <wallet/coinselection.h>
6 
7 #include <consensus/amount.h>
8 #include <policy/feerate.h>
9 #include <util/check.h>
10 #include <util/system.h>
11 #include <util/moneystr.h>
12 
13 #include <numeric>
14 #include <optional>
15 
16 namespace wallet {
17 // Descending order comparator
18 struct {
19  bool operator()(const OutputGroup& a, const OutputGroup& b) const
20  {
21  return a.GetSelectionAmount() > b.GetSelectionAmount();
22  }
23 } descending;
24 
25 /*
26  * This is the Branch and Bound Coin Selection algorithm designed by Murch. It searches for an input
27  * set that can pay for the spending target and does not exceed the spending target by more than the
28  * cost of creating and spending a change output. The algorithm uses a depth-first search on a binary
29  * tree. In the binary tree, each node corresponds to the inclusion or the omission of a UTXO. UTXOs
30  * are sorted by their effective values and the tree is explored deterministically per the inclusion
31  * branch first. At each node, the algorithm checks whether the selection is within the target range.
32  * While the selection has not reached the target range, more UTXOs are included. When a selection's
33  * value exceeds the target range, the complete subtree deriving from this selection can be omitted.
34  * At that point, the last included UTXO is deselected and the corresponding omission branch explored
35  * instead. The search ends after the complete tree has been searched or after a limited number of tries.
36  *
37  * The search continues to search for better solutions after one solution has been found. The best
38  * solution is chosen by minimizing the waste metric. The waste metric is defined as the cost to
39  * spend the current inputs at the given fee rate minus the long term expected cost to spend the
40  * inputs, plus the amount by which the selection exceeds the spending target:
41  *
42  * waste = selectionTotal - target + inputs × (currentFeeRate - longTermFeeRate)
43  *
44  * The algorithm uses two additional optimizations. A lookahead keeps track of the total value of
45  * the unexplored UTXOs. A subtree is not explored if the lookahead indicates that the target range
46  * cannot be reached. Further, it is unnecessary to test equivalent combinations. This allows us
47  * to skip testing the inclusion of UTXOs that match the effective value and waste of an omitted
48  * predecessor.
49  *
50  * The Branch and Bound algorithm is described in detail in Murch's Master Thesis:
51  * https://murch.one/wp-content/uploads/2016/11/erhardt2016coinselection.pdf
52  *
53  * @param const std::vector<CInputCoin>& utxo_pool The set of UTXOs that we are choosing from.
54  * These UTXOs will be sorted in descending order by effective value and the CInputCoins'
55  * values are their effective values.
56  * @param const CAmount& selection_target This is the value that we want to select. It is the lower
57  * bound of the range.
58  * @param const CAmount& cost_of_change This is the cost of creating and spending a change output.
59  * This plus selection_target is the upper bound of the range.
60  * @returns The result of this coin selection algorithm, or std::nullopt
61  */
62 
63 static const size_t TOTAL_TRIES = 100000;
64 
65 std::optional<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change)
66 {
67  SelectionResult result(selection_target);
68  CAmount curr_value = 0;
69 
70  std::vector<bool> curr_selection; // select the utxo at this index
71  curr_selection.reserve(utxo_pool.size());
72 
73  // Calculate curr_available_value
74  CAmount curr_available_value = 0;
75  for (const OutputGroup& utxo : utxo_pool) {
76  // Assert that this utxo is not negative. It should never be negative, effective value calculation should have removed it
77  assert(utxo.GetSelectionAmount() > 0);
78  curr_available_value += utxo.GetSelectionAmount();
79  }
80  if (curr_available_value < selection_target) {
81  return std::nullopt;
82  }
83 
84  // Sort the utxo_pool
85  std::sort(utxo_pool.begin(), utxo_pool.end(), descending);
86 
87  CAmount curr_waste = 0;
88  std::vector<bool> best_selection;
89  CAmount best_waste = MAX_MONEY;
90 
91  // Depth First search loop for choosing the UTXOs
92  for (size_t i = 0; i < TOTAL_TRIES; ++i) {
93  // Conditions for starting a backtrack
94  bool backtrack = false;
95  if (curr_value + curr_available_value < selection_target || // Cannot possibly reach target with the amount remaining in the curr_available_value.
96  curr_value > selection_target + cost_of_change || // Selected value is out of range, go back and try other branch
97  (curr_waste > best_waste && (utxo_pool.at(0).fee - utxo_pool.at(0).long_term_fee) > 0)) { // Don't select things which we know will be more wasteful if the waste is increasing
98  backtrack = true;
99  } else if (curr_value >= selection_target) { // Selected value is within range
100  curr_waste += (curr_value - selection_target); // This is the excess value which is added to the waste for the below comparison
101  // Adding another UTXO after this check could bring the waste down if the long term fee is higher than the current fee.
102  // However we are not going to explore that because this optimization for the waste is only done when we have hit our target
103  // value. Adding any more UTXOs will be just burning the UTXO; it will go entirely to fees. Thus we aren't going to
104  // explore any more UTXOs to avoid burning money like that.
105  if (curr_waste <= best_waste) {
106  best_selection = curr_selection;
107  best_selection.resize(utxo_pool.size());
108  best_waste = curr_waste;
109  if (best_waste == 0) {
110  break;
111  }
112  }
113  curr_waste -= (curr_value - selection_target); // Remove the excess value as we will be selecting different coins now
114  backtrack = true;
115  }
116 
117  // Backtracking, moving backwards
118  if (backtrack) {
119  // Walk backwards to find the last included UTXO that still needs to have its omission branch traversed.
120  while (!curr_selection.empty() && !curr_selection.back()) {
121  curr_selection.pop_back();
122  curr_available_value += utxo_pool.at(curr_selection.size()).GetSelectionAmount();
123  }
124 
125  if (curr_selection.empty()) { // We have walked back to the first utxo and no branch is untraversed. All solutions searched
126  break;
127  }
128 
129  // Output was included on previous iterations, try excluding now.
130  curr_selection.back() = false;
131  OutputGroup& utxo = utxo_pool.at(curr_selection.size() - 1);
132  curr_value -= utxo.GetSelectionAmount();
133  curr_waste -= utxo.fee - utxo.long_term_fee;
134  } else { // Moving forwards, continuing down this branch
135  OutputGroup& utxo = utxo_pool.at(curr_selection.size());
136 
137  // Remove this utxo from the curr_available_value utxo amount
138  curr_available_value -= utxo.GetSelectionAmount();
139 
140  // Avoid searching a branch if the previous UTXO has the same value and same waste and was excluded. Since the ratio of fee to
141  // 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.
142  if (!curr_selection.empty() && !curr_selection.back() &&
143  utxo.GetSelectionAmount() == utxo_pool.at(curr_selection.size() - 1).GetSelectionAmount() &&
144  utxo.fee == utxo_pool.at(curr_selection.size() - 1).fee) {
145  curr_selection.push_back(false);
146  } else {
147  // Inclusion branch first (Largest First Exploration)
148  curr_selection.push_back(true);
149  curr_value += utxo.GetSelectionAmount();
150  curr_waste += utxo.fee - utxo.long_term_fee;
151  }
152  }
153  }
154 
155  // Check for solution
156  if (best_selection.empty()) {
157  return std::nullopt;
158  }
159 
160  // Set output set
161  for (size_t i = 0; i < best_selection.size(); ++i) {
162  if (best_selection.at(i)) {
163  result.AddInput(utxo_pool.at(i));
164  }
165  }
166 
167  return result;
168 }
169 
170 std::optional<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value)
171 {
172  SelectionResult result(target_value);
173 
174  std::vector<size_t> indexes;
175  indexes.resize(utxo_pool.size());
176  std::iota(indexes.begin(), indexes.end(), 0);
177  Shuffle(indexes.begin(), indexes.end(), FastRandomContext());
178 
179  CAmount selected_eff_value = 0;
180  for (const size_t i : indexes) {
181  const OutputGroup& group = utxo_pool.at(i);
182  Assume(group.GetSelectionAmount() > 0);
183  selected_eff_value += group.GetSelectionAmount();
184  result.AddInput(group);
185  if (selected_eff_value >= target_value) {
186  return result;
187  }
188  }
189  return std::nullopt;
190 }
191 
192 static void ApproximateBestSubset(const std::vector<OutputGroup>& groups, const CAmount& nTotalLower, const CAmount& nTargetValue,
193  std::vector<char>& vfBest, CAmount& nBest, int iterations = 1000)
194 {
195  std::vector<char> vfIncluded;
196 
197  vfBest.assign(groups.size(), true);
198  nBest = nTotalLower;
199 
200  FastRandomContext insecure_rand;
201 
202  for (int nRep = 0; nRep < iterations && nBest != nTargetValue; nRep++)
203  {
204  vfIncluded.assign(groups.size(), false);
205  CAmount nTotal = 0;
206  bool fReachedTarget = false;
207  for (int nPass = 0; nPass < 2 && !fReachedTarget; nPass++)
208  {
209  for (unsigned int i = 0; i < groups.size(); i++)
210  {
211  //The solver here uses a randomized algorithm,
212  //the randomness serves no real security purpose but is just
213  //needed to prevent degenerate behavior and it is important
214  //that the rng is fast. We do not use a constant random sequence,
215  //because there may be some privacy improvement by making
216  //the selection random.
217  if (nPass == 0 ? insecure_rand.randbool() : !vfIncluded[i])
218  {
219  nTotal += groups[i].GetSelectionAmount();
220  vfIncluded[i] = true;
221  if (nTotal >= nTargetValue)
222  {
223  fReachedTarget = true;
224  if (nTotal < nBest)
225  {
226  nBest = nTotal;
227  vfBest = vfIncluded;
228  }
229  nTotal -= groups[i].GetSelectionAmount();
230  vfIncluded[i] = false;
231  }
232  }
233  }
234  }
235  }
236 }
237 
238 std::optional<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue)
239 {
240  SelectionResult result(nTargetValue);
241 
242  // List of values less than target
243  std::optional<OutputGroup> lowest_larger;
244  std::vector<OutputGroup> applicable_groups;
245  CAmount nTotalLower = 0;
246 
247  Shuffle(groups.begin(), groups.end(), FastRandomContext());
248 
249  for (const OutputGroup& group : groups) {
250  if (group.GetSelectionAmount() == nTargetValue) {
251  result.AddInput(group);
252  return result;
253  } else if (group.GetSelectionAmount() < nTargetValue + MIN_CHANGE) {
254  applicable_groups.push_back(group);
255  nTotalLower += group.GetSelectionAmount();
256  } else if (!lowest_larger || group.GetSelectionAmount() < lowest_larger->GetSelectionAmount()) {
257  lowest_larger = group;
258  }
259  }
260 
261  if (nTotalLower == nTargetValue) {
262  for (const auto& group : applicable_groups) {
263  result.AddInput(group);
264  }
265  return result;
266  }
267 
268  if (nTotalLower < nTargetValue) {
269  if (!lowest_larger) return std::nullopt;
270  result.AddInput(*lowest_larger);
271  return result;
272  }
273 
274  // Solve subset sum by stochastic approximation
275  std::sort(applicable_groups.begin(), applicable_groups.end(), descending);
276  std::vector<char> vfBest;
277  CAmount nBest;
278 
279  ApproximateBestSubset(applicable_groups, nTotalLower, nTargetValue, vfBest, nBest);
280  if (nBest != nTargetValue && nTotalLower >= nTargetValue + MIN_CHANGE) {
281  ApproximateBestSubset(applicable_groups, nTotalLower, nTargetValue + MIN_CHANGE, vfBest, nBest);
282  }
283 
284  // If we have a bigger coin and (either the stochastic approximation didn't find a good solution,
285  // or the next bigger coin is closer), return the bigger coin
286  if (lowest_larger &&
287  ((nBest != nTargetValue && nBest < nTargetValue + MIN_CHANGE) || lowest_larger->GetSelectionAmount() <= nBest)) {
288  result.AddInput(*lowest_larger);
289  } else {
290  for (unsigned int i = 0; i < applicable_groups.size(); i++) {
291  if (vfBest[i]) {
292  result.AddInput(applicable_groups[i]);
293  }
294  }
295 
297  std::string log_message{"Coin selection best subset: "};
298  for (unsigned int i = 0; i < applicable_groups.size(); i++) {
299  if (vfBest[i]) {
300  log_message += strprintf("%s ", FormatMoney(applicable_groups[i].m_value));
301  }
302  }
303  LogPrint(BCLog::SELECTCOINS, "%stotal %s\n", log_message, FormatMoney(nBest));
304  }
305  }
306 
307  return result;
308 }
309 
310 /******************************************************************************
311 
312  OutputGroup
313 
314  ******************************************************************************/
315 
316 void OutputGroup::Insert(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants, bool positive_only) {
317  // Compute the effective value first
318  const CAmount coin_fee = output.m_input_bytes < 0 ? 0 : m_effective_feerate.GetFee(output.m_input_bytes);
319  const CAmount ev = output.txout.nValue - coin_fee;
320 
321  // Filter for positive only here before adding the coin
322  if (positive_only && ev <= 0) return;
323 
324  m_outputs.push_back(output);
325  CInputCoin& coin = m_outputs.back();
326 
327  coin.m_fee = coin_fee;
328  fee += coin.m_fee;
329 
332 
333  coin.effective_value = ev;
335 
336  m_from_me &= from_me;
337  m_value += output.txout.nValue;
338  m_depth = std::min(m_depth, depth);
339  // ancestors here express the number of ancestors the new coin will end up having, which is
340  // the sum, rather than the max; this will overestimate in the cases where multiple inputs
341  // have common ancestors
342  m_ancestors += ancestors;
343  // descendants is the count as seen from the top ancestor, not the descendants as seen from the
344  // coin itself; thus, this value is counted as the max, not the sum
345  m_descendants = std::max(m_descendants, descendants);
346 }
347 
348 bool OutputGroup::EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const
349 {
350  return m_depth >= (m_from_me ? eligibility_filter.conf_mine : eligibility_filter.conf_theirs)
351  && m_ancestors <= eligibility_filter.max_ancestors
352  && m_descendants <= eligibility_filter.max_descendants;
353 }
354 
356 {
358 }
359 
360 CAmount GetSelectionWaste(const std::set<CInputCoin>& inputs, CAmount change_cost, CAmount target, bool use_effective_value)
361 {
362  // This function should not be called with empty inputs as that would mean the selection failed
363  assert(!inputs.empty());
364 
365  // Always consider the cost of spending an input now vs in the future.
366  CAmount waste = 0;
367  CAmount selected_effective_value = 0;
368  for (const CInputCoin& coin : inputs) {
369  waste += coin.m_fee - coin.m_long_term_fee;
370  selected_effective_value += use_effective_value ? coin.effective_value : coin.txout.nValue;
371  }
372 
373  if (change_cost) {
374  // Consider the cost of making change and spending it in the future
375  // If we aren't making change, the caller should've set change_cost to 0
376  assert(change_cost > 0);
377  waste += change_cost;
378  } else {
379  // When we are not making change (change_cost == 0), consider the excess we are throwing away to fees
380  assert(selected_effective_value >= target);
381  waste += selected_effective_value - target;
382  }
383 
384  return waste;
385 }
386 
388 {
390 }
391 
393 {
394  return *Assert(m_waste);
395 }
396 
398 {
399  return std::accumulate(m_selected_inputs.cbegin(), m_selected_inputs.cend(), CAmount{0}, [](CAmount sum, const auto& coin) { return sum + coin.txout.nValue; });
400 }
401 
403 {
404  m_selected_inputs.clear();
405  m_waste.reset();
406 }
407 
409 {
412 }
413 
414 const std::set<CInputCoin>& SelectionResult::GetInputSet() const
415 {
416  return m_selected_inputs;
417 }
418 
419 std::vector<CInputCoin> SelectionResult::GetShuffledInputVector() const
420 {
421  std::vector<CInputCoin> coins(m_selected_inputs.begin(), m_selected_inputs.end());
422  Shuffle(coins.begin(), coins.end(), FastRandomContext());
423  return coins;
424 }
425 
427 {
428  Assert(m_waste.has_value());
429  Assert(other.m_waste.has_value());
430  // As this operator is only used in std::min_element, we want the result that has more inputs when waste are equal.
431  return *m_waste < *other.m_waste || (*m_waste == *other.m_waste && m_selected_inputs.size() > other.m_selected_inputs.size());
432 }
433 } // namespace wallet
wallet::SelectCoinsSRD
std::optional< SelectionResult > SelectCoinsSRD(const std::vector< OutputGroup > &utxo_pool, CAmount target_value)
Select coins by Single Random Draw.
Definition: coinselection.cpp:170
wallet::OutputGroup::m_subtract_fee_outputs
bool m_subtract_fee_outputs
Indicate that we are subtracting the fee from outputs.
Definition: coinselection.h:170
feerate.h
wallet::OutputGroup::m_outputs
std::vector< CInputCoin > m_outputs
The list of UTXOs contained in this output group.
Definition: coinselection.h:142
assert
assert(!tx.IsCoinBase())
check.h
wallet::SelectionResult::GetSelectedValue
CAmount GetSelectedValue() const
Get the sum of the input values.
Definition: coinselection.cpp:397
moneystr.h
wallet::SelectionResult::Clear
void Clear()
Definition: coinselection.cpp:402
FastRandomContext::randbool
bool randbool() noexcept
Generate a random boolean.
Definition: random.h:223
wallet::OutputGroup::long_term_fee
CAmount long_term_fee
The fee to spend these UTXOs at the long term feerate.
Definition: coinselection.h:163
wallet::OutputGroup::Insert
void Insert(const CInputCoin &output, int depth, bool from_me, size_t ancestors, size_t descendants, bool positive_only)
Definition: coinselection.cpp:316
wallet::GetSelectionWaste
CAmount GetSelectionWaste(const std::set< CInputCoin > &inputs, CAmount change_cost, CAmount target, bool use_effective_value)
Compute the waste for this result given the cost of change and the opportunity cost of spending these...
Definition: coinselection.cpp:360
wallet::CInputCoin::txout
CTxOut txout
Definition: coinselection.h:54
wallet
Definition: node.h:38
wallet::OutputGroup::m_long_term_feerate
CFeeRate m_long_term_feerate
The feerate for spending a created change output eventually (i.e.
Definition: coinselection.h:167
wallet::OutputGroup::m_descendants
size_t m_descendants
The maximum count of descendants of a single UTXO in this output group.
Definition: coinselection.h:155
wallet::OutputGroup::effective_value
CAmount effective_value
The value of the UTXOs after deducting the cost of spending them at the effective feerate.
Definition: coinselection.h:157
wallet::SelectionResult::GetInputSet
const std::set< CInputCoin > & GetInputSet() const
Get m_selected_inputs.
Definition: coinselection.cpp:414
wallet::OutputGroup::GetSelectionAmount
CAmount GetSelectionAmount() const
Definition: coinselection.cpp:355
wallet::SelectionResult::GetWaste
CAmount GetWaste() const
Definition: coinselection.cpp:392
wallet::KnapsackSolver
std::optional< SelectionResult > KnapsackSolver(std::vector< OutputGroup > &groups, const CAmount &nTargetValue)
Definition: coinselection.cpp:238
Assert
#define Assert(val)
Identity function.
Definition: check.h:57
wallet::CoinEligibilityFilter::max_ancestors
const uint64_t max_ancestors
Maximum number of unconfirmed ancestors aggregated across all UTXOs in an OutputGroup.
Definition: coinselection.h:127
CTxOut::nValue
CAmount nValue
Definition: transaction.h:151
Assume
#define Assume(val)
Assume is the identity function.
Definition: check.h:72
wallet::OutputGroup::m_effective_feerate
CFeeRate m_effective_feerate
The target feerate of the transaction we're trying to build.
Definition: coinselection.h:161
wallet::SelectionResult::m_use_effective
bool m_use_effective
Whether the input values for calculations should be the effective value (true) or normal value (false...
Definition: coinselection.h:211
coinselection.h
wallet::SelectionResult::ComputeAndSetWaste
void ComputeAndSetWaste(CAmount change_cost)
Calculates and stores the waste for this selection via GetSelectionWaste.
Definition: coinselection.cpp:387
wallet::descending
struct wallet::@16 descending
wallet::SelectionResult::m_target
const CAmount m_target
The target the algorithm selected for.
Definition: coinselection.h:209
wallet::OutputGroup::m_value
CAmount m_value
The total value of the UTXOs in sum.
Definition: coinselection.h:148
wallet::OutputGroup::m_from_me
bool m_from_me
Whether the UTXOs were sent by the wallet to itself.
Definition: coinselection.h:146
CAmount
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
wallet::OutputGroup::m_depth
int m_depth
The minimum number of confirmations the UTXOs in the group have.
Definition: coinselection.h:150
Shuffle
void Shuffle(I first, I last, R &&rng)
More efficient than using std::shuffle on a FastRandomContext.
Definition: random.h:243
wallet::CoinEligibilityFilter::max_descendants
const uint64_t max_descendants
Maximum number of descendants that a single UTXO in the OutputGroup may have.
Definition: coinselection.h:129
wallet::OutputGroup
A group of UTXOs paid to the same output script.
Definition: coinselection.h:139
LogPrint
#define LogPrint(category,...)
Definition: logging.h:192
wallet::CInputCoin
A UTXO under consideration for use in funding a new transaction.
Definition: coinselection.h:22
wallet::CInputCoin::m_input_bytes
int m_input_bytes
Pre-computed estimated size of this output as a fully-signed input in a transaction.
Definition: coinselection.h:60
wallet::SelectCoinsBnB
std::optional< SelectionResult > SelectCoinsBnB(std::vector< OutputGroup > &utxo_pool, const CAmount &selection_target, const CAmount &cost_of_change)
Definition: coinselection.cpp:65
wallet::OutputGroup::EligibleForSpending
bool EligibleForSpending(const CoinEligibilityFilter &eligibility_filter) const
Definition: coinselection.cpp:348
wallet::CInputCoin::m_long_term_fee
CAmount m_long_term_fee
Definition: coinselection.h:57
system.h
wallet::CInputCoin::effective_value
CAmount effective_value
Definition: coinselection.h:55
strprintf
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
LogAcceptCategory
static bool LogAcceptCategory(BCLog::LogFlags category)
Return true if log accepts specified category.
Definition: logging.h:161
wallet::MIN_CHANGE
static constexpr CAmount MIN_CHANGE
target minimum change amount
Definition: coinselection.h:17
wallet::ApproximateBestSubset
static void ApproximateBestSubset(const std::vector< OutputGroup > &groups, const CAmount &nTotalLower, const CAmount &nTargetValue, std::vector< char > &vfBest, CAmount &nBest, int iterations=1000)
Definition: coinselection.cpp:192
sum
volatile double sum
Definition: examples.cpp:10
wallet::SelectionResult::GetShuffledInputVector
std::vector< CInputCoin > GetShuffledInputVector() const
Get the vector of CInputCoins that will be used to fill in a CTransaction's vin.
Definition: coinselection.cpp:419
wallet::OutputGroup::m_ancestors
size_t m_ancestors
The aggregated count of unconfirmed ancestors of all UTXOs in this group.
Definition: coinselection.h:153
util::insert
void insert(Tdst &dst, const Tsrc &src)
Simplification of std insertion.
Definition: system.h:528
wallet::SelectionResult::AddInput
void AddInput(const OutputGroup &group)
Definition: coinselection.cpp:408
BCLog::SELECTCOINS
@ SELECTCOINS
Definition: logging.h:49
wallet::CoinEligibilityFilter::conf_mine
const int conf_mine
Minimum number of confirmations for outputs that we sent to ourselves.
Definition: coinselection.h:123
wallet::SelectionResult::m_waste
std::optional< CAmount > m_waste
The computed waste.
Definition: coinselection.h:213
MAX_MONEY
static constexpr CAmount MAX_MONEY
No amount larger than this (in satoshi) is valid.
Definition: amount.h:26
wallet::CInputCoin::m_fee
CAmount m_fee
Definition: coinselection.h:56
wallet::OutputGroup::fee
CAmount fee
The fee to spend these UTXOs at the effective feerate.
Definition: coinselection.h:159
CFeeRate::GetFee
CAmount GetFee(uint32_t num_bytes) const
Return the fee in satoshis for the given size in bytes.
Definition: feerate.cpp:23
wallet::CoinEligibilityFilter::conf_theirs
const int conf_theirs
Minimum number of confirmations for outputs received from a different wallet.
Definition: coinselection.h:125
wallet::SelectionResult
Definition: coinselection.h:203
amount.h
wallet::CoinEligibilityFilter
Parameters for filtering which OutputGroups we may use in coin selection.
Definition: coinselection.h:119
FastRandomContext
Fast randomness source.
Definition: random.h:131
wallet::SelectionResult::m_selected_inputs
std::set< CInputCoin > m_selected_inputs
Set of inputs selected by the algorithm to use in the transaction.
Definition: coinselection.h:207
wallet::TOTAL_TRIES
static const size_t TOTAL_TRIES
Definition: coinselection.cpp:63
FormatMoney
std::string FormatMoney(const CAmount n)
Money parsing/formatting utilities.
Definition: moneystr.cpp:15
wallet::SelectionResult::operator<
bool operator<(SelectionResult other) const
Definition: coinselection.cpp:426