aboutsummaryrefslogtreecommitdiff
path: root/src/policy
diff options
context:
space:
mode:
authorglozow <gloriajzhao@gmail.com>2021-08-03 13:13:43 +0100
committerglozow <gloriajzhao@gmail.com>2021-09-02 16:23:26 +0100
commit7b60c02b7d5e2ab12288393d2258873ebb26d811 (patch)
tree3ede75858f8f52b94a2dfeef45806b100e23d93d /src/policy
parentf8ad2a57c61d1e817e2445226688e03080fc8688 (diff)
MOVEONLY: BIP125 Rule 2 to policy/rbf
Diffstat (limited to 'src/policy')
-rw-r--r--src/policy/rbf.cpp37
-rw-r--r--src/policy/rbf.h7
2 files changed, 44 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;
+}
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<std::string> 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<std::string> HasNoNewUnconfirmed(const CTransaction& tx, const CTxMemPool& m_pool,
+ const CTxMemPool::setEntries& setIterConflicting)
+ EXCLUSIVE_LOCKS_REQUIRED(m_pool.cs);
#endif // BITCOIN_POLICY_RBF_H