2020-12-31 05:48:25 -03:00
|
|
|
// Copyright (c) 2016-2020 The Bitcoin Core developers
|
2015-12-16 16:57:54 -03:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2017-11-09 21:57:53 -03:00
|
|
|
#include <policy/rbf.h>
|
2021-07-27 09:23:40 -04:00
|
|
|
|
|
|
|
#include <policy/settings.h>
|
|
|
|
#include <tinyformat.h>
|
|
|
|
#include <util/moneystr.h>
|
2019-04-02 18:03:37 -03:00
|
|
|
#include <util/rbf.h>
|
2015-12-16 16:57:54 -03:00
|
|
|
|
2019-02-23 13:04:20 -03:00
|
|
|
RBFTransactionState IsRBFOptIn(const CTransaction& tx, const CTxMemPool& pool)
|
2015-12-16 16:57:54 -03:00
|
|
|
{
|
|
|
|
AssertLockHeld(pool.cs);
|
|
|
|
|
2021-08-16 05:19:15 -04:00
|
|
|
CTxMemPool::setEntries ancestors;
|
2015-12-16 16:57:54 -03:00
|
|
|
|
|
|
|
// First check the transaction itself.
|
2016-04-05 09:20:49 -03:00
|
|
|
if (SignalsOptInRBF(tx)) {
|
2018-03-09 11:03:40 -03:00
|
|
|
return RBFTransactionState::REPLACEABLE_BIP125;
|
2015-12-16 16:57:54 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
// If this transaction is not in our mempool, then we can't be sure
|
|
|
|
// we will know about all its inputs.
|
2016-04-05 09:20:49 -03:00
|
|
|
if (!pool.exists(tx.GetHash())) {
|
2018-03-09 11:03:40 -03:00
|
|
|
return RBFTransactionState::UNKNOWN;
|
2015-12-16 16:57:54 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
// If all the inputs have nSequence >= maxint-1, it still might be
|
|
|
|
// signaled for RBF if any unconfirmed parents have signaled.
|
|
|
|
uint64_t noLimit = std::numeric_limits<uint64_t>::max();
|
|
|
|
std::string dummy;
|
2016-04-05 09:20:49 -03:00
|
|
|
CTxMemPoolEntry entry = *pool.mapTx.find(tx.GetHash());
|
2021-08-16 05:19:15 -04:00
|
|
|
pool.CalculateMemPoolAncestors(entry, ancestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
|
2015-12-16 16:57:54 -03:00
|
|
|
|
2021-08-16 05:19:15 -04:00
|
|
|
for (CTxMemPool::txiter it : ancestors) {
|
2015-12-16 16:57:54 -03:00
|
|
|
if (SignalsOptInRBF(it->GetTx())) {
|
2018-03-09 11:03:40 -03:00
|
|
|
return RBFTransactionState::REPLACEABLE_BIP125;
|
2015-12-16 16:57:54 -03:00
|
|
|
}
|
|
|
|
}
|
2018-03-09 11:03:40 -03:00
|
|
|
return RBFTransactionState::FINAL;
|
2015-12-16 16:57:54 -03:00
|
|
|
}
|
2020-07-19 05:09:59 -04:00
|
|
|
|
|
|
|
RBFTransactionState IsRBFOptInEmptyMempool(const CTransaction& tx)
|
|
|
|
{
|
|
|
|
// If we don't have a local mempool we can only check the transaction itself.
|
|
|
|
return SignalsOptInRBF(tx) ? RBFTransactionState::REPLACEABLE_BIP125 : RBFTransactionState::UNKNOWN;
|
|
|
|
}
|
2021-07-27 09:23:40 -04:00
|
|
|
|
2021-09-02 10:27:37 -04:00
|
|
|
std::optional<std::string> GetEntriesForConflicts(const CTransaction& tx,
|
2021-08-16 05:40:46 -04:00
|
|
|
CTxMemPool& pool,
|
|
|
|
const CTxMemPool::setEntries& iters_conflicting,
|
|
|
|
CTxMemPool::setEntries& all_conflicts)
|
2021-07-27 09:23:40 -04:00
|
|
|
{
|
2021-08-16 05:19:15 -04:00
|
|
|
AssertLockHeld(pool.cs);
|
|
|
|
const uint256 txid = tx.GetHash();
|
2021-07-27 09:23:40 -04:00
|
|
|
uint64_t nConflictingCount = 0;
|
2021-08-16 05:19:15 -04:00
|
|
|
for (const auto& mi : iters_conflicting) {
|
2021-07-27 09:23:40 -04:00
|
|
|
nConflictingCount += mi->GetCountWithDescendants();
|
2021-08-16 05:40:46 -04:00
|
|
|
// BIP125 Rule #5: don't consider replacing more than MAX_BIP125_REPLACEMENT_CANDIDATES
|
|
|
|
// entries from the mempool. This potentially overestimates the number of actual
|
|
|
|
// descendants (i.e. if multiple conflicts share a descendant, it will be counted multiple
|
|
|
|
// times), but we just want to be conservative to avoid doing too much work.
|
2021-07-27 09:23:40 -04:00
|
|
|
if (nConflictingCount > MAX_BIP125_REPLACEMENT_CANDIDATES) {
|
2021-09-02 10:27:37 -04:00
|
|
|
return strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
|
2021-09-01 04:54:04 -04:00
|
|
|
txid.ToString(),
|
|
|
|
nConflictingCount,
|
|
|
|
MAX_BIP125_REPLACEMENT_CANDIDATES);
|
2021-07-27 09:23:40 -04:00
|
|
|
}
|
|
|
|
}
|
2021-08-16 05:40:46 -04:00
|
|
|
// Calculate the set of all transactions that would have to be evicted.
|
2021-08-16 05:19:15 -04:00
|
|
|
for (CTxMemPool::txiter it : iters_conflicting) {
|
|
|
|
pool.CalculateDescendants(it, all_conflicts);
|
2021-07-27 09:23:40 -04:00
|
|
|
}
|
2021-09-02 10:27:37 -04:00
|
|
|
return std::nullopt;
|
2021-07-27 09:23:40 -04:00
|
|
|
}
|
|
|
|
|
2021-08-03 08:13:43 -04:00
|
|
|
std::optional<std::string> HasNoNewUnconfirmed(const CTransaction& tx,
|
2021-08-16 05:19:15 -04:00
|
|
|
const CTxMemPool& pool,
|
|
|
|
const CTxMemPool::setEntries& iters_conflicting)
|
2021-08-03 08:13:43 -04:00
|
|
|
{
|
2021-08-16 05:19:15 -04:00
|
|
|
AssertLockHeld(pool.cs);
|
|
|
|
std::set<uint256> parents_of_conflicts;
|
|
|
|
for (const auto& mi : iters_conflicting) {
|
2021-08-16 05:40:46 -04:00
|
|
|
for (const CTxIn& txin : mi->GetTx().vin) {
|
2021-08-16 05:19:15 -04:00
|
|
|
parents_of_conflicts.insert(txin.prevout.hash);
|
2021-08-03 08:13:43 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-09-01 04:54:04 -04:00
|
|
|
for (unsigned int j = 0; j < tx.vin.size(); j++) {
|
2021-08-16 05:40:46 -04:00
|
|
|
// BIP125 Rule #2: We don't want to accept replacements that require low feerate junk to be
|
|
|
|
// mined first. Ideally we'd keep track of the ancestor feerates and make the decision
|
|
|
|
// based on that, but for now requiring all new inputs to be confirmed works.
|
2021-08-03 08:13:43 -04:00
|
|
|
//
|
2021-09-01 04:54:04 -04:00
|
|
|
// Note that if you relax this to make RBF a little more useful, this may break the
|
2021-08-16 05:40:46 -04:00
|
|
|
// CalculateMempoolAncestors RBF relaxation which subtracts the conflict count/size from the
|
|
|
|
// descendant limit.
|
2021-09-01 04:54:04 -04:00
|
|
|
if (!parents_of_conflicts.count(tx.vin[j].prevout.hash)) {
|
|
|
|
// Rather than check the UTXO set - potentially expensive - it's cheaper to just check
|
|
|
|
// if the new input refers to a tx that's in the mempool.
|
2021-08-16 05:19:15 -04:00
|
|
|
if (pool.exists(tx.vin[j].prevout.hash)) {
|
2021-08-03 08:13:43 -04:00
|
|
|
return strprintf("replacement %s adds unconfirmed input, idx %d",
|
|
|
|
tx.GetHash().ToString(), j);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
2021-07-27 10:55:25 -04:00
|
|
|
|
2021-08-16 05:19:15 -04:00
|
|
|
std::optional<std::string> EntriesAndTxidsDisjoint(const CTxMemPool::setEntries& ancestors,
|
|
|
|
const std::set<uint256>& direct_conflicts,
|
2021-07-27 10:55:25 -04:00
|
|
|
const uint256& txid)
|
|
|
|
{
|
2021-09-01 04:54:04 -04:00
|
|
|
for (CTxMemPool::txiter ancestorIt : ancestors) {
|
2021-08-16 05:40:46 -04:00
|
|
|
const uint256& hashAncestor = ancestorIt->GetTx().GetHash();
|
2021-09-01 04:54:04 -04:00
|
|
|
if (direct_conflicts.count(hashAncestor)) {
|
2021-07-27 10:55:25 -04:00
|
|
|
return strprintf("%s spends conflicting transaction %s",
|
|
|
|
txid.ToString(),
|
|
|
|
hashAncestor.ToString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
2021-08-11 10:51:27 -04:00
|
|
|
|
2021-08-16 05:19:15 -04:00
|
|
|
std::optional<std::string> PaysMoreThanConflicts(const CTxMemPool::setEntries& iters_conflicting,
|
|
|
|
CFeeRate replacement_feerate,
|
|
|
|
const uint256& txid)
|
2021-08-11 10:51:27 -04:00
|
|
|
{
|
2021-08-16 05:19:15 -04:00
|
|
|
for (const auto& mi : iters_conflicting) {
|
2021-09-01 04:54:04 -04:00
|
|
|
// Don't allow the replacement to reduce the feerate of the mempool.
|
2021-08-11 10:51:27 -04:00
|
|
|
//
|
2021-09-01 04:54:04 -04:00
|
|
|
// We usually don't want to accept replacements with lower feerates than what they replaced
|
|
|
|
// as that would lower the feerate of the next block. Requiring that the feerate always be
|
|
|
|
// increased is also an easy-to-reason about way to prevent DoS attacks via replacements.
|
2021-08-11 10:51:27 -04:00
|
|
|
//
|
2021-09-01 04:54:04 -04:00
|
|
|
// We only consider the feerates of transactions being directly replaced, not their indirect
|
|
|
|
// descendants. While that does mean high feerate children are ignored when deciding whether
|
|
|
|
// or not to replace, we do require the replacement to pay more overall fees too, mitigating
|
|
|
|
// most cases.
|
2021-08-16 05:19:15 -04:00
|
|
|
CFeeRate original_feerate(mi->GetModifiedFee(), mi->GetTxSize());
|
2021-09-01 04:54:04 -04:00
|
|
|
if (replacement_feerate <= original_feerate) {
|
2021-08-11 10:51:27 -04:00
|
|
|
return strprintf("rejecting replacement %s; new feerate %s <= old feerate %s",
|
2021-08-16 05:19:15 -04:00
|
|
|
txid.ToString(),
|
|
|
|
replacement_feerate.ToString(),
|
|
|
|
original_feerate.ToString());
|
2021-08-11 10:51:27 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
2021-08-16 05:19:15 -04:00
|
|
|
std::optional<std::string> PaysForRBF(CAmount original_fees,
|
|
|
|
CAmount replacement_fees,
|
|
|
|
size_t replacement_vsize,
|
2021-09-08 05:44:39 -03:00
|
|
|
CFeeRate relay_fee,
|
2021-08-16 05:19:15 -04:00
|
|
|
const uint256& txid)
|
2021-08-11 10:51:41 -04:00
|
|
|
{
|
2021-08-16 05:40:46 -04:00
|
|
|
// BIP125 Rule #3: The replacement fees must be greater than or equal to fees of the
|
|
|
|
// transactions it replaces, otherwise the bandwidth used by those conflicting transactions
|
|
|
|
// would not be paid for.
|
2021-09-01 04:54:04 -04:00
|
|
|
if (replacement_fees < original_fees) {
|
2021-08-11 10:51:41 -04:00
|
|
|
return strprintf("rejecting replacement %s, less fees than conflicting txs; %s < %s",
|
2021-08-16 05:19:15 -04:00
|
|
|
txid.ToString(), FormatMoney(replacement_fees), FormatMoney(original_fees));
|
2021-08-11 10:51:41 -04:00
|
|
|
}
|
|
|
|
|
2021-08-16 05:40:46 -04:00
|
|
|
// BIP125 Rule #4: The new transaction must pay for its own bandwidth. Otherwise, we have a DoS
|
|
|
|
// vector where attackers can cause a transaction to be replaced (and relayed) repeatedly by
|
|
|
|
// increasing the fee by tiny amounts.
|
2021-08-16 05:19:15 -04:00
|
|
|
CAmount additional_fees = replacement_fees - original_fees;
|
2021-09-08 05:44:39 -03:00
|
|
|
if (additional_fees < relay_fee.GetFee(replacement_vsize)) {
|
2021-08-11 10:51:41 -04:00
|
|
|
return strprintf("rejecting replacement %s, not enough additional fees to relay; %s < %s",
|
2021-08-16 05:19:15 -04:00
|
|
|
txid.ToString(),
|
|
|
|
FormatMoney(additional_fees),
|
2021-09-08 05:44:39 -03:00
|
|
|
FormatMoney(relay_fee.GetFee(replacement_vsize)));
|
2021-08-11 10:51:41 -04:00
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|