aboutsummaryrefslogtreecommitdiff
path: root/src/policy/rbf.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/policy/rbf.cpp')
-rw-r--r--src/policy/rbf.cpp37
1 files changed, 37 insertions, 0 deletions
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<std::string> GetEntriesForConflicts(const CTransaction& tx,
return std::nullopt;
}
+std::optional<std::string> HasNoNewUnconfirmed(const CTransaction& tx,
+ const CTxMemPool& m_pool,
+ const CTxMemPool::setEntries& setIterConflicting)
+{
+ AssertLockHeld(m_pool.cs);
+ std::set<uint256> 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;
+}