diff options
author | glozow <gloriajzhao@gmail.com> | 2021-08-03 13:13:43 +0100 |
---|---|---|
committer | glozow <gloriajzhao@gmail.com> | 2021-09-02 16:23:26 +0100 |
commit | 7b60c02b7d5e2ab12288393d2258873ebb26d811 (patch) | |
tree | 3ede75858f8f52b94a2dfeef45806b100e23d93d /src/policy | |
parent | f8ad2a57c61d1e817e2445226688e03080fc8688 (diff) |
MOVEONLY: BIP125 Rule 2 to policy/rbf
Diffstat (limited to 'src/policy')
-rw-r--r-- | src/policy/rbf.cpp | 37 | ||||
-rw-r--r-- | src/policy/rbf.h | 7 |
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 |