/Users/eugenesiegel/btc/bitcoin/src/wallet/coinselection.h
| Line | Count | Source (jump to first uncovered line) | 
| 1 |  | // Copyright (c) 2017-2022 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 <consensus/amount.h> | 
| 9 |  | #include <consensus/consensus.h> | 
| 10 |  | #include <outputtype.h> | 
| 11 |  | #include <policy/feerate.h> | 
| 12 |  | #include <primitives/transaction.h> | 
| 13 |  | #include <random.h> | 
| 14 |  | #include <util/check.h> | 
| 15 |  | #include <util/insert.h> | 
| 16 |  | #include <util/result.h> | 
| 17 |  |  | 
| 18 |  | #include <optional> | 
| 19 |  |  | 
| 20 |  |  | 
| 21 |  | namespace wallet { | 
| 22 |  | //! lower bound for randomly-chosen target change amount | 
| 23 |  | static constexpr CAmount CHANGE_LOWER{50000}; | 
| 24 |  | //! upper bound for randomly-chosen target change amount | 
| 25 |  | static constexpr CAmount CHANGE_UPPER{1000000}; | 
| 26 |  |  | 
| 27 |  | /** A UTXO under consideration for use in funding a new transaction. */ | 
| 28 |  | struct COutput { | 
| 29 |  | private: | 
| 30 |  |     /** The output's value minus fees required to spend it and bump its unconfirmed ancestors to the target feerate. */ | 
| 31 |  |     std::optional<CAmount> effective_value; | 
| 32 |  |  | 
| 33 |  |     /** The fee required to spend this output at the transaction's target feerate and to bump its unconfirmed ancestors to the target feerate. */ | 
| 34 |  |     std::optional<CAmount> fee; | 
| 35 |  |  | 
| 36 |  | public: | 
| 37 |  |     /** The outpoint identifying this UTXO */ | 
| 38 |  |     COutPoint outpoint; | 
| 39 |  |  | 
| 40 |  |     /** The output itself */ | 
| 41 |  |     CTxOut txout; | 
| 42 |  |  | 
| 43 |  |     /** | 
| 44 |  |      * Depth in block chain. | 
| 45 |  |      * If > 0: the tx is on chain and has this many confirmations. | 
| 46 |  |      * If = 0: the tx is waiting confirmation. | 
| 47 |  |      * If < 0: a conflicting tx is on chain and has this many confirmations. */ | 
| 48 |  |     int depth; | 
| 49 |  |  | 
| 50 |  |     /** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */ | 
| 51 |  |     int input_bytes; | 
| 52 |  |  | 
| 53 |  |     /** Whether we know how to spend this output, ignoring the lack of keys */ | 
| 54 |  |     bool solvable; | 
| 55 |  |  | 
| 56 |  |     /** | 
| 57 |  |      * Whether this output is considered safe to spend. Unconfirmed transactions | 
| 58 |  |      * from outside keys and unconfirmed replacement transactions are considered | 
| 59 |  |      * unsafe and will not be used to fund new spending transactions. | 
| 60 |  |      */ | 
| 61 |  |     bool safe; | 
| 62 |  |  | 
| 63 |  |     /** The time of the transaction containing this output as determined by CWalletTx::nTimeSmart */ | 
| 64 |  |     int64_t time; | 
| 65 |  |  | 
| 66 |  |     /** Whether the transaction containing this output is sent from the owning wallet */ | 
| 67 |  |     bool from_me; | 
| 68 |  |  | 
| 69 |  |     /** The fee required to spend this output at the consolidation feerate. */ | 
| 70 |  |     CAmount long_term_fee{0}; | 
| 71 |  |  | 
| 72 |  |     /** The fee necessary to bump this UTXO's ancestor transactions to the target feerate */ | 
| 73 |  |     CAmount ancestor_bump_fees{0}; | 
| 74 |  |  | 
| 75 |  |     COutput(const COutPoint& outpoint, const CTxOut& txout, int depth, int input_bytes, bool solvable, bool safe, int64_t time, bool from_me, const std::optional<CFeeRate> feerate = std::nullopt) | 
| 76 | 0 |         : outpoint{outpoint}, | 
| 77 | 0 |           txout{txout}, | 
| 78 | 0 |           depth{depth}, | 
| 79 | 0 |           input_bytes{input_bytes}, | 
| 80 | 0 |           solvable{solvable}, | 
| 81 | 0 |           safe{safe}, | 
| 82 | 0 |           time{time}, | 
| 83 | 0 |           from_me{from_me} | 
| 84 | 0 |     { | 
| 85 | 0 |         if (feerate) { | 
| 86 |  |             // base fee without considering potential unconfirmed ancestors | 
| 87 | 0 |             fee = input_bytes < 0 ? 0 : feerate.value().GetFee(input_bytes); | 
| 88 | 0 |             effective_value = txout.nValue - fee.value(); | 
| 89 | 0 |         } | 
| 90 | 0 |     } | 
| 91 |  |  | 
| 92 |  |     COutput(const COutPoint& outpoint, const CTxOut& txout, int depth, int input_bytes, bool solvable, bool safe, int64_t time, bool from_me, const CAmount fees) | 
| 93 |  |         : COutput(outpoint, txout, depth, input_bytes, solvable, safe, time, from_me) | 
| 94 | 0 |     { | 
| 95 | 0 |         // if input_bytes is unknown, then fees should be 0, if input_bytes is known, then the fees should be a positive integer or 0 (input_bytes known and fees = 0 only happens in the tests) | 
| 96 | 0 |         assert((input_bytes < 0 && fees == 0) || (input_bytes > 0 && fees >= 0)); | 
| 97 | 0 |         fee = fees; | 
| 98 | 0 |         effective_value = txout.nValue - fee.value(); | 
| 99 | 0 |     } | 
| 100 |  |  | 
| 101 |  |     std::string ToString() const; | 
| 102 |  |  | 
| 103 |  |     bool operator<(const COutput& rhs) const | 
| 104 | 0 |     { | 
| 105 | 0 |         return outpoint < rhs.outpoint; | 
| 106 | 0 |     } | 
| 107 |  |  | 
| 108 |  |     void ApplyBumpFee(CAmount bump_fee) | 
| 109 | 0 |     { | 
| 110 | 0 |         assert(bump_fee >= 0); | 
| 111 | 0 |         ancestor_bump_fees = bump_fee; | 
| 112 | 0 |         assert(fee); | 
| 113 | 0 |         *fee += bump_fee; | 
| 114 |  |         // Note: assert(effective_value - bump_fee == nValue - fee.value()); | 
| 115 | 0 |         effective_value = txout.nValue - fee.value(); | 
| 116 | 0 |     } | 
| 117 |  |  | 
| 118 |  |     CAmount GetFee() const | 
| 119 | 0 |     { | 
| 120 | 0 |         assert(fee.has_value()); | 
| 121 | 0 |         return fee.value(); | 
| 122 | 0 |     } | 
| 123 |  |  | 
| 124 |  |     CAmount GetEffectiveValue() const | 
| 125 | 0 |     { | 
| 126 | 0 |         assert(effective_value.has_value()); | 
| 127 | 0 |         return effective_value.value(); | 
| 128 | 0 |     } | 
| 129 |  |  | 
| 130 | 0 |     bool HasEffectiveValue() const { return effective_value.has_value(); } | 
| 131 |  | }; | 
| 132 |  |  | 
| 133 |  | /** Parameters for one iteration of Coin Selection. */ | 
| 134 |  | struct CoinSelectionParams { | 
| 135 |  |     /** Randomness to use in the context of coin selection. */ | 
| 136 |  |     FastRandomContext& rng_fast; | 
| 137 |  |     /** Size of a change output in bytes, determined by the output type. */ | 
| 138 |  |     int change_output_size = 0; | 
| 139 |  |     /** Size of the input to spend a change output in virtual bytes. */ | 
| 140 |  |     int change_spend_size = 0; | 
| 141 |  |     /** Mininmum change to target in Knapsack solver and CoinGrinder: | 
| 142 |  |      * select coins to cover the payment and at least this value of change. */ | 
| 143 |  |     CAmount m_min_change_target{0}; | 
| 144 |  |     /** Minimum amount for creating a change output. | 
| 145 |  |      * If change budget is smaller than min_change then we forgo creation of change output. | 
| 146 |  |      */ | 
| 147 |  |     CAmount min_viable_change{0}; | 
| 148 |  |     /** Cost of creating the change output. */ | 
| 149 |  |     CAmount m_change_fee{0}; | 
| 150 |  |     /** Cost of creating the change output + cost of spending the change output in the future. */ | 
| 151 |  |     CAmount m_cost_of_change{0}; | 
| 152 |  |     /** The targeted feerate of the transaction being built. */ | 
| 153 |  |     CFeeRate m_effective_feerate; | 
| 154 |  |     /** The feerate estimate used to estimate an upper bound on what should be sufficient to spend | 
| 155 |  |      * the change output sometime in the future. */ | 
| 156 |  |     CFeeRate m_long_term_feerate; | 
| 157 |  |     /** If the cost to spend a change output at the discard feerate exceeds its value, drop it to fees. */ | 
| 158 |  |     CFeeRate m_discard_feerate; | 
| 159 |  |     /** Size of the transaction before coin selection, consisting of the header and recipient | 
| 160 |  |      * output(s), excluding the inputs and change output(s). */ | 
| 161 |  |     int tx_noinputs_size = 0; | 
| 162 |  |     /** Indicate that we are subtracting the fee from outputs */ | 
| 163 |  |     bool m_subtract_fee_outputs = false; | 
| 164 |  |     /** When true, always spend all (up to OUTPUT_GROUP_MAX_ENTRIES) or none of the outputs | 
| 165 |  |      * associated with the same address. This helps reduce privacy leaks resulting from address | 
| 166 |  |      * reuse. Dust outputs are not eligible to be added to output groups and thus not considered. */ | 
| 167 |  |     bool m_avoid_partial_spends = false; | 
| 168 |  |     /** | 
| 169 |  |      * When true, allow unsafe coins to be selected during Coin Selection. This may spend unconfirmed outputs: | 
| 170 |  |      * 1) Received from other wallets, 2) replacing other txs, 3) that have been replaced. | 
| 171 |  |      */ | 
| 172 |  |     bool m_include_unsafe_inputs = false; | 
| 173 |  |     /** The version of the transaction we are trying to create. */ | 
| 174 |  |     uint32_t m_version{CTransaction::CURRENT_VERSION}; | 
| 175 |  |     /** The maximum weight for this transaction. */ | 
| 176 |  |     std::optional<int> m_max_tx_weight{std::nullopt}; | 
| 177 |  |  | 
| 178 |  |     CoinSelectionParams(FastRandomContext& rng_fast, int change_output_size, int change_spend_size, | 
| 179 |  |                         CAmount min_change_target, CFeeRate effective_feerate, | 
| 180 |  |                         CFeeRate long_term_feerate, CFeeRate discard_feerate, int tx_noinputs_size, bool avoid_partial, | 
| 181 |  |                         std::optional<int> max_tx_weight = std::nullopt) | 
| 182 |  |         : rng_fast{rng_fast}, | 
| 183 |  |           change_output_size(change_output_size), | 
| 184 |  |           change_spend_size(change_spend_size), | 
| 185 |  |           m_min_change_target(min_change_target), | 
| 186 |  |           m_effective_feerate(effective_feerate), | 
| 187 |  |           m_long_term_feerate(long_term_feerate), | 
| 188 |  |           m_discard_feerate(discard_feerate), | 
| 189 |  |           tx_noinputs_size(tx_noinputs_size), | 
| 190 |  |           m_avoid_partial_spends(avoid_partial), | 
| 191 |  |           m_max_tx_weight(max_tx_weight) | 
| 192 | 0 |     { | 
| 193 | 0 |     } | 
| 194 |  |     CoinSelectionParams(FastRandomContext& rng_fast) | 
| 195 | 0 |         : rng_fast{rng_fast} {} | 
| 196 |  | }; | 
| 197 |  |  | 
| 198 |  | /** Parameters for filtering which OutputGroups we may use in coin selection. | 
| 199 |  |  * We start by being very selective and requiring multiple confirmations and | 
| 200 |  |  * then get more permissive if we cannot fund the transaction. */ | 
| 201 |  | struct CoinEligibilityFilter | 
| 202 |  | { | 
| 203 |  |     /** Minimum number of confirmations for outputs that we sent to ourselves. | 
| 204 |  |      * We may use unconfirmed UTXOs sent from ourselves, e.g. change outputs. */ | 
| 205 |  |     const int conf_mine; | 
| 206 |  |     /** Minimum number of confirmations for outputs received from a different wallet. */ | 
| 207 |  |     const int conf_theirs; | 
| 208 |  |     /** Maximum number of unconfirmed ancestors aggregated across all UTXOs in an OutputGroup. */ | 
| 209 |  |     const uint64_t max_ancestors; | 
| 210 |  |     /** Maximum number of descendants that a single UTXO in the OutputGroup may have. */ | 
| 211 |  |     const uint64_t max_descendants; | 
| 212 |  |     /** When avoid_reuse=true and there are full groups (OUTPUT_GROUP_MAX_ENTRIES), whether or not to use any partial groups.*/ | 
| 213 |  |     const bool m_include_partial_groups{false}; | 
| 214 |  |  | 
| 215 |  |     CoinEligibilityFilter() = delete; | 
| 216 | 0 |     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) {} | 
| 217 | 0 |     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) {} | 
| 218 | 0 |     CoinEligibilityFilter(int conf_mine, int conf_theirs, uint64_t max_ancestors, uint64_t max_descendants, bool include_partial) : conf_mine(conf_mine), conf_theirs(conf_theirs), max_ancestors(max_ancestors), max_descendants(max_descendants), m_include_partial_groups(include_partial) {} | 
| 219 |  |  | 
| 220 | 0 |     bool operator<(const CoinEligibilityFilter& other) const { | 
| 221 | 0 |         return std::tie(conf_mine, conf_theirs, max_ancestors, max_descendants, m_include_partial_groups) | 
| 222 | 0 |                < std::tie(other.conf_mine, other.conf_theirs, other.max_ancestors, other.max_descendants, other.m_include_partial_groups); | 
| 223 | 0 |     } | 
| 224 |  | }; | 
| 225 |  |  | 
| 226 |  | /** A group of UTXOs paid to the same output script. */ | 
| 227 |  | struct OutputGroup | 
| 228 |  | { | 
| 229 |  |     /** The list of UTXOs contained in this output group. */ | 
| 230 |  |     std::vector<std::shared_ptr<COutput>> m_outputs; | 
| 231 |  |     /** Whether the UTXOs were sent by the wallet to itself. This is relevant because we may want at | 
| 232 |  |      * least a certain number of confirmations on UTXOs received from outside wallets while trusting | 
| 233 |  |      * our own UTXOs more. */ | 
| 234 |  |     bool m_from_me{true}; | 
| 235 |  |     /** The total value of the UTXOs in sum. */ | 
| 236 |  |     CAmount m_value{0}; | 
| 237 |  |     /** The minimum number of confirmations the UTXOs in the group have. Unconfirmed is 0. */ | 
| 238 |  |     int m_depth{999}; | 
| 239 |  |     /** The aggregated count of unconfirmed ancestors of all UTXOs in this | 
| 240 |  |      * group. Not deduplicated and may overestimate when ancestors are shared. */ | 
| 241 |  |     size_t m_ancestors{0}; | 
| 242 |  |     /** The maximum count of descendants of a single UTXO in this output group. */ | 
| 243 |  |     size_t m_descendants{0}; | 
| 244 |  |     /** The value of the UTXOs after deducting the cost of spending them at the effective feerate. */ | 
| 245 |  |     CAmount effective_value{0}; | 
| 246 |  |     /** The fee to spend these UTXOs at the effective feerate. */ | 
| 247 |  |     CAmount fee{0}; | 
| 248 |  |     /** The fee to spend these UTXOs at the long term feerate. */ | 
| 249 |  |     CAmount long_term_fee{0}; | 
| 250 |  |     /** The feerate for spending a created change output eventually (i.e. not urgently, and thus at | 
| 251 |  |      * a lower feerate). Calculated using long term fee estimate. This is used to decide whether | 
| 252 |  |      * it could be economical to create a change output. */ | 
| 253 |  |     CFeeRate m_long_term_feerate{0}; | 
| 254 |  |     /** Indicate that we are subtracting the fee from outputs. | 
| 255 |  |      * When true, the value that is used for coin selection is the UTXO's real value rather than effective value */ | 
| 256 |  |     bool m_subtract_fee_outputs{false}; | 
| 257 |  |     /** Total weight of the UTXOs in this group. */ | 
| 258 |  |     int m_weight{0}; | 
| 259 |  |  | 
| 260 |  |     OutputGroup() = default; | 
| 261 |  |     OutputGroup(const CoinSelectionParams& params) : | 
| 262 | 0 |         m_long_term_feerate(params.m_long_term_feerate), | 
| 263 | 0 |         m_subtract_fee_outputs(params.m_subtract_fee_outputs) | 
| 264 | 0 |     {} | 
| 265 |  |  | 
| 266 |  |     void Insert(const std::shared_ptr<COutput>& output, size_t ancestors, size_t descendants); | 
| 267 |  |     bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const; | 
| 268 |  |     CAmount GetSelectionAmount() const; | 
| 269 |  | }; | 
| 270 |  |  | 
| 271 |  | struct Groups { | 
| 272 |  |     // Stores 'OutputGroup' containing only positive UTXOs (value > 0). | 
| 273 |  |     std::vector<OutputGroup> positive_group; | 
| 274 |  |     // Stores 'OutputGroup' which may contain both positive and negative UTXOs. | 
| 275 |  |     std::vector<OutputGroup> mixed_group; | 
| 276 |  | }; | 
| 277 |  |  | 
| 278 |  | /** Stores several 'Groups' whose were mapped by output type. */ | 
| 279 |  | struct OutputGroupTypeMap | 
| 280 |  | { | 
| 281 |  |     // Maps output type to output groups. | 
| 282 |  |     std::map<OutputType, Groups> groups_by_type; | 
| 283 |  |     // All inserted groups, no type distinction. | 
| 284 |  |     Groups all_groups; | 
| 285 |  |  | 
| 286 |  |     // Based on the insert flag; appends group to the 'mixed_group' and, if value > 0, to the 'positive_group'. | 
| 287 |  |     // This affects both; the groups filtered by type and the overall groups container. | 
| 288 |  |     void Push(const OutputGroup& group, OutputType type, bool insert_positive, bool insert_mixed); | 
| 289 |  |     // Different output types count | 
| 290 | 0 |     size_t TypesCount() { return groups_by_type.size(); } | 
| 291 |  | }; | 
| 292 |  |  | 
| 293 |  | typedef std::map<CoinEligibilityFilter, OutputGroupTypeMap> FilteredOutputGroups; | 
| 294 |  |  | 
| 295 |  | /** Choose a random change target for each transaction to make it harder to fingerprint the Core | 
| 296 |  |  * wallet based on the change output values of transactions it creates. | 
| 297 |  |  * Change target covers at least change fees and adds a random value on top of it. | 
| 298 |  |  * The random value is between 50ksat and min(2 * payment_value, 1milsat) | 
| 299 |  |  * When payment_value <= 25ksat, the value is just 50ksat. | 
| 300 |  |  * | 
| 301 |  |  * Making change amounts similar to the payment value may help disguise which output(s) are payments | 
| 302 |  |  * are which ones are change. Using double the payment value may increase the number of inputs | 
| 303 |  |  * needed (and thus be more expensive in fees), but breaks analysis techniques which assume the | 
| 304 |  |  * coins selected are just sufficient to cover the payment amount ("unnecessary input" heuristic). | 
| 305 |  |  * | 
| 306 |  |  * @param[in]   payment_value   Average payment value of the transaction output(s). | 
| 307 |  |  * @param[in]   change_fee      Fee for creating a change output. | 
| 308 |  |  */ | 
| 309 |  | [[nodiscard]] CAmount GenerateChangeTarget(const CAmount payment_value, const CAmount change_fee, FastRandomContext& rng); | 
| 310 |  |  | 
| 311 |  | enum class SelectionAlgorithm : uint8_t | 
| 312 |  | { | 
| 313 |  |     BNB = 0, | 
| 314 |  |     KNAPSACK = 1, | 
| 315 |  |     SRD = 2, | 
| 316 |  |     CG = 3, | 
| 317 |  |     MANUAL = 4, | 
| 318 |  | }; | 
| 319 |  |  | 
| 320 |  | std::string GetAlgorithmName(const SelectionAlgorithm algo); | 
| 321 |  |  | 
| 322 |  | struct SelectionResult | 
| 323 |  | { | 
| 324 |  | private: | 
| 325 |  |     /** Set of inputs selected by the algorithm to use in the transaction */ | 
| 326 |  |     std::set<std::shared_ptr<COutput>> m_selected_inputs; | 
| 327 |  |     /** The target the algorithm selected for. Equal to the recipient amount plus non-input fees */ | 
| 328 |  |     CAmount m_target; | 
| 329 |  |     /** The algorithm used to produce this result */ | 
| 330 |  |     SelectionAlgorithm m_algo; | 
| 331 |  |     /** Whether the input values for calculations should be the effective value (true) or normal value (false) */ | 
| 332 |  |     bool m_use_effective{false}; | 
| 333 |  |     /** The computed waste */ | 
| 334 |  |     std::optional<CAmount> m_waste; | 
| 335 |  |     /** False if algorithm was cut short by hitting limit of attempts and solution is non-optimal */ | 
| 336 |  |     bool m_algo_completed{true}; | 
| 337 |  |     /** The count of selections that were evaluated by this coin selection attempt */ | 
| 338 |  |     size_t m_selections_evaluated; | 
| 339 |  |     /** Total weight of the selected inputs */ | 
| 340 |  |     int m_weight{0}; | 
| 341 |  |     /** How much individual inputs overestimated the bump fees for the shared ancestry */ | 
| 342 |  |     CAmount bump_fee_group_discount{0}; | 
| 343 |  |  | 
| 344 |  |     template<typename T> | 
| 345 |  |     void InsertInputs(const T& inputs) | 
| 346 | 0 |     { | 
| 347 |  |         // Store sum of combined input sets to check that the results have no shared UTXOs | 
| 348 | 0 |         const size_t expected_count = m_selected_inputs.size() + inputs.size(); | 
| 349 | 0 |         util::insert(m_selected_inputs, inputs); | 
| 350 | 0 |         if (m_selected_inputs.size() != expected_count) { | 
| 351 | 0 |             throw std::runtime_error(STR_INTERNAL_BUG("Shared UTXOs among selection results"));| Line | Count | Source |  | 89 | 0 | #define STR_INTERNAL_BUG(msg) StrFormatInternalBug((msg), __FILE__, __LINE__, __func__) | 
 |             throw std::runtime_error(STR_INTERNAL_BUG("Shared UTXOs among selection results"));| Line | Count | Source |  | 89 | 0 | #define STR_INTERNAL_BUG(msg) StrFormatInternalBug((msg), __FILE__, __LINE__, __func__) | 
 | 
| 352 | 0 |         } | 
| 353 | 0 |     } Unexecuted instantiation: _ZN6wallet15SelectionResult12InsertInputsINSt3__16vectorINS2_10shared_ptrINS_7COutputEEENS2_9allocatorIS6_EEEEEEvRKT_Unexecuted instantiation: _ZN6wallet15SelectionResult12InsertInputsINSt3__13setINS2_10shared_ptrINS_7COutputEEENS2_4lessIS6_EENS2_9allocatorIS6_EEEEEEvRKT_ | 
| 354 |  |  | 
| 355 |  | public: | 
| 356 |  |     explicit SelectionResult(const CAmount target, SelectionAlgorithm algo) | 
| 357 | 0 |         : m_target(target), m_algo(algo) {} | 
| 358 |  |  | 
| 359 |  |     SelectionResult() = delete; | 
| 360 |  |  | 
| 361 |  |     /** Get the sum of the input values */ | 
| 362 |  |     [[nodiscard]] CAmount GetSelectedValue() const; | 
| 363 |  |  | 
| 364 |  |     [[nodiscard]] CAmount GetSelectedEffectiveValue() const; | 
| 365 |  |  | 
| 366 |  |     [[nodiscard]] CAmount GetTotalBumpFees() const; | 
| 367 |  |  | 
| 368 |  |     void Clear(); | 
| 369 |  |  | 
| 370 |  |     void AddInput(const OutputGroup& group); | 
| 371 |  |     void AddInputs(const std::set<std::shared_ptr<COutput>>& inputs, bool subtract_fee_outputs); | 
| 372 |  |  | 
| 373 |  |     /** How much individual inputs overestimated the bump fees for shared ancestries */ | 
| 374 |  |     void SetBumpFeeDiscount(const CAmount discount); | 
| 375 |  |  | 
| 376 |  |     /** Calculates and stores the waste for this result given the cost of change | 
| 377 |  |      * and the opportunity cost of spending these inputs now vs in the future. | 
| 378 |  |      * If change exists, waste = change_cost + inputs * (effective_feerate - long_term_feerate) - bump_fee_group_discount | 
| 379 |  |      * If no change, waste = excess + inputs * (effective_feerate - long_term_feerate) - bump_fee_group_discount | 
| 380 |  |      * where excess = selected_effective_value - target | 
| 381 |  |      * change_cost = effective_feerate * change_output_size + long_term_feerate * change_spend_size | 
| 382 |  |      * | 
| 383 |  |      * @param[in] min_viable_change The minimum amount necessary to make a change output economic | 
| 384 |  |      * @param[in] change_cost       The cost of creating a change output and spending it in the future. Only | 
| 385 |  |      *                              used if there is change, in which case it must be non-negative. | 
| 386 |  |      * @param[in] change_fee        The fee for creating a change output | 
| 387 |  |      */ | 
| 388 |  |     void RecalculateWaste(const CAmount min_viable_change, const CAmount change_cost, const CAmount change_fee); | 
| 389 |  |     [[nodiscard]] CAmount GetWaste() const; | 
| 390 |  |  | 
| 391 |  |     /** Tracks that algorithm was able to exhaustively search the entire combination space before hitting limit of tries */ | 
| 392 |  |     void SetAlgoCompleted(bool algo_completed); | 
| 393 |  |  | 
| 394 |  |     /** Get m_algo_completed */ | 
| 395 |  |     bool GetAlgoCompleted() const; | 
| 396 |  |  | 
| 397 |  |     /** Record the number of selections that were evaluated */ | 
| 398 |  |     void SetSelectionsEvaluated(size_t attempts); | 
| 399 |  |  | 
| 400 |  |     /** Get selections_evaluated */ | 
| 401 |  |     size_t GetSelectionsEvaluated() const ; | 
| 402 |  |  | 
| 403 |  |     /** | 
| 404 |  |      * Combines the @param[in] other selection result into 'this' selection result. | 
| 405 |  |      * | 
| 406 |  |      * Important note: | 
| 407 |  |      * There must be no shared 'COutput' among the two selection results being combined. | 
| 408 |  |      */ | 
| 409 |  |     void Merge(const SelectionResult& other); | 
| 410 |  |  | 
| 411 |  |     /** Get m_selected_inputs */ | 
| 412 |  |     const std::set<std::shared_ptr<COutput>>& GetInputSet() const; | 
| 413 |  |     /** Get the vector of COutputs that will be used to fill in a CTransaction's vin */ | 
| 414 |  |     std::vector<std::shared_ptr<COutput>> GetShuffledInputVector() const; | 
| 415 |  |  | 
| 416 |  |     bool operator<(SelectionResult other) const; | 
| 417 |  |  | 
| 418 |  |     /** Get the amount for the change output after paying needed fees. | 
| 419 |  |      * | 
| 420 |  |      * The change amount is not 100% precise due to discrepancies in fee calculation. | 
| 421 |  |      * The final change amount (if any) should be corrected after calculating the final tx fees. | 
| 422 |  |      * When there is a discrepancy, most of the time the final change would be slightly bigger than estimated. | 
| 423 |  |      * | 
| 424 |  |      * Following are the possible factors of discrepancy: | 
| 425 |  |      *  + non-input fees always include segwit flags | 
| 426 |  |      *  + input fee estimation always include segwit stack size | 
| 427 |  |      *  + input fees are rounded individually and not collectively, which leads to small rounding errors | 
| 428 |  |      *  - input counter size is always assumed to be 1vbyte | 
| 429 |  |      * | 
| 430 |  |      * @param[in]  min_viable_change  Minimum amount for change output, if change would be less then we forgo change | 
| 431 |  |      * @param[in]  change_fee         Fees to include change output in the tx | 
| 432 |  |      * @returns Amount for change output, 0 when there is no change. | 
| 433 |  |      * | 
| 434 |  |      */ | 
| 435 |  |     CAmount GetChange(const CAmount min_viable_change, const CAmount change_fee) const; | 
| 436 |  |  | 
| 437 | 0 |     CAmount GetTarget() const { return m_target; } | 
| 438 |  |  | 
| 439 | 0 |     SelectionAlgorithm GetAlgo() const { return m_algo; } | 
| 440 |  |  | 
| 441 | 0 |     int GetWeight() const { return m_weight; } | 
| 442 |  | }; | 
| 443 |  |  | 
| 444 |  | util::Result<SelectionResult> SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, | 
| 445 |  |                                              int max_selection_weight); | 
| 446 |  |  | 
| 447 |  | util::Result<SelectionResult> CoinGrinder(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, CAmount change_target, int max_selection_weight); | 
| 448 |  |  | 
| 449 |  | /** Select coins by Single Random Draw. OutputGroups are selected randomly from the eligible | 
| 450 |  |  * outputs until the target is satisfied | 
| 451 |  |  * | 
| 452 |  |  * @param[in]  utxo_pool    The positive effective value OutputGroups eligible for selection | 
| 453 |  |  * @param[in]  target_value The target value to select for | 
| 454 |  |  * @param[in]  rng The randomness source to shuffle coins | 
| 455 |  |  * @param[in]  max_selection_weight The maximum allowed weight for a selection result to be valid | 
| 456 |  |  * @returns If successful, a valid SelectionResult, otherwise, util::Error | 
| 457 |  |  */ | 
| 458 |  | util::Result<SelectionResult> SelectCoinsSRD(const std::vector<OutputGroup>& utxo_pool, CAmount target_value, CAmount change_fee, FastRandomContext& rng, | 
| 459 |  |                                              int max_selection_weight); | 
| 460 |  |  | 
| 461 |  | // Original coin selection algorithm as a fallback | 
| 462 |  | util::Result<SelectionResult> KnapsackSolver(std::vector<OutputGroup>& groups, const CAmount& nTargetValue, | 
| 463 |  |                                              CAmount change_target, FastRandomContext& rng, int max_selection_weight); | 
| 464 |  | } // namespace wallet | 
| 465 |  |  | 
| 466 |  | #endif // BITCOIN_WALLET_COINSELECTION_H |