Line data Source code
1 : // Copyright (c) 2017-2018 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 : #ifndef BITCOIN_WALLET_COINSELECTION_H
6 : #define BITCOIN_WALLET_COINSELECTION_H
7 :
8 : #include <amount.h>
9 : #include <primitives/transaction.h>
10 : #include <random.h>
11 :
12 : class CFeeRate;
13 :
14 : //! target minimum change amount
15 : static constexpr CAmount MIN_CHANGE{COIN / 100};
16 : //! final minimum change amount after paying for fees
17 : static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
18 :
19 32964406 : class CInputCoin {
20 : public:
21 2404532 : CInputCoin(const CTransactionRef& tx, unsigned int i)
22 1202266 : {
23 1202266 : if (!tx)
24 0 : throw std::invalid_argument("tx should not be null");
25 1202266 : if (i >= tx->vout.size())
26 0 : throw std::out_of_range("The output index is out of range");
27 :
28 1202266 : outpoint = COutPoint(tx->GetHash(), i);
29 1202266 : txout = tx->vout[i];
30 1202266 : effective_value = txout.nValue;
31 2404532 : }
32 :
33 1152162 : CInputCoin(const CTransactionRef& tx, unsigned int i, int input_bytes) : CInputCoin(tx, i)
34 : {
35 1152162 : m_input_bytes = input_bytes;
36 1152162 : }
37 :
38 : COutPoint outpoint;
39 : CTxOut txout;
40 : CAmount effective_value;
41 1202266 : CAmount m_fee{0};
42 1202266 : CAmount m_long_term_fee{0};
43 :
44 : /** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */
45 1202266 : int m_input_bytes{-1};
46 :
47 1446234 : bool operator<(const CInputCoin& rhs) const {
48 1446234 : return outpoint < rhs.outpoint;
49 : }
50 :
51 : bool operator!=(const CInputCoin& rhs) const {
52 : return outpoint != rhs.outpoint;
53 : }
54 :
55 1169 : bool operator==(const CInputCoin& rhs) const {
56 1169 : return outpoint == rhs.outpoint;
57 : }
58 : };
59 :
60 : struct CoinEligibilityFilter
61 : {
62 : const int conf_mine;
63 : const int conf_theirs;
64 : const uint64_t max_ancestors;
65 : const uint64_t max_descendants;
66 :
67 25816 : CoinEligibilityFilter(int conf_mine, int conf_theirs, uint64_t max_ancestors) : conf_mine(conf_mine), conf_theirs(conf_theirs), max_ancestors(max_ancestors), max_descendants(max_ancestors) {}
68 14338 : CoinEligibilityFilter(int conf_mine, int conf_theirs, uint64_t max_ancestors, uint64_t max_descendants) : conf_mine(conf_mine), conf_theirs(conf_theirs), max_ancestors(max_ancestors), max_descendants(max_descendants) {}
69 : };
70 :
71 37255348 : struct OutputGroup
72 : {
73 : std::vector<CInputCoin> m_outputs;
74 978053 : bool m_from_me{true};
75 978053 : CAmount m_value{0};
76 978053 : int m_depth{999};
77 978053 : size_t m_ancestors{0};
78 978053 : size_t m_descendants{0};
79 978053 : CAmount effective_value{0};
80 978053 : CAmount fee{0};
81 978053 : CAmount long_term_fee{0};
82 :
83 1956106 : OutputGroup() {}
84 : OutputGroup(std::vector<CInputCoin>&& outputs, bool from_me, CAmount value, int depth, size_t ancestors, size_t descendants)
85 : : m_outputs(std::move(outputs))
86 : , m_from_me(from_me)
87 : , m_value(value)
88 : , m_depth(depth)
89 : , m_ancestors(ancestors)
90 : , m_descendants(descendants)
91 : {}
92 933801 : OutputGroup(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants) : OutputGroup() {
93 933801 : Insert(output, depth, from_me, ancestors, descendants);
94 933801 : }
95 : void Insert(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants);
96 : std::vector<CInputCoin>::iterator Discard(const CInputCoin& output);
97 : bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const;
98 :
99 : //! Update the OutputGroup's fee, long_term_fee, and effective_value based on the given feerates
100 : void SetFees(const CFeeRate effective_feerate, const CFeeRate long_term_feerate);
101 : OutputGroup GetPositiveOnlyGroup();
102 : };
103 :
104 : 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);
105 :
106 : // Original coin selection algorithm as a fallback
107 : bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet);
108 :
109 : #endif // BITCOIN_WALLET_COINSELECTION_H
|