2020-12-31 05:48:25 -03:00
|
|
|
// Copyright (c) 2017-2019 The Bitcoin Core developers
|
2018-03-05 18:29:37 -03:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2018-03-22 11:19:44 -03:00
|
|
|
#ifndef BITCOIN_WALLET_COINSELECTION_H
|
|
|
|
#define BITCOIN_WALLET_COINSELECTION_H
|
2018-03-05 18:29:37 -03:00
|
|
|
|
|
|
|
#include <amount.h>
|
2020-08-31 15:56:30 -04:00
|
|
|
#include <policy/feerate.h>
|
2018-03-05 18:29:37 -03:00
|
|
|
#include <primitives/transaction.h>
|
|
|
|
#include <random.h>
|
2018-03-07 14:18:37 -03:00
|
|
|
|
|
|
|
//! target minimum change amount
|
2018-09-17 15:33:52 -03:00
|
|
|
static constexpr CAmount MIN_CHANGE{COIN / 100};
|
2018-03-07 14:18:37 -03:00
|
|
|
//! final minimum change amount after paying for fees
|
|
|
|
static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
|
|
|
|
|
2021-04-21 18:52:29 -04:00
|
|
|
/** A UTXO under consideration for use in funding a new transaction. */
|
2018-03-07 14:18:37 -03:00
|
|
|
class CInputCoin {
|
|
|
|
public:
|
|
|
|
CInputCoin(const CTransactionRef& tx, unsigned int i)
|
|
|
|
{
|
|
|
|
if (!tx)
|
|
|
|
throw std::invalid_argument("tx should not be null");
|
|
|
|
if (i >= tx->vout.size())
|
|
|
|
throw std::out_of_range("The output index is out of range");
|
|
|
|
|
|
|
|
outpoint = COutPoint(tx->GetHash(), i);
|
|
|
|
txout = tx->vout[i];
|
|
|
|
effective_value = txout.nValue;
|
|
|
|
}
|
|
|
|
|
2018-07-17 03:56:06 -04:00
|
|
|
CInputCoin(const CTransactionRef& tx, unsigned int i, int input_bytes) : CInputCoin(tx, i)
|
|
|
|
{
|
|
|
|
m_input_bytes = input_bytes;
|
|
|
|
}
|
|
|
|
|
2018-03-07 14:18:37 -03:00
|
|
|
COutPoint outpoint;
|
|
|
|
CTxOut txout;
|
|
|
|
CAmount effective_value;
|
2019-11-12 17:06:24 -03:00
|
|
|
CAmount m_fee{0};
|
|
|
|
CAmount m_long_term_fee{0};
|
2018-03-07 14:18:37 -03:00
|
|
|
|
2018-07-17 03:56:06 -04:00
|
|
|
/** Pre-computed estimated size of this output as a fully-signed input in a transaction. Can be -1 if it could not be calculated */
|
|
|
|
int m_input_bytes{-1};
|
|
|
|
|
2018-03-07 14:18:37 -03:00
|
|
|
bool operator<(const CInputCoin& rhs) const {
|
|
|
|
return outpoint < rhs.outpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator!=(const CInputCoin& rhs) const {
|
|
|
|
return outpoint != rhs.outpoint;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const CInputCoin& rhs) const {
|
|
|
|
return outpoint == rhs.outpoint;
|
|
|
|
}
|
|
|
|
};
|
2018-03-05 18:29:37 -03:00
|
|
|
|
2021-04-21 18:52:29 -04:00
|
|
|
/** Parameters for filtering which OutputGroups we may use in coin selection.
|
|
|
|
* We start by being very selective and requiring multiple confirmations and
|
|
|
|
* then get more permissive if we cannot fund the transaction. */
|
2018-07-18 22:40:13 -04:00
|
|
|
struct CoinEligibilityFilter
|
|
|
|
{
|
2021-04-21 18:52:29 -04:00
|
|
|
/** Minimum number of confirmations for outputs that we sent to ourselves.
|
|
|
|
* We may use unconfirmed UTXOs sent from ourselves, e.g. change outputs. */
|
2018-07-18 22:40:13 -04:00
|
|
|
const int conf_mine;
|
2021-03-10 11:37:18 -03:00
|
|
|
/** Minimum number of confirmations for outputs received from a different wallet. */
|
2018-07-18 22:40:13 -04:00
|
|
|
const int conf_theirs;
|
2021-04-21 18:52:29 -04:00
|
|
|
/** Maximum number of unconfirmed ancestors aggregated across all UTXOs in an OutputGroup. */
|
2018-07-18 22:40:13 -04:00
|
|
|
const uint64_t max_ancestors;
|
2021-04-21 18:52:29 -04:00
|
|
|
/** Maximum number of descendants that a single UTXO in the OutputGroup may have. */
|
2018-07-18 22:40:13 -04:00
|
|
|
const uint64_t max_descendants;
|
2021-04-21 18:52:29 -04:00
|
|
|
/** When avoid_reuse=true and there are full groups (OUTPUT_GROUP_MAX_ENTRIES), whether or not to use any partial groups.*/
|
|
|
|
const bool m_include_partial_groups{false};
|
2018-07-18 22:40:13 -04:00
|
|
|
|
|
|
|
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) {}
|
|
|
|
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) {}
|
2020-10-01 14:43:17 -03:00
|
|
|
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) {}
|
2018-07-18 22:40:13 -04:00
|
|
|
};
|
|
|
|
|
2021-04-21 18:52:29 -04:00
|
|
|
/** A group of UTXOs paid to the same output script. */
|
2018-07-18 22:43:03 -04:00
|
|
|
struct OutputGroup
|
|
|
|
{
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The list of UTXOs contained in this output group. */
|
2018-07-18 22:43:03 -04:00
|
|
|
std::vector<CInputCoin> m_outputs;
|
2021-04-21 18:52:29 -04:00
|
|
|
/** Whether the UTXOs were sent by the wallet to itself. This is relevant because we may want at
|
|
|
|
* least a certain number of confirmations on UTXOs received from outside wallets while trusting
|
|
|
|
* our own UTXOs more. */
|
2018-07-18 22:43:03 -04:00
|
|
|
bool m_from_me{true};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The total value of the UTXOs in sum. */
|
2018-07-18 22:43:03 -04:00
|
|
|
CAmount m_value{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The minimum number of confirmations the UTXOs in the group have. Unconfirmed is 0. */
|
2018-07-18 22:43:03 -04:00
|
|
|
int m_depth{999};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The aggregated count of unconfirmed ancestors of all UTXOs in this
|
|
|
|
* group. Not deduplicated and may overestimate when ancestors are shared. */
|
2018-07-18 22:43:03 -04:00
|
|
|
size_t m_ancestors{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The maximum count of descendants of a single UTXO in this output group. */
|
2018-07-18 22:43:03 -04:00
|
|
|
size_t m_descendants{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The value of the UTXOs after deducting the cost of spending them at the effective feerate. */
|
2018-07-18 22:43:03 -04:00
|
|
|
CAmount effective_value{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The fee to spend these UTXOs at the effective feerate. */
|
2018-07-18 22:43:03 -04:00
|
|
|
CAmount fee{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The target feerate of the transaction we're trying to build. */
|
2020-08-31 15:56:30 -04:00
|
|
|
CFeeRate m_effective_feerate{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The fee to spend these UTXOs at the long term feerate. */
|
2018-07-18 22:43:03 -04:00
|
|
|
CAmount long_term_fee{0};
|
2021-04-21 18:52:29 -04:00
|
|
|
/** The feerate for spending a created change output eventually (i.e. not urgently, and thus at
|
|
|
|
* a lower feerate). Calculated using long term fee estimate. This is used to decide whether
|
|
|
|
* it could be economical to create a change output. */
|
2020-08-31 15:56:30 -04:00
|
|
|
CFeeRate m_long_term_feerate{0};
|
2018-07-18 22:43:03 -04:00
|
|
|
|
|
|
|
OutputGroup() {}
|
2020-08-31 15:56:30 -04:00
|
|
|
OutputGroup(const CFeeRate& effective_feerate, const CFeeRate& long_term_feerate) :
|
|
|
|
m_effective_feerate(effective_feerate),
|
|
|
|
m_long_term_feerate(long_term_feerate)
|
2018-07-18 22:43:03 -04:00
|
|
|
{}
|
2019-11-12 17:06:24 -03:00
|
|
|
|
2020-08-31 16:45:39 -04:00
|
|
|
void Insert(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants, bool positive_only);
|
2018-07-18 22:43:03 -04:00
|
|
|
bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const;
|
|
|
|
};
|
|
|
|
|
2019-10-30 19:41:13 -03:00
|
|
|
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret);
|
2018-03-05 18:29:37 -03:00
|
|
|
|
2018-03-10 00:51:39 -03:00
|
|
|
// Original coin selection algorithm as a fallback
|
2018-07-18 22:45:26 -04:00
|
|
|
bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet);
|
2018-07-18 22:43:03 -04:00
|
|
|
|
2018-03-22 11:19:44 -03:00
|
|
|
#endif // BITCOIN_WALLET_COINSELECTION_H
|