From 7b60c02b7d5e2ab12288393d2258873ebb26d811 Mon Sep 17 00:00:00 2001 From: glozow Date: Tue, 3 Aug 2021 13:13:43 +0100 Subject: MOVEONLY: BIP125 Rule 2 to policy/rbf --- src/policy/rbf.cpp | 37 +++++++++++++++++++++++++++++++++++++ src/policy/rbf.h | 7 +++++++ 2 files changed, 44 insertions(+) (limited to 'src/policy') diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp index 3ff4c1f9c2..f6b3bc783a 100644 --- a/src/policy/rbf.cpp +++ b/src/policy/rbf.cpp @@ -75,3 +75,40 @@ std::optional GetEntriesForConflicts(const CTransaction& tx, return std::nullopt; } +std::optional HasNoNewUnconfirmed(const CTransaction& tx, + const CTxMemPool& m_pool, + const CTxMemPool::setEntries& setIterConflicting) +{ + AssertLockHeld(m_pool.cs); + std::set setConflictsParents; + for (const auto& mi : setIterConflicting) { + for (const CTxIn &txin : mi->GetTx().vin) + { + setConflictsParents.insert(txin.prevout.hash); + } + } + + for (unsigned int j = 0; j < tx.vin.size(); j++) + { + // 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. + // + // Note that if you relax this to make RBF a little more useful, + // this may break the CalculateMempoolAncestors RBF relaxation, + // above. See the comment above the first CalculateMempoolAncestors + // call for more info. + if (!setConflictsParents.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. + if (m_pool.exists(tx.vin[j].prevout.hash)) { + return strprintf("replacement %s adds unconfirmed input, idx %d", + tx.GetHash().ToString(), j); + } + } + } + return std::nullopt; +} diff --git a/src/policy/rbf.h b/src/policy/rbf.h index 2a41ca8892..0f9a3d9856 100644 --- a/src/policy/rbf.h +++ b/src/policy/rbf.h @@ -49,4 +49,11 @@ std::optional GetEntriesForConflicts(const CTransaction& tx, CTxMem const CTxMemPool::setEntries& setIterConflicting, CTxMemPool::setEntries& allConflicting) EXCLUSIVE_LOCKS_REQUIRED(m_pool.cs); + +/** BIP125 Rule #2: "The replacement transaction may only include an unconfirmed input if that input + * was included in one of the original transactions." + * @returns error message if Rule #2 is broken, otherwise std::nullopt. */ +std::optional HasNoNewUnconfirmed(const CTransaction& tx, const CTxMemPool& m_pool, + const CTxMemPool::setEntries& setIterConflicting) + EXCLUSIVE_LOCKS_REQUIRED(m_pool.cs); #endif // BITCOIN_POLICY_RBF_H -- cgit v1.2.3