2020-12-31 09:48:25 +01:00
|
|
|
// Copyright (c) 2016-2020 The Bitcoin Core developers
|
2015-12-16 14:57:54 -05:00
|
|
|
// Distributed under the MIT software license, see the accompanying
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
2017-11-10 13:57:53 +13:00
|
|
|
#include <policy/rbf.h>
|
2021-07-27 14:23:40 +01:00
|
|
|
|
|
|
|
#include <policy/settings.h>
|
|
|
|
#include <tinyformat.h>
|
|
|
|
#include <util/moneystr.h>
|
2019-04-02 17:03:37 -04:00
|
|
|
#include <util/rbf.h>
|
2015-12-16 14:57:54 -05:00
|
|
|
|
2019-02-23 11:04:20 -05:00
|
|
|
RBFTransactionState IsRBFOptIn(const CTransaction& tx, const CTxMemPool& pool)
|
2015-12-16 14:57:54 -05:00
|
|
|
{
|
|
|
|
AssertLockHeld(pool.cs);
|
|
|
|
|
|
|
|
CTxMemPool::setEntries setAncestors;
|
|
|
|
|
|
|
|
// First check the transaction itself.
|
2016-04-05 14:20:49 +02:00
|
|
|
if (SignalsOptInRBF(tx)) {
|
2018-03-09 15:03:40 +01:00
|
|
|
return RBFTransactionState::REPLACEABLE_BIP125;
|
2015-12-16 14:57:54 -05: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 14:20:49 +02:00
|
|
|
if (!pool.exists(tx.GetHash())) {
|
2018-03-09 15:03:40 +01:00
|
|
|
return RBFTransactionState::UNKNOWN;
|
2015-12-16 14:57:54 -05: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 14:20:49 +02:00
|
|
|
CTxMemPoolEntry entry = *pool.mapTx.find(tx.GetHash());
|
2015-12-16 14:57:54 -05:00
|
|
|
pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false);
|
|
|
|
|
2017-06-02 03:18:57 +02:00
|
|
|
for (CTxMemPool::txiter it : setAncestors) {
|
2015-12-16 14:57:54 -05:00
|
|
|
if (SignalsOptInRBF(it->GetTx())) {
|
2018-03-09 15:03:40 +01:00
|
|
|
return RBFTransactionState::REPLACEABLE_BIP125;
|
2015-12-16 14:57:54 -05:00
|
|
|
}
|
|
|
|
}
|
2018-03-09 15:03:40 +01:00
|
|
|
return RBFTransactionState::FINAL;
|
2015-12-16 14:57:54 -05:00
|
|
|
}
|
2020-07-19 11:09:59 +02: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 14:23:40 +01:00
|
|
|
|
|
|
|
bool GetEntriesForConflicts(const CTransaction& tx,
|
|
|
|
CTxMemPool& m_pool,
|
|
|
|
const CTxMemPool::setEntries& setIterConflicting,
|
|
|
|
CTxMemPool::setEntries& allConflicting,
|
|
|
|
std::string& err_string)
|
|
|
|
{
|
|
|
|
AssertLockHeld(m_pool.cs);
|
|
|
|
const uint256 hash = tx.GetHash();
|
|
|
|
uint64_t nConflictingCount = 0;
|
|
|
|
for (const auto& mi : setIterConflicting) {
|
|
|
|
nConflictingCount += mi->GetCountWithDescendants();
|
|
|
|
// This potentially overestimates the number of actual descendants
|
|
|
|
// but we just want to be conservative to avoid doing too much
|
|
|
|
// work.
|
|
|
|
if (nConflictingCount > MAX_BIP125_REPLACEMENT_CANDIDATES) {
|
|
|
|
err_string = strprintf("rejecting replacement %s; too many potential replacements (%d > %d)\n",
|
|
|
|
hash.ToString(),
|
|
|
|
nConflictingCount,
|
|
|
|
MAX_BIP125_REPLACEMENT_CANDIDATES);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// If not too many to replace, then calculate the set of
|
|
|
|
// transactions that would have to be evicted
|
|
|
|
for (CTxMemPool::txiter it : setIterConflicting) {
|
|
|
|
m_pool.CalculateDescendants(it, allConflicting);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|