diff --git a/src/txmempool.h b/src/txmempool.h --- a/src/txmempool.h +++ b/src/txmempool.h @@ -665,7 +665,21 @@ Amount &nFeeDelta) const; void ClearPrioritisation(const TxId &txid); -public: + /** Get the transaction in the pool that spends the same prevout */ + const CTransaction *GetConflictTx(const COutPoint &prevout) const + EXCLUSIVE_LOCKS_REQUIRED(cs); + + /** Returns an iterator to the given txid, if found */ + boost::optional GetIter(const TxId &txid) const + EXCLUSIVE_LOCKS_REQUIRED(cs); + + /** + * Translate a set of txids into a set of pool iterators to avoid repeated + * lookups. + */ + setEntries GetIterSet(const std::set &txids) const + EXCLUSIVE_LOCKS_REQUIRED(cs); + /** * Remove a set of transactions from the mempool. If a transaction is in * this set, then all in-mempool descendants must also be in the set, unless diff --git a/src/txmempool.cpp b/src/txmempool.cpp --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -192,11 +192,11 @@ // GetMemPoolParents() is only valid for entries in the mempool, so we // iterate mapTx to find parents. for (const CTxIn &in : tx.vin) { - txiter piter = mapTx.find(in.prevout.GetTxId()); - if (piter == mapTx.end()) { + boost::optional piter = GetIter(in.prevout.GetTxId()); + if (!piter) { continue; } - parentHashes.insert(piter); + parentHashes.insert(*piter); if (parentHashes.size() + 1 > limitAncestorCount) { errString = strprintf("too many unconfirmed parents [limit: %u]", @@ -419,12 +419,11 @@ // Update transaction for any feeDelta created by PrioritiseTransaction // TODO: refactor so that the fee delta is calculated before inserting into // mapTx. - std::map::const_iterator pos = mapDeltas.find(txid); - if (pos != mapDeltas.end()) { - const TXModifier &deltas = pos->second; - if (deltas.second != Amount::zero()) { - mapTx.modify(newit, update_fee_delta(deltas.second)); - } + double priorityDelta = 0; + Amount feeDelta = Amount::zero(); + ApplyDeltas(entry.GetTx().GetId(), priorityDelta, feeDelta); + if (feeDelta != Amount::zero()) { + mapTx.modify(newit, update_fee_delta(feeDelta)); } // Update cachedInnerUsage to include contained transaction's usage. @@ -446,11 +445,8 @@ // the mess we're leaving here. // Update ancestors with information about this tx - for (const TxId &phash : setParentTransactions) { - txiter pit = mapTx.find(phash); - if (pit != mapTx.end()) { - UpdateParent(newit, pit, true); - } + for (const auto &pit : GetIterSet(setParentTransactions)) { + UpdateParent(newit, pit, true); } UpdateAncestorsOf(true, newit, setAncestors); UpdateEntryForAncestors(newit, setAncestors); @@ -988,6 +984,32 @@ mapDeltas.erase(txid); } +const CTransaction *CTxMemPool::GetConflictTx(const COutPoint &prevout) const { + const auto it = mapNextTx.find(prevout); + return it == mapNextTx.end() ? nullptr : it->second; +} + +boost::optional +CTxMemPool::GetIter(const TxId &txid) const { + auto it = mapTx.find(txid); + if (it != mapTx.end()) { + return it; + } + return boost::optional{}; +} + +CTxMemPool::setEntries +CTxMemPool::GetIterSet(const std::set &txids) const { + CTxMemPool::setEntries ret; + for (const auto &txid : txids) { + const auto mi = GetIter(txid); + if (mi) { + ret.insert(*mi); + } + } + return ret; +} + bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const { for (const CTxIn &in : tx.vin) { if (exists(in.prevout.GetTxId())) {