mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-05 10:17:30 -05:00
![Andrew Chow](/assets/img/avatar_default.png)
The fees for transaction overhead and recipient outputs are now included in nTargetValue instead of being a separate parameter. For the coin selection algorithms, it doesn't matter that these are separate as in either case, the algorithm needs to select enough to cover these fees. Note that setting nValueToSelect is changed as it now includes not_input_fees. Without the change to how nValueToSelect is increased for KnapsackSolver, this would result in overpaying fees. The change to increase by the difference between nFeeRet and not_input_fees allows this to have the same behavior as previously. Additionally, because we assume that KnapsackSolver will always find a solution that requires change (we assume that BnB always finds a non-change solution), we also include the fee for the change output in KnapsackSolver's target. As part of this, we also use the changeless nFeeRet when iterating for KnapsackSolver. This is because we include the change fee when doing KnapsackSolver, so nFeeRet on further iterations won't include the change fee.
128 lines
5.8 KiB
C++
128 lines
5.8 KiB
C++
// Copyright (c) 2017-2019 The Bitcoin Core developers
|
|
// Distributed under the MIT software license, see the accompanying
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
#ifndef BITCOIN_WALLET_COINSELECTION_H
|
|
#define BITCOIN_WALLET_COINSELECTION_H
|
|
|
|
#include <amount.h>
|
|
#include <policy/feerate.h>
|
|
#include <primitives/transaction.h>
|
|
#include <random.h>
|
|
|
|
//! target minimum change amount
|
|
static constexpr CAmount MIN_CHANGE{COIN / 100};
|
|
//! final minimum change amount after paying for fees
|
|
static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2;
|
|
|
|
/** A UTXO under consideration for use in funding a new transaction. */
|
|
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;
|
|
}
|
|
|
|
CInputCoin(const CTransactionRef& tx, unsigned int i, int input_bytes) : CInputCoin(tx, i)
|
|
{
|
|
m_input_bytes = input_bytes;
|
|
}
|
|
|
|
COutPoint outpoint;
|
|
CTxOut txout;
|
|
CAmount effective_value;
|
|
CAmount m_fee{0};
|
|
CAmount m_long_term_fee{0};
|
|
|
|
/** 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};
|
|
|
|
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;
|
|
}
|
|
};
|
|
|
|
/** 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. */
|
|
struct CoinEligibilityFilter
|
|
{
|
|
/** Minimum number of confirmations for outputs that we sent to ourselves.
|
|
* We may use unconfirmed UTXOs sent from ourselves, e.g. change outputs. */
|
|
const int conf_mine;
|
|
/** Minimum number of confirmations for outputs received from a different wallet. */
|
|
const int conf_theirs;
|
|
/** Maximum number of unconfirmed ancestors aggregated across all UTXOs in an OutputGroup. */
|
|
const uint64_t max_ancestors;
|
|
/** Maximum number of descendants that a single UTXO in the OutputGroup may have. */
|
|
const uint64_t max_descendants;
|
|
/** 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};
|
|
|
|
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) {}
|
|
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) {}
|
|
};
|
|
|
|
/** A group of UTXOs paid to the same output script. */
|
|
struct OutputGroup
|
|
{
|
|
/** The list of UTXOs contained in this output group. */
|
|
std::vector<CInputCoin> m_outputs;
|
|
/** 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. */
|
|
bool m_from_me{true};
|
|
/** The total value of the UTXOs in sum. */
|
|
CAmount m_value{0};
|
|
/** The minimum number of confirmations the UTXOs in the group have. Unconfirmed is 0. */
|
|
int m_depth{999};
|
|
/** The aggregated count of unconfirmed ancestors of all UTXOs in this
|
|
* group. Not deduplicated and may overestimate when ancestors are shared. */
|
|
size_t m_ancestors{0};
|
|
/** The maximum count of descendants of a single UTXO in this output group. */
|
|
size_t m_descendants{0};
|
|
/** The value of the UTXOs after deducting the cost of spending them at the effective feerate. */
|
|
CAmount effective_value{0};
|
|
/** The fee to spend these UTXOs at the effective feerate. */
|
|
CAmount fee{0};
|
|
/** The target feerate of the transaction we're trying to build. */
|
|
CFeeRate m_effective_feerate{0};
|
|
/** The fee to spend these UTXOs at the long term feerate. */
|
|
CAmount long_term_fee{0};
|
|
/** 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. */
|
|
CFeeRate m_long_term_feerate{0};
|
|
|
|
OutputGroup() {}
|
|
OutputGroup(const CFeeRate& effective_feerate, const CFeeRate& long_term_feerate) :
|
|
m_effective_feerate(effective_feerate),
|
|
m_long_term_feerate(long_term_feerate)
|
|
{}
|
|
|
|
void Insert(const CInputCoin& output, int depth, bool from_me, size_t ancestors, size_t descendants, bool positive_only);
|
|
bool EligibleForSpending(const CoinEligibilityFilter& eligibility_filter) const;
|
|
};
|
|
|
|
bool SelectCoinsBnB(std::vector<OutputGroup>& utxo_pool, const CAmount& selection_target, const CAmount& cost_of_change, std::set<CInputCoin>& out_set, CAmount& value_ret);
|
|
|
|
// Original coin selection algorithm as a fallback
|
|
bool KnapsackSolver(const CAmount& nTargetValue, std::vector<OutputGroup>& groups, std::set<CInputCoin>& setCoinsRet, CAmount& nValueRet);
|
|
|
|
#endif // BITCOIN_WALLET_COINSELECTION_H
|