LCOV - code coverage report
Current view: top level - src - txmempool.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 1079 1172 92.1 %
Date: 2026-06-25 07:23:43 Functions: 97 97 100.0 %

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2021 The Bitcoin Core developers
       3             : // Distributed under the MIT software license, see the accompanying
       4             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       5             : 
       6             : #include <txmempool.h>
       7             : 
       8             : #include <chain.h>
       9             : #include <coins.h>
      10             : #include <consensus/consensus.h>
      11             : #include <consensus/tx_verify.h>
      12             : #include <consensus/validation.h>
      13             : #include <hash.h>
      14             : #include <index/addressindex_util.h>
      15             : #include <policy/fees.h>
      16             : #include <policy/policy.h>
      17             : #include <policy/settings.h>
      18             : #include <util/check.h>
      19             : #include <util/moneystr.h>
      20             : #include <util/overflow.h>
      21             : #include <util/system.h>
      22             : #include <util/time.h>
      23             : #include <validationinterface.h>
      24             : 
      25             : #include <evo/specialtx.h>
      26             : #include <evo/assetlocktx.h>
      27             : #include <evo/providertx.h>
      28             : #include <evo/deterministicmns.h>
      29             : #include <instantsend/instantsend.h>
      30             : 
      31             : #include <cmath>
      32             : #include <memory>
      33             : #include <optional>
      34             : #include <ranges>
      35             : 
      36             : // Forward declarations for index globals and utilities
      37             : class AddressIndex;
      38             : class SpentIndex;
      39             : extern std::unique_ptr<AddressIndex> g_addressindex;
      40             : extern std::unique_ptr<SpentIndex> g_spentindex;
      41             : 
      42        4340 : bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp)
      43             : {
      44        4340 :     AssertLockHeld(cs_main);
      45             :     // If there are relative lock times then the maxInputBlock will be set
      46             :     // If there are no relative lock times, the LockPoints don't depend on the chain
      47        4340 :     if (lp.maxInputBlock) {
      48             :         // Check whether active_chain is an extension of the block at which the LockPoints
      49             :         // calculation was valid.  If not LockPoints are no longer valid
      50        4334 :         if (!active_chain.Contains(lp.maxInputBlock)) {
      51          29 :             return false;
      52             :         }
      53        4305 :     }
      54             : 
      55             :     // LockPoints still valid
      56        4311 :     return true;
      57        4340 : }
      58             : 
      59      259641 : CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
      60             :                                  int64_t time, unsigned int entry_height,
      61             :                                  bool spends_coinbase, int64_t sigops_count, LockPoints lp)
      62       86547 :     : tx{tx},
      63       86547 :       nFee{fee},
      64       86547 :       nTxSize(tx->GetTotalSize()),
      65       86547 :       nUsageSize{RecursiveDynamicUsage(tx)},
      66       86547 :       nTime{time},
      67       86547 :       entryHeight{entry_height},
      68       86547 :       spendsCoinbase{spends_coinbase},
      69       86547 :       sigOpCount{sigops_count},
      70       86547 :       m_modified_fee{nFee},
      71       86547 :       lockPoints{lp},
      72             :       nSizeWithDescendants{GetTxSize()},
      73             :       nModFeesWithDescendants{nFee},
      74             :       nSizeWithAncestors{GetTxSize()},
      75             :       nModFeesWithAncestors{nFee},
      76       86547 :       nSigOpCountWithAncestors{sigOpCount} {}
      77             : 
      78         432 : void CTxMemPoolEntry::UpdateModifiedFee(CAmount newFeeDelta)
      79             : {
      80         432 :     nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, newFeeDelta);
      81         432 :     nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, newFeeDelta);
      82         432 :     m_modified_fee = SaturatingAdd(m_modified_fee, newFeeDelta);
      83         432 : }
      84             : 
      85          23 : void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp)
      86             : {
      87          23 :     lockPoints = lp;
      88          23 : }
      89             : 
      90   268839753 : size_t CTxMemPoolEntry::GetTxSize() const
      91             : {
      92   268839753 :     return GetVirtualTransactionSize(nTxSize, sigOpCount);
      93             : }
      94             : 
      95         985 : void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants,
      96             :                                       const std::set<uint256>& setExclude, std::set<uint256>& descendants_to_remove,
      97             :                                       uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
      98             : {
      99         985 :     CTxMemPoolEntry::Children stageEntries, descendants;
     100         985 :     stageEntries = updateIt->GetMemPoolChildrenConst();
     101             : 
     102       15446 :     while (!stageEntries.empty()) {
     103       14461 :         const CTxMemPoolEntry& descendant = *stageEntries.begin();
     104       14461 :         descendants.insert(descendant);
     105       14461 :         stageEntries.erase(descendant);
     106       14461 :         const CTxMemPoolEntry::Children& children = descendant.GetMemPoolChildrenConst();
     107      493013 :         for (const CTxMemPoolEntry& childEntry : children) {
     108      478552 :             cacheMap::iterator cacheIt = cachedDescendants.find(mapTx.iterator_to(childEntry));
     109      478552 :             if (cacheIt != cachedDescendants.end()) {
     110             :                 // We've already calculated this one, just add the entries for this set
     111             :                 // but don't traverse again.
     112     1055710 :                 for (txiter cacheEntry : cacheIt->second) {
     113     1035005 :                     descendants.insert(*cacheEntry);
     114             :                 }
     115      478552 :             } else if (!descendants.count(childEntry)) {
     116             :                 // Schedule for later processing
     117       30510 :                 stageEntries.insert(childEntry);
     118       30510 :             }
     119             :         }
     120             :     }
     121             :     // descendants now contains all in-mempool descendants of updateIt.
     122             :     // Update and add to cached descendant map
     123         985 :     int64_t modifySize = 0;
     124         985 :     CAmount modifyFee = 0;
     125         985 :     int64_t modifyCount = 0;
     126       15450 :     for (const CTxMemPoolEntry& descendant : descendants) {
     127       14465 :         if (!setExclude.count(descendant.GetTx().GetHash())) {
     128       11286 :             modifySize += descendant.GetTxSize();
     129       11286 :             modifyFee += descendant.GetModifiedFee();
     130       11286 :             modifyCount++;
     131       11286 :             cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant));
     132             :             // Update ancestor state for each descendant
     133       22572 :             mapTx.modify(mapTx.iterator_to(descendant), [=](CTxMemPoolEntry& e) {
     134       11286 :                 e.UpdateAncestorState(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCount());
     135       11286 :             });
     136             :             // Don't directly remove the transaction here -- doing so would
     137             :             // invalidate iterators in cachedDescendants. Mark it for removal
     138             :             // by inserting into descendants_to_remove.
     139       11286 :             if (descendant.GetCountWithAncestors() > ancestor_count_limit || descendant.GetSizeWithAncestors() > ancestor_size_limit) {
     140           0 :                 descendants_to_remove.insert(descendant.GetTx().GetHash());
     141           0 :             }
     142       11286 :         }
     143             :     }
     144        1970 :     mapTx.modify(updateIt, [=](CTxMemPoolEntry& e) { e.UpdateDescendantState(modifySize, modifyFee, modifyCount); });
     145         985 : }
     146             : 
     147        6481 : void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate, uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
     148             : {
     149        6481 :     AssertLockHeld(cs);
     150             :     // For each entry in vHashesToUpdate, store the set of in-mempool, but not
     151             :     // in-vHashesToUpdate transactions, so that we don't have to recalculate
     152             :     // descendants when we come across a previously seen entry.
     153        6481 :     cacheMap mapMemPoolDescendantsToUpdate;
     154             : 
     155             :     // Use a set for lookups into vHashesToUpdate (these entries are already
     156             :     // accounted for in the state of their ancestors)
     157        6481 :     std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
     158             : 
     159        6481 :     std::set<uint256> descendants_to_remove;
     160             : 
     161             :     // Iterate in reverse, so that whenever we are looking at a transaction
     162             :     // we are sure that all in-mempool descendants have already been processed.
     163             :     // This maximizes the benefit of the descendant cache and guarantees that
     164             :     // CTxMemPoolEntry::m_children will be updated, an assumption made in
     165             :     // UpdateForDescendants.
     166        7466 :     for (const uint256& hash : vHashesToUpdate | std::views::reverse) {
     167             :         // calculate children from mapNextTx
     168         985 :         txiter it = mapTx.find(hash);
     169         985 :         if (it == mapTx.end()) {
     170           0 :             continue;
     171             :         }
     172         985 :         auto iter = mapNextTx.lower_bound(COutPoint(hash, 0));
     173             :         // First calculate the children, and update CTxMemPoolEntry::m_children to
     174             :         // include them, and update their CTxMemPoolEntry::m_parents to include this tx.
     175             :         // we cache the in-mempool children to avoid duplicate updates
     176             :         {
     177         985 :             WITH_FRESH_EPOCH(m_epoch);
     178       30109 :             for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
     179       14126 :                 const uint256 &childHash = iter->second->GetHash();
     180       14126 :                 txiter childIter = mapTx.find(childHash);
     181       14126 :                 assert(childIter != mapTx.end());
     182             :                 // We can skip updating entries we've encountered before or that
     183             :                 // are in the block (which are already accounted for).
     184       14126 :                 if (!visited(childIter) && !setAlreadyIncluded.count(childHash)) {
     185       11280 :                     UpdateChild(it, childIter, true);
     186       11280 :                     UpdateParent(childIter, it, true);
     187       11280 :                 }
     188       14126 :             }
     189         985 :         } // release epoch guard for UpdateForDescendants
     190         985 :         UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded, descendants_to_remove, ancestor_size_limit, ancestor_count_limit);
     191             :     }
     192             : 
     193        6481 :     for (const auto& txid : descendants_to_remove) {
     194             :         // This txid may have been removed already in a prior call to removeRecursive.
     195             :         // Therefore we ensure it is not yet removed already.
     196           0 :         if (const std::optional<txiter> txiter = GetIter(txid)) {
     197           0 :             removeRecursive((*txiter)->GetTx(), MemPoolRemovalReason::SIZELIMIT);
     198           0 :         }
     199             :     }
     200        6481 : }
     201             : 
     202     8183546 : bool CTxMemPool::CalculateAncestorsAndCheckLimits(size_t entry_size,
     203             :                                                   size_t entry_count,
     204             :                                                   setEntries& setAncestors,
     205             :                                                   CTxMemPoolEntry::Parents& staged_ancestors,
     206             :                                                   uint64_t limitAncestorCount,
     207             :                                                   uint64_t limitAncestorSize,
     208             :                                                   uint64_t limitDescendantCount,
     209             :                                                   uint64_t limitDescendantSize,
     210             :                                                   std::string &errString) const
     211             : {
     212     8183546 :     size_t totalSizeWithAncestors = entry_size;
     213             : 
     214     9508958 :     while (!staged_ancestors.empty()) {
     215     1325602 :         const CTxMemPoolEntry& stage = staged_ancestors.begin()->get();
     216     1325602 :         txiter stageit = mapTx.iterator_to(stage);
     217             : 
     218     1325602 :         setAncestors.insert(stageit);
     219     1325602 :         staged_ancestors.erase(stage);
     220     1325602 :         totalSizeWithAncestors += stageit->GetTxSize();
     221             : 
     222     1325602 :         if (stageit->GetSizeWithDescendants() + entry_size > limitDescendantSize) {
     223          59 :             errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize);
     224          59 :             return false;
     225     1325543 :         } else if (stageit->GetCountWithDescendants() + entry_count > limitDescendantCount) {
     226          50 :             errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount);
     227          50 :             return false;
     228     1325493 :         } else if (totalSizeWithAncestors > limitAncestorSize) {
     229           2 :             errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize);
     230           2 :             return false;
     231             :         }
     232             : 
     233     1325491 :         const CTxMemPoolEntry::Parents& parents = stageit->GetMemPoolParentsConst();
     234     2884937 :         for (const CTxMemPoolEntry& parent : parents) {
     235     1559525 :             txiter parent_it = mapTx.iterator_to(parent);
     236             : 
     237             :             // If this is a new ancestor, add it.
     238     1559525 :             if (setAncestors.count(parent_it) == 0) {
     239     1359790 :                 staged_ancestors.insert(parent);
     240     1359790 :             }
     241     1559525 :             if (staged_ancestors.size() + setAncestors.size() + entry_count > limitAncestorCount) {
     242          79 :                 errString = strprintf("too many unconfirmed ancestors [limit: %u]", limitAncestorCount);
     243          79 :                 return false;
     244             :             }
     245             :         }
     246             :     }
     247             : 
     248     8183356 :     return true;
     249     8183546 : }
     250             : 
     251         127 : bool CTxMemPool::CheckPackageLimits(const Package& package,
     252             :                                     uint64_t limitAncestorCount,
     253             :                                     uint64_t limitAncestorSize,
     254             :                                     uint64_t limitDescendantCount,
     255             :                                     uint64_t limitDescendantSize,
     256             :                                     std::string &errString) const
     257             : {
     258         127 :     CTxMemPoolEntry::Parents staged_ancestors;
     259         127 :     size_t total_size = 0;
     260        1298 :     for (const auto& tx : package) {
     261        1173 :         total_size += GetVirtualTransactionSize(*tx);
     262        3135 :         for (const auto& input : tx->vin) {
     263        1964 :             std::optional<txiter> piter = GetIter(input.prevout.hash);
     264        1964 :             if (piter) {
     265          72 :                 staged_ancestors.insert(**piter);
     266          72 :                 if (staged_ancestors.size() + package.size() > limitAncestorCount) {
     267           2 :                     errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
     268           2 :                     return false;
     269             :                 }
     270          70 :             }
     271             :         }
     272             :     }
     273             :     // When multiple transactions are passed in, the ancestors and descendants of all transactions
     274             :     // considered together must be within limits even if they are not interdependent. This may be
     275             :     // stricter than the limits for each individual transaction.
     276         125 :     setEntries setAncestors;
     277         250 :     const auto ret = CalculateAncestorsAndCheckLimits(total_size, package.size(),
     278             :                                                       setAncestors, staged_ancestors,
     279         125 :                                                       limitAncestorCount, limitAncestorSize,
     280         125 :                                                       limitDescendantCount, limitDescendantSize, errString);
     281             :     // It's possible to overestimate the ancestor/descendant totals.
     282         125 :     if (!ret) errString.insert(0, "possibly ");
     283         125 :     return ret;
     284         127 : }
     285             : 
     286     8183422 : bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry,
     287             :                                            setEntries &setAncestors,
     288             :                                            uint64_t limitAncestorCount,
     289             :                                            uint64_t limitAncestorSize,
     290             :                                            uint64_t limitDescendantCount,
     291             :                                            uint64_t limitDescendantSize,
     292             :                                            std::string &errString,
     293             :                                            bool fSearchForParents /* = true */) const
     294             : {
     295     8183422 :     CTxMemPoolEntry::Parents staged_ancestors;
     296     8183422 :     const CTransaction &tx = entry.GetTx();
     297             : 
     298     8183422 :     if (fSearchForParents) {
     299             :         // Get parents of this transaction that are in the mempool
     300             :         // GetMemPoolParents() is only valid for entries in the mempool, so we
     301             :         // iterate mapTx to find parents.
     302    19456223 :         for (unsigned int i = 0; i < tx.vin.size(); i++) {
     303    11347409 :             std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
     304    11347409 :             if (piter) {
     305      190947 :                 staged_ancestors.insert(**piter);
     306      190947 :                 if (staged_ancestors.size() + 1 > limitAncestorCount) {
     307           1 :                     errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
     308           1 :                     return false;
     309             :                 }
     310      190946 :             }
     311    11347408 :         }
     312     8108814 :     } else {
     313             :         // If we're not searching for parents, we require this to already be an
     314             :         // entry in the mempool and use the entry's cached parents.
     315       74607 :         txiter it = mapTx.iterator_to(entry);
     316       74607 :         staged_ancestors = it->GetMemPoolParentsConst();
     317             :     }
     318             : 
     319     8183421 :     return CalculateAncestorsAndCheckLimits(entry.GetTxSize(), /*entry_count=*/1,
     320     8183421 :                                             setAncestors, staged_ancestors,
     321     8183421 :                                             limitAncestorCount, limitAncestorSize,
     322     8183421 :                                             limitDescendantCount, limitDescendantSize, errString);
     323     8183422 : }
     324             : 
     325      123146 : void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors)
     326             : {
     327      123146 :     const CTxMemPoolEntry::Parents& parents = it->GetMemPoolParentsConst();
     328             :     // add or remove this tx as a child of each parent
     329      134865 :     for (const CTxMemPoolEntry& parent : parents) {
     330       11719 :         UpdateChild(mapTx.iterator_to(parent), it, add);
     331             :     }
     332      123146 :     const int64_t updateCount = (add ? 1 : -1);
     333      123146 :     const int64_t updateSize = updateCount * it->GetTxSize();
     334      123146 :     const CAmount updateFee = updateCount * it->GetModifiedFee();
     335     1147693 :     for (txiter ancestorIt : setAncestors) {
     336     2049094 :         mapTx.modify(ancestorIt, [=](CTxMemPoolEntry& e) { e.UpdateDescendantState(updateSize, updateFee, updateCount); });
     337             :     }
     338      123146 : }
     339             : 
     340       63716 : void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncestors)
     341             : {
     342       63716 :     int64_t updateCount = setAncestors.size();
     343       63716 :     int64_t updateSize = 0;
     344       63716 :     CAmount updateFee = 0;
     345       63716 :     int updateSigOps = 0;
     346     1088167 :     for (txiter ancestorIt : setAncestors) {
     347     1024451 :         updateSize += ancestorIt->GetTxSize();
     348     1024451 :         updateFee += ancestorIt->GetModifiedFee();
     349     1024451 :         updateSigOps += ancestorIt->GetSigOpCount();
     350             :     }
     351      127432 :     mapTx.modify(it, [=](CTxMemPoolEntry& e){ e.UpdateAncestorState(updateSize, updateFee, updateCount, updateSigOps); });
     352       63716 : }
     353             : 
     354       59430 : void CTxMemPool::UpdateChildrenForRemoval(txiter it)
     355             : {
     356       59430 :     const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
     357       64903 :     for (const CTxMemPoolEntry& updateIt : children) {
     358        5473 :         UpdateParent(mapTx.iterator_to(updateIt), it, false);
     359             :     }
     360       59430 : }
     361             : 
     362      144563 : void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants)
     363             : {
     364             :     // For each entry, walk back all ancestors and decrement size associated with this
     365             :     // transaction
     366      144563 :     const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
     367      144563 :     if (updateDescendants) {
     368             :         // updateDescendants should be true whenever we're not recursively
     369             :         // removing a tx and all its descendants, eg when a transaction is
     370             :         // confirmed in a block.
     371             :         // Here we only update statistics and not data in CTxMemPool::Parents
     372             :         // and CTxMemPoolEntry::Children (which we need to preserve until we're
     373             :         // finished with all operations that need to traverse the mempool).
     374      118028 :         for (txiter removeIt : entriesToRemove) {
     375       59014 :             setEntries setDescendants;
     376       59014 :             CalculateDescendants(removeIt, setDescendants);
     377       59014 :             setDescendants.erase(removeIt); // don't update state for self
     378       59014 :             int64_t modifySize = -((int64_t)removeIt->GetTxSize());
     379       59014 :             CAmount modifyFee = -removeIt->GetModifiedFee();
     380       59014 :             int modifySigOps = -removeIt->GetSigOpCount();
     381       69518 :             for (txiter dit : setDescendants) {
     382       21008 :                 mapTx.modify(dit, [=](CTxMemPoolEntry& e){ e.UpdateAncestorState(modifySize, modifyFee, -1, modifySigOps); });
     383             :             }
     384       59014 :         }
     385       59014 :     }
     386      203993 :     for (txiter removeIt : entriesToRemove) {
     387       59430 :         setEntries setAncestors;
     388       59430 :         const CTxMemPoolEntry &entry = *removeIt;
     389       59430 :         std::string dummy;
     390             :         // Since this is a tx that is already in the mempool, we can call CMPA
     391             :         // with fSearchForParents = false.  If the mempool is in a consistent
     392             :         // state, then using true or false should both be correct, though false
     393             :         // should be a bit faster.
     394             :         // However, if we happen to be in the middle of processing a reorg, then
     395             :         // the mempool can be in an inconsistent state.  In this case, the set
     396             :         // of ancestors reachable via GetMemPoolParents()/GetMemPoolChildren()
     397             :         // will be the same as the set of ancestors whose packages include this
     398             :         // transaction, because when we add a new transaction to the mempool in
     399             :         // addUnchecked(), we assume it has no children, and in the case of a
     400             :         // reorg where that assumption is false, the in-mempool children aren't
     401             :         // linked to the in-block tx's until UpdateTransactionsFromBlock() is
     402             :         // called.
     403             :         // So if we're being called during a reorg, ie before
     404             :         // UpdateTransactionsFromBlock() has been called, then
     405             :         // GetMemPoolParents()/GetMemPoolChildren() will differ from the set of
     406             :         // mempool parents we'd calculate by searching, and it's important that
     407             :         // we use the cached notion of ancestor transactions as the set of
     408             :         // things to update for removal.
     409       59430 :         CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
     410             :         // Note that UpdateAncestorsOf severs the child links that point to
     411             :         // removeIt in the entries for the parents of removeIt.
     412       59430 :         UpdateAncestorsOf(false, removeIt, setAncestors);
     413       59430 :     }
     414             :     // After updating all the ancestor sizes, we can now sever the link between each
     415             :     // transaction being removed and any mempool children (ie, update CTxMemPoolEntry::m_parents
     416             :     // for each direct child of a transaction being removed).
     417      203993 :     for (txiter removeIt : entriesToRemove) {
     418       59430 :         UpdateChildrenForRemoval(removeIt);
     419             :     }
     420      144563 : }
     421             : 
     422     1025578 : void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
     423             : {
     424     1025578 :     nSizeWithDescendants += modifySize;
     425     1025578 :     assert(int64_t(nSizeWithDescendants) > 0);
     426     1025578 :     nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, modifyFee);
     427     1025578 :     nCountWithDescendants += modifyCount;
     428     1025578 :     assert(int64_t(nCountWithDescendants) > 0);
     429     1025578 : }
     430             : 
     431       85560 : void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
     432             : {
     433       85560 :     nSizeWithAncestors += modifySize;
     434       85560 :     assert(int64_t(nSizeWithAncestors) > 0);
     435       85560 :     nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, modifyFee);
     436       85560 :     nCountWithAncestors += modifyCount;
     437       85560 :     assert(int64_t(nCountWithAncestors) > 0);
     438       85560 :     nSigOpCountWithAncestors += modifySigOps;
     439       85560 :     assert(int(nSigOpCountWithAncestors) >= 0);
     440       85560 : }
     441             : 
     442       53328 : CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
     443       26664 :     : m_check_ratio(check_ratio), minerPolicyEstimator(estimator)
     444       26664 : {
     445             :     _clear(); //lock free clear
     446       26664 : }
     447             : 
     448        3067 : void CTxMemPool::ConnectManagers(gsl::not_null<CDeterministicMNManager*> dmnman, gsl::not_null<llmq::CInstantSendManager*> isman)
     449             : {
     450             :     // Do not allow double-initialization
     451        3067 :     assert(m_dmnman.load(std::memory_order_acquire) == nullptr);
     452        3067 :     m_dmnman.store(dmnman, std::memory_order_release);
     453        3067 :     assert(m_isman.load(std::memory_order_acquire) == nullptr);
     454        3067 :     m_isman.store(isman, std::memory_order_release);
     455        3067 : }
     456             : 
     457        3065 : void CTxMemPool::DisconnectManagers()
     458             : {
     459        3065 :     m_dmnman.store(nullptr, std::memory_order_release);
     460        3065 :     m_isman.store(nullptr, std::memory_order_release);
     461        3065 : }
     462             : 
     463       14927 : bool CTxMemPool::isSpent(const COutPoint& outpoint) const
     464             : {
     465       14927 :     LOCK(cs);
     466       14927 :     return mapNextTx.count(outpoint);
     467       14927 : }
     468             : 
     469         559 : unsigned int CTxMemPool::GetTransactionsUpdated() const
     470             : {
     471         559 :     return nTransactionsUpdated;
     472             : }
     473             : 
     474      271391 : void CTxMemPool::AddTransactionsUpdated(unsigned int n)
     475             : {
     476      271391 :     nTransactionsUpdated += n;
     477      271391 : }
     478             : 
     479       63716 : void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
     480             : {
     481             :     // Add to memory pool without checking anything.
     482             :     // Used by AcceptToMemoryPool(), which DOES do
     483             :     // all the appropriate checks.
     484       63716 :     indexed_transaction_set::iterator newit = mapTx.emplace(CTxMemPoolEntry::ExplicitCopy, entry).first;
     485             : 
     486             :     // Update transaction for any feeDelta created by PrioritiseTransaction
     487       63716 :     CAmount delta{0};
     488       63716 :     ApplyDelta(entry.GetTx().GetHash(), delta);
     489             :     // The following call to UpdateModifiedFee assumes no previous fee modifications
     490       63716 :     Assume(entry.GetFee() == entry.GetModifiedFee());
     491       63716 :     if (delta) {
     492         124 :         mapTx.modify(newit, [&delta](CTxMemPoolEntry& e) { e.UpdateModifiedFee(delta); });
     493          62 :     }
     494             : 
     495             :     // Update cachedInnerUsage to include contained transaction's usage.
     496             :     // (When we update the entry for in-mempool parents, memory usage will be
     497             :     // further updated.)
     498       63716 :     cachedInnerUsage += entry.DynamicMemoryUsage();
     499             : 
     500       63716 :     const CTransaction& tx = newit->GetTx();
     501       63716 :     std::set<uint256> setParentTransactions;
     502      169599 :     for (unsigned int i = 0; i < tx.vin.size(); i++) {
     503      105883 :         mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, &tx));
     504      105883 :         setParentTransactions.insert(tx.vin[i].prevout.hash);
     505      105883 :     }
     506             :     // Don't bother worrying about child transactions of this one.
     507             :     // Normal case of a new transaction arriving is that there can't be any
     508             :     // children, because such children would be orphans.
     509             :     // An exception to that is if a transaction enters that used to be in a block.
     510             :     // In that case, our disconnect block logic will call UpdateTransactionsFromBlock
     511             :     // to clean up the mess we're leaving here.
     512             : 
     513             :     // Update ancestors with information about this tx
     514       75360 :     for (const auto& pit : GetIterSet(setParentTransactions)) {
     515       11644 :             UpdateParent(newit, pit, true);
     516             :     }
     517       63716 :     UpdateAncestorsOf(true, newit, setAncestors);
     518       63716 :     UpdateEntryForAncestors(newit, setAncestors);
     519             : 
     520       63716 :     nTransactionsUpdated++;
     521       63716 :     totalTxSize += entry.GetTxSize();
     522       63716 :     m_total_fee += entry.GetFee();
     523       63716 :     if (minerPolicyEstimator) {
     524       63706 :         minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
     525       63706 :     }
     526             : 
     527       63716 :     vTxHashes.emplace_back(entry.GetTx().GetHash(), newit);
     528       63716 :     newit->vTxHashesIdx = vTxHashes.size() - 1;
     529             : 
     530             :     // Invalid ProTxes should never get this far because transactions should be
     531             :     // fully checked by AcceptToMemoryPool() at this point, so we just assume that
     532             :     // everything is fine here.
     533       63716 :     if (auto dmnman = m_dmnman.load(std::memory_order_acquire); dmnman) {
     534       39116 :         addUncheckedProTx(*dmnman, newit, tx);
     535       39116 :     }
     536       63716 : }
     537             : 
     538       36890 : void CTxMemPool::addAddressIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view)
     539             : {
     540       36890 :     if (!g_addressindex) return;
     541             : 
     542          24 :     LOCK(cs);
     543          24 :     const CTransaction& tx = entry.GetTx();
     544          24 :     std::vector<CMempoolAddressDeltaKey> inserted;
     545             : 
     546          24 :     uint256 txhash = tx.GetHash();
     547          52 :     for (unsigned int j = 0; j < tx.vin.size(); j++) {
     548          28 :         const CTxIn input = tx.vin[j];
     549          28 :         const Coin& coin = view.AccessCoin(input.prevout);
     550          28 :         const CTxOut &prevout = coin.out;
     551             : 
     552          28 :         AddressType address_type{AddressType::UNKNOWN};
     553          28 :         uint160 address_bytes;
     554             : 
     555          28 :         if (!AddressBytesFromScript(prevout.scriptPubKey, address_type, address_bytes)) {
     556           0 :             continue;
     557             :         }
     558             : 
     559          28 :         CMempoolAddressDeltaKey key(address_type, address_bytes, txhash, j, /* tx_spent */ true);
     560          28 :         CMempoolAddressDelta delta(entry.GetTime(), prevout.nValue * -1, input.prevout.hash, input.prevout.n);
     561          28 :         mapAddress.insert(std::make_pair(key, delta));
     562          28 :         inserted.push_back(key);
     563          28 :     }
     564             : 
     565          64 :     for (unsigned int k = 0; k < tx.vout.size(); k++) {
     566          40 :         const CTxOut &out = tx.vout[k];
     567             : 
     568          40 :         AddressType address_type{AddressType::UNKNOWN};
     569          40 :         uint160 address_bytes;
     570             : 
     571          40 :         if (!AddressBytesFromScript(out.scriptPubKey, address_type, address_bytes)) {
     572           0 :             continue;
     573             :         }
     574             : 
     575          40 :         CMempoolAddressDeltaKey key(address_type, address_bytes, txhash, k, /* tx_spent */ false);
     576          40 :         mapAddress.insert(std::make_pair(key, CMempoolAddressDelta(entry.GetTime(), out.nValue)));
     577          40 :         inserted.push_back(key);
     578          40 :     }
     579             : 
     580          24 :     mapAddressInserted.insert(std::make_pair(txhash, inserted));
     581       36890 : }
     582             : 
     583           8 : void CTxMemPool::getAddressIndex(const std::vector<CMempoolAddressDeltaKey>& addresses,
     584             :                                  std::vector<CMempoolAddressDeltaEntry>& results) const
     585             : {
     586           8 :     LOCK(cs);
     587          16 :     for (const auto& address : addresses) {
     588           8 :         auto ait = mapAddress.lower_bound(address);
     589          41 :         while (ait != mapAddress.end() && (*ait).first.m_address_bytes == address.m_address_bytes
     590          19 :                && (*ait).first.m_address_type == address.m_address_type) {
     591          14 :             results.push_back(*ait);
     592          14 :             ait++;
     593             :         }
     594             :     }
     595           8 : }
     596             : 
     597       59430 : void CTxMemPool::removeAddressIndex(const uint256 txhash)
     598             : {
     599       59430 :     LOCK(cs);
     600       59430 :     if (auto it = mapAddressInserted.find(txhash); it != mapAddressInserted.end()) {
     601          62 :         for (const auto& key : (*it).second) {
     602          47 :             mapAddress.erase(key);
     603             :         }
     604          15 :         mapAddressInserted.erase(it);
     605          15 :     }
     606       59430 : }
     607             : 
     608       36890 : void CTxMemPool::addSpentIndex(const CTxMemPoolEntry& entry, const CCoinsViewCache& view)
     609             : {
     610       36890 :     if (!g_spentindex) return;
     611             : 
     612          18 :     LOCK(cs);
     613             : 
     614          18 :     const CTransaction& tx = entry.GetTx();
     615          18 :     std::vector<CSpentIndexKey> inserted;
     616             : 
     617          18 :     uint256 txhash = tx.GetHash();
     618          36 :     for (unsigned int j = 0; j < tx.vin.size(); j++) {
     619          18 :         const CTxIn input = tx.vin[j];
     620          18 :         const Coin& coin = view.AccessCoin(input.prevout);
     621          18 :         const CTxOut &prevout = coin.out;
     622             : 
     623          18 :         AddressType address_type{AddressType::UNKNOWN};
     624          18 :         uint160 address_bytes;
     625             : 
     626          18 :         if (!AddressBytesFromScript(prevout.scriptPubKey, address_type, address_bytes)) {
     627           0 :             continue;
     628             :         }
     629             : 
     630          18 :         CSpentIndexKey key = CSpentIndexKey(input.prevout.hash, input.prevout.n);
     631          18 :         CSpentIndexValue value = CSpentIndexValue(txhash, j, -1, prevout.nValue, address_type, address_bytes);
     632             : 
     633          18 :         mapSpent.insert(std::make_pair(key, value));
     634          18 :         inserted.push_back(key);
     635          18 :     }
     636             : 
     637          18 :     mapSpentInserted.insert(make_pair(txhash, inserted));
     638       36890 : }
     639             : 
     640          24 : bool CTxMemPool::getSpentIndex(const CSpentIndexKey& key, CSpentIndexValue& value) const
     641             : {
     642          24 :     LOCK(cs);
     643          24 :     if (auto it = mapSpent.find(key); it != mapSpent.end()) {
     644           6 :         value = it->second;
     645           6 :         return true;
     646             :     }
     647          18 :     return false;
     648          24 : }
     649             : 
     650       59430 : void CTxMemPool::removeSpentIndex(const uint256 txhash)
     651             : {
     652       59430 :     LOCK(cs);
     653       59430 :     if (auto it = mapSpentInserted.find(txhash); it != mapSpentInserted.end()) {
     654          36 :         for (const auto& key : (*it).second) {
     655          18 :             mapSpent.erase(key);
     656             :         }
     657          18 :         mapSpentInserted.erase(it);
     658          18 :     }
     659       59430 : }
     660             : 
     661       39116 : void CTxMemPool::addUncheckedProTx(CDeterministicMNManager& dmnman, indexed_transaction_set::iterator& newit,
     662             :                                    const CTransaction& tx)
     663             : {
     664       39116 :     const uint256 tx_hash{tx.GetHash()};
     665       39116 :     if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
     666         583 :         auto proTx = *Assert(GetTxPayload<CProRegTx>(tx));
     667         583 :         if (!proTx.collateralOutpoint.hash.IsNull()) {
     668         372 :             mapProTxRefs.emplace(tx_hash, proTx.collateralOutpoint.hash);
     669         372 :         }
     670        1168 :         for (const auto& entry : proTx.netInfo->GetEntries()) {
     671         585 :             mapProTxAddresses.emplace(entry, tx_hash);
     672             :         }
     673         583 :         mapProTxPubKeyIDs.emplace(proTx.keyIDOwner, tx_hash);
     674         583 :         mapProTxBlsPubKeyHashes.emplace(proTx.pubKeyOperator.GetHash(), tx_hash);
     675         583 :         if (!proTx.collateralOutpoint.hash.IsNull()) {
     676         372 :             mapProTxCollaterals.emplace(proTx.collateralOutpoint, tx_hash);
     677         372 :         } else {
     678         211 :             mapProTxCollaterals.emplace(COutPoint(tx_hash, proTx.collateralOutpoint.n), tx_hash);
     679             :         }
     680       39116 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) {
     681         497 :         auto proTx = *Assert(GetTxPayload<CProUpServTx>(tx));
     682         497 :         mapProTxRefs.emplace(proTx.proTxHash, tx_hash);
     683        1022 :         for (const auto& entry : proTx.netInfo->GetEntries()) {
     684         525 :             mapProTxAddresses.emplace(entry, tx_hash);
     685             :         }
     686       38533 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
     687           8 :         auto proTx = *Assert(GetTxPayload<CProUpRegTx>(tx));
     688           8 :         mapProTxRefs.emplace(proTx.proTxHash, tx_hash);
     689           8 :         mapProTxBlsPubKeyHashes.emplace(proTx.pubKeyOperator.GetHash(), tx_hash);
     690           8 :         auto dmn = Assert(dmnman.GetListAtChainTip().GetMN(proTx.proTxHash));
     691           8 :         newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator);
     692           8 :         if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) {
     693           0 :             newit->isKeyChangeProTx = true;
     694           0 :         }
     695       38036 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
     696          21 :         auto proTx = *Assert(GetTxPayload<CProUpRevTx>(tx));
     697          21 :         mapProTxRefs.emplace(proTx.proTxHash, tx_hash);
     698          21 :         auto dmn = Assert(dmnman.GetListAtChainTip().GetMN(proTx.proTxHash));
     699          21 :         newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator);
     700          21 :         if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) {
     701          21 :             newit->isKeyChangeProTx = true;
     702          21 :         }
     703       38028 :     } else if (tx.nType == TRANSACTION_ASSET_UNLOCK) {
     704         228 :         auto assetUnlockTx = *Assert(GetTxPayload<CAssetUnlockPayload>(tx));
     705         228 :         mapAssetUnlockExpiry.insert({tx_hash, assetUnlockTx.getHeightToExpiry()});
     706       38007 :     } else if (tx.nType == TRANSACTION_MNHF_SIGNAL) {
     707         344 :         PrioritiseTransaction(tx_hash, 0.1 * COIN);
     708         344 :     }
     709       39116 : }
     710             : 
     711       59430 : void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
     712             : {
     713             :     // We increment mempool sequence value no matter removal reason
     714             :     // even if not directly reported below.
     715       59430 :     uint64_t mempool_sequence = GetAndIncrementSequence();
     716             : 
     717       59430 :     if (reason != MemPoolRemovalReason::BLOCK) {
     718             :         // Notify clients that a transaction has been removed from the mempool
     719             :         // for any reason except being included in a block. Clients interested
     720             :         // in transactions included in blocks can subscribe to the BlockConnected
     721             :         // notification.
     722         416 :         GetMainSignals().TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence);
     723         416 :     }
     724             : 
     725       59430 :     const uint256 hash = it->GetTx().GetHash();
     726      142790 :     for (const CTxIn& txin : it->GetTx().vin)
     727       83360 :         mapNextTx.erase(txin.prevout);
     728             : 
     729       59430 :     RemoveUnbroadcastTx(hash, true /* add logging because unchecked */ );
     730             : 
     731       59430 :     if (vTxHashes.size() > 1) {
     732       54870 :         vTxHashes[it->vTxHashesIdx] = std::move(vTxHashes.back());
     733       54870 :         vTxHashes[it->vTxHashesIdx].second->vTxHashesIdx = it->vTxHashesIdx;
     734       54870 :         vTxHashes.pop_back();
     735       54870 :         if (vTxHashes.size() * 2 < vTxHashes.capacity())
     736        4088 :             vTxHashes.shrink_to_fit();
     737       54870 :     } else
     738        4560 :         vTxHashes.clear();
     739             : 
     740       59430 :     if (m_dmnman.load(std::memory_order_acquire)) {
     741       34830 :         removeUncheckedProTx(it->GetTx());
     742       34830 :     }
     743             : 
     744       59430 :     totalTxSize -= it->GetTxSize();
     745       59430 :     m_total_fee -= it->GetFee();
     746       59430 :     cachedInnerUsage -= it->DynamicMemoryUsage();
     747       59430 :     cachedInnerUsage -= memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
     748       59430 :     mapTx.erase(it);
     749       59430 :     nTransactionsUpdated++;
     750       59430 :     if (minerPolicyEstimator) {minerPolicyEstimator->removeTx(hash, false);}
     751       59430 :     removeAddressIndex(hash);
     752       59430 :     removeSpentIndex(hash);
     753       59430 : }
     754             : 
     755       34830 : void CTxMemPool::removeUncheckedProTx(const CTransaction& tx)
     756             : {
     757       35868 :     auto eraseProTxRef = [&](const uint256& proTxHash, const uint256& txHash) {
     758        1038 :         auto its = mapProTxRefs.equal_range(proTxHash);
     759        1875 :         for (auto it = its.first; it != its.second;) {
     760         837 :             if (it->second == txHash) {
     761         835 :                 it = mapProTxRefs.erase(it);
     762         835 :             } else {
     763           2 :                 ++it;
     764             :             }
     765             :         }
     766        1038 :     };
     767             : 
     768       34830 :     const uint256 tx_hash{tx.GetHash()};
     769       34830 :     if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
     770         573 :         auto proTx = *Assert(GetTxPayload<CProRegTx>(tx));
     771         573 :         if (!proTx.collateralOutpoint.IsNull()) {
     772         573 :             eraseProTxRef(tx_hash, proTx.collateralOutpoint.hash);
     773         573 :         }
     774        1148 :         for (const auto& entry : proTx.netInfo->GetEntries()) {
     775         575 :             mapProTxAddresses.erase(entry);
     776             :         }
     777         573 :         mapProTxPubKeyIDs.erase(proTx.keyIDOwner);
     778         573 :         mapProTxBlsPubKeyHashes.erase(proTx.pubKeyOperator.GetHash());
     779         573 :         mapProTxCollaterals.erase(proTx.collateralOutpoint);
     780         573 :         mapProTxCollaterals.erase(COutPoint(tx_hash, proTx.collateralOutpoint.n));
     781       34830 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) {
     782         436 :         auto proTx = *Assert(GetTxPayload<CProUpServTx>(tx));
     783         436 :         eraseProTxRef(proTx.proTxHash, tx_hash);
     784         900 :         for (const auto& entry : proTx.netInfo->GetEntries()) {
     785         464 :             mapProTxAddresses.erase(entry);
     786             :         }
     787       34257 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
     788           8 :         auto proTx = *Assert(GetTxPayload<CProUpRegTx>(tx));
     789           8 :         eraseProTxRef(proTx.proTxHash, tx_hash);
     790           8 :         mapProTxBlsPubKeyHashes.erase(proTx.pubKeyOperator.GetHash());
     791       33821 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
     792          21 :         auto proTx = *Assert(GetTxPayload<CProUpRevTx>(tx));
     793          21 :         eraseProTxRef(proTx.proTxHash, tx_hash);
     794       33813 :     } else if (tx.nType == TRANSACTION_ASSET_UNLOCK) {
     795         192 :         mapAssetUnlockExpiry.erase(tx_hash);
     796         192 :     }
     797       34830 : }
     798             : 
     799             : // Calculates descendants of entry that are not already in setDescendants, and adds to
     800             : // setDescendants. Assumes entryit is already a tx in the mempool and CTxMemPoolEntry::m_children
     801             : // is correct for tx and all descendants.
     802             : // Also assumes that if an entry is in setDescendants already, then all
     803             : // in-mempool descendants of it are already in setDescendants as well, so that we
     804             : // can save time by not iterating over those entries.
     805       77522 : void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants) const
     806             : {
     807       77522 :     setEntries stage;
     808       77522 :     if (setDescendants.count(entryit) == 0) {
     809       77522 :         stage.insert(entryit);
     810       77522 :     }
     811             :     // Traverse down the children of entry, only adding children that are not
     812             :     // accounted for in setDescendants already (because those children have either
     813             :     // already been walked, or will be walked in this iteration).
     814     1176365 :     while (!stage.empty()) {
     815     1098843 :         txiter it = *stage.begin();
     816     1098843 :         setDescendants.insert(it);
     817     1098843 :         stage.erase(it);
     818             : 
     819     1098843 :         const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
     820     2161592 :         for (const CTxMemPoolEntry& child : children) {
     821     1062749 :             txiter childiter = mapTx.iterator_to(child);
     822     1062749 :             if (!setDescendants.count(childiter)) {
     823     1041939 :                 stage.insert(childiter);
     824     1041939 :             }
     825             :         }
     826             :     }
     827       77522 : }
     828             : 
     829       36674 : void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReason reason)
     830             : {
     831             :     // Remove transaction from memory pool
     832       36674 :     AssertLockHeld(cs);
     833       36674 :         setEntries txToRemove;
     834       36674 :         txiter origit = mapTx.find(origTx.GetHash());
     835       36674 :         if (origit != mapTx.end()) {
     836         241 :             txToRemove.insert(origit);
     837         241 :         } else {
     838             :             // When recursively removing but origTx isn't in the mempool
     839             :             // be sure to remove any children that are in the pool. This can
     840             :             // happen during chain re-orgs if origTx isn't re-accepted into
     841             :             // the mempool for any reason.
     842       75423 :             for (unsigned int i = 0; i < origTx.vout.size(); i++) {
     843       38990 :                 auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
     844       38990 :                 if (it == mapNextTx.end())
     845       38915 :                     continue;
     846          75 :                 txiter nextit = mapTx.find(it->second->GetHash());
     847          75 :                 assert(nextit != mapTx.end());
     848          75 :                 txToRemove.insert(nextit);
     849          75 :             }
     850             :         }
     851       36674 :         setEntries setAllRemoves;
     852       36990 :         for (txiter it : txToRemove) {
     853         316 :             CalculateDescendants(it, setAllRemoves);
     854             :         }
     855             : 
     856       36674 :         RemoveStaged(setAllRemoves, false, reason);
     857       36674 : }
     858             : 
     859        6481 : void CTxMemPool::removeForReorg(CChain& chain, std::function<bool(txiter)> check_final_and_mature) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
     860             : {
     861             :     // Remove transactions spending a coinbase which are now immature and no-longer-final transactions
     862        6481 :     AssertLockHeld(cs);
     863        6481 :     AssertLockHeld(::cs_main);
     864             : 
     865        6481 :     setEntries txToRemove;
     866        8671 :     for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
     867        2190 :         if (check_final_and_mature(it)) txToRemove.insert(it);
     868        2190 :     }
     869        6481 :     setEntries setAllRemoves;
     870        6516 :     for (txiter it : txToRemove) {
     871          35 :         CalculateDescendants(it, setAllRemoves);
     872             :     }
     873        6481 :     RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG);
     874        8636 :     for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
     875        2155 :         assert(TestLockPointValidity(chain, it->GetLockPoints()));
     876        2155 :     }
     877        6481 : }
     878             : 
     879      558233 : void CTxMemPool::removeConflicts(const CTransaction &tx)
     880             : {
     881             :     // Remove transactions which depend on inputs of tx, recursively
     882      558233 :     AssertLockHeld(cs);
     883      981735 :     for (const CTxIn &txin : tx.vin) {
     884      423502 :         auto it = mapNextTx.find(txin.prevout);
     885      423502 :         if (it != mapNextTx.end()) {
     886         183 :             const CTransaction &txConflict = *it->second;
     887         183 :             if (txConflict != tx)
     888             :             {
     889         183 :                 if (txConflict.nType == TRANSACTION_PROVIDER_REGISTER) {
     890             :                     // Remove all other protxes which refer to this protx
     891             :                     // NOTE: Can't use equal_range here as every call to removeRecursive might invalidate iterators
     892           6 :                     while (true) {
     893           6 :                         auto itPro = mapProTxRefs.find(txConflict.GetHash());
     894           6 :                         if (itPro == mapProTxRefs.end()) {
     895           2 :                             break;
     896             :                         }
     897           4 :                         auto txit = mapTx.find(itPro->second);
     898           4 :                         if (txit != mapTx.end()) {
     899           2 :                             ClearPrioritisation(txit->GetTx().GetHash());
     900           2 :                             removeRecursive(txit->GetTx(), MemPoolRemovalReason::CONFLICT);
     901           2 :                         } else {
     902           2 :                             mapProTxRefs.erase(itPro);
     903             :                         }
     904             :                     }
     905           2 :                 }
     906         183 :                 ClearPrioritisation(txConflict.GetHash());
     907         183 :                 removeRecursive(txConflict, MemPoolRemovalReason::CONFLICT);
     908         183 :             }
     909         183 :         }
     910             :     }
     911      558233 : }
     912             : 
     913        1876 : void CTxMemPool::removeProTxPubKeyConflicts(const CTransaction &tx, const CKeyID &keyId)
     914             : {
     915        1876 :     if (mapProTxPubKeyIDs.count(keyId)) {
     916           0 :         uint256 conflictHash = mapProTxPubKeyIDs[keyId];
     917           0 :         if (conflictHash != tx.GetHash() && mapTx.count(conflictHash)) {
     918           0 :             removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
     919           0 :         }
     920           0 :     }
     921        1876 : }
     922             : 
     923        1983 : void CTxMemPool::removeProTxPubKeyConflicts(const CTransaction &tx, const CBLSLazyPublicKey &pubKey)
     924             : {
     925        1983 :     if (mapProTxBlsPubKeyHashes.count(pubKey.GetHash())) {
     926           0 :         uint256 conflictHash = mapProTxBlsPubKeyHashes[pubKey.GetHash()];
     927           0 :         if (conflictHash != tx.GetHash() && mapTx.count(conflictHash)) {
     928           0 :             removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
     929           0 :         }
     930           0 :     }
     931        1983 : }
     932             : 
     933        1876 : void CTxMemPool::removeProTxCollateralConflicts(const CTransaction &tx, const COutPoint &collateralOutpoint)
     934             : {
     935        1876 :     if (mapProTxCollaterals.count(collateralOutpoint)) {
     936           0 :         uint256 conflictHash = mapProTxCollaterals[collateralOutpoint];
     937           0 :         if (conflictHash != tx.GetHash() && mapTx.count(conflictHash)) {
     938           0 :             removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
     939           0 :         }
     940           0 :     }
     941        1876 : }
     942             : 
     943      533633 : void CTxMemPool::removeProTxSpentCollateralConflicts(const CTransaction &tx)
     944             : {
     945      533633 :     auto dmnman = Assert(m_dmnman.load(std::memory_order_acquire));
     946             : 
     947             :     // Remove TXs that refer to a MN for which the collateral was spent
     948      533823 :     auto removeSpentCollateralConflict = [&](const uint256& proTxHash) EXCLUSIVE_LOCKS_REQUIRED(cs) {
     949             :         // Can't use equal_range here as every call to removeRecursive might invalidate iterators
     950         190 :         AssertLockHeld(cs);
     951         190 :         while (true) {
     952         190 :             auto it = mapProTxRefs.find(proTxHash);
     953         190 :             if (it == mapProTxRefs.end()) {
     954         190 :                 break;
     955             :             }
     956           0 :             auto conflictIt = mapTx.find(it->second);
     957           0 :             if (conflictIt != mapTx.end()) {
     958           0 :                 removeRecursive(conflictIt->GetTx(), MemPoolRemovalReason::CONFLICT);
     959           0 :             } else {
     960             :                 // Should not happen as we track referencing TXs in addUnchecked/removeUnchecked.
     961             :                 // But lets be on the safe side and not run into an endless loop...
     962           0 :                 LogPrint(BCLog::MEMPOOL, "%s: ERROR: found invalid TX ref in mapProTxRefs, proTxHash=%s, txHash=%s\n", __func__, proTxHash.ToString(), it->second.ToString());
     963           0 :                 mapProTxRefs.erase(it);
     964             :             }
     965             :         }
     966         190 :     };
     967      533633 :     auto mnList = dmnman->GetListAtChainTip();
     968      932535 :     for (const auto& in : tx.vin) {
     969      398902 :         auto collateralIt = mapProTxCollaterals.find(in.prevout);
     970      398902 :         if (collateralIt != mapProTxCollaterals.end()) {
     971             :             // These are not yet mined ProRegTxs
     972           0 :             removeSpentCollateralConflict(collateralIt->second);
     973           0 :         }
     974      398902 :         auto dmn = mnList.GetMNByCollateral(in.prevout);
     975      398902 :         if (dmn) {
     976             :             // These are updates referring to a mined ProRegTx
     977         190 :             removeSpentCollateralConflict(dmn->proTxHash);
     978         190 :         }
     979      398902 :     }
     980      533633 : }
     981             : 
     982         164 : void CTxMemPool::removeProTxKeyChangedConflicts(const CTransaction &tx, const uint256& proTxHash, const uint256& newKeyHash)
     983             : {
     984         164 :     std::set<uint256> conflictingTxs;
     985         164 :     for (auto its = mapProTxRefs.equal_range(proTxHash); its.first != its.second; ++its.first) {
     986           0 :         auto txit = mapTx.find(its.first->second);
     987           0 :         if (txit == mapTx.end()) {
     988           0 :             continue;
     989             :         }
     990           0 :         if (txit->validForProTxKey != newKeyHash) {
     991           0 :             conflictingTxs.emplace(txit->GetTx().GetHash());
     992           0 :         }
     993           0 :     }
     994         164 :     for (const auto& txHash : conflictingTxs) {
     995           0 :         auto& tx = mapTx.find(txHash)->GetTx();
     996           0 :         removeRecursive(tx, MemPoolRemovalReason::CONFLICT);
     997             :     }
     998         164 : }
     999             : 
    1000      533633 : void CTxMemPool::removeProTxConflicts(const CTransaction &tx)
    1001             : {
    1002      533633 :     removeProTxSpentCollateralConflicts(tx);
    1003             : 
    1004      533633 :     const uint256 tx_hash{tx.GetHash()};
    1005      533633 :     if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
    1006        1876 :         const auto opt_proTx = GetTxPayload<CProRegTx>(tx);
    1007        1876 :         if (!opt_proTx) {
    1008           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1009           0 :             return;
    1010             :         }
    1011        1876 :         auto& proTx = *opt_proTx;
    1012             : 
    1013        3758 :         for (const auto& entry : proTx.netInfo->GetEntries()) {
    1014        1882 :             if (mapProTxAddresses.count(entry)) {
    1015           0 :                 uint256 conflictHash = mapProTxAddresses[entry];
    1016           0 :                 if (conflictHash != tx_hash && mapTx.count(conflictHash)) {
    1017           0 :                     removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
    1018           0 :                 }
    1019           0 :             }
    1020             :         }
    1021        1876 :         removeProTxPubKeyConflicts(tx, proTx.keyIDOwner);
    1022        1876 :         removeProTxPubKeyConflicts(tx, proTx.pubKeyOperator);
    1023        1876 :         if (!proTx.collateralOutpoint.hash.IsNull()) {
    1024        1227 :             removeProTxCollateralConflicts(tx, proTx.collateralOutpoint);
    1025        1227 :         } else {
    1026         649 :             removeProTxCollateralConflicts(tx, COutPoint(tx_hash, proTx.collateralOutpoint.n));
    1027             :         }
    1028      533633 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) {
    1029        2163 :         const auto opt_proTx = GetTxPayload<CProUpServTx>(tx);
    1030        2163 :         if (!opt_proTx) {
    1031           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1032           0 :             return;
    1033             :         }
    1034             : 
    1035        4410 :         for (const auto& entry : opt_proTx->netInfo->GetEntries()) {
    1036        2247 :             if (mapProTxAddresses.count(entry)) {
    1037           0 :                 uint256 conflictHash = mapProTxAddresses[entry];
    1038           0 :                 if (conflictHash != tx_hash && mapTx.count(conflictHash)) {
    1039           0 :                     removeRecursive(mapTx.find(conflictHash)->GetTx(), MemPoolRemovalReason::CONFLICT);
    1040           0 :                 }
    1041           0 :             }
    1042             :         }
    1043      531757 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
    1044         107 :         const auto opt_proTx = GetTxPayload<CProUpRegTx>(tx);
    1045         107 :         if (!opt_proTx) {
    1046           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1047           0 :             return;
    1048             :         }
    1049             : 
    1050         107 :         removeProTxPubKeyConflicts(tx, opt_proTx->pubKeyOperator);
    1051         107 :         removeProTxKeyChangedConflicts(tx, opt_proTx->proTxHash, ::SerializeHash(opt_proTx->pubKeyOperator));
    1052      529594 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
    1053          57 :         const auto opt_proTx = GetTxPayload<CProUpRevTx>(tx);
    1054          57 :         if (!opt_proTx) {
    1055           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1056           0 :             return;
    1057             :         }
    1058             : 
    1059          57 :         removeProTxKeyChangedConflicts(tx, opt_proTx->proTxHash, ::SerializeHash(CBLSPublicKey()));
    1060          57 :     }
    1061      533633 : }
    1062             : 
    1063             : /**
    1064             :  * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
    1065             :  */
    1066      253734 : void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight)
    1067             : {
    1068      253734 :     AssertLockHeld(cs);
    1069      253734 :     std::vector<const CTxMemPoolEntry*> entries;
    1070      811935 :     for (const auto& tx : vtx)
    1071             :     {
    1072      558201 :         uint256 hash = tx->GetHash();
    1073             : 
    1074      558201 :         indexed_transaction_set::iterator i = mapTx.find(hash);
    1075      558201 :         if (i != mapTx.end())
    1076       59014 :             entries.push_back(&*i);
    1077             :     }
    1078             :     // Before the txs in the new block have been removed from the mempool, update policy estimates
    1079      253734 :     if (minerPolicyEstimator) {minerPolicyEstimator->processBlock(nBlockHeight, entries);}
    1080      811935 :     for (const auto& tx : vtx)
    1081             :     {
    1082      558201 :         txiter it = mapTx.find(tx->GetHash());
    1083      558201 :         if (it != mapTx.end()) {
    1084       59014 :             setEntries stage;
    1085       59014 :             stage.insert(it);
    1086       59014 :             RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
    1087       59014 :         }
    1088      558201 :         removeConflicts(*tx);
    1089      558201 :         if (m_dmnman.load(std::memory_order_acquire)) {
    1090      533601 :             removeProTxConflicts(*tx);
    1091      533601 :         }
    1092      558201 :         ClearPrioritisation(tx->GetHash());
    1093             :     }
    1094      253734 :     lastRollingFeeUpdate = GetTime();
    1095      253734 :     blockSinceLastRollingFeeBump = true;
    1096      253734 : }
    1097             : 
    1098             : /**
    1099             :   * Called when a length of chain is increased. Removes from mempool expired asset-unlock transactions
    1100             :   */
    1101      253064 : void CTxMemPool::removeExpiredAssetUnlock(int nBlockHeight)
    1102             : {
    1103      253064 :     AssertLockHeld(cs);
    1104             :     // items to removed should be firstly collected to independent list,
    1105             :     // because removing items by `removeRecursive` changes the mapAssetUnlockExpiry
    1106      253064 :     std::vector<CTransactionRef> entries;
    1107      255524 :     for (const auto& item: mapAssetUnlockExpiry) {
    1108        2460 :         if (item.second < nBlockHeight) {
    1109          48 :             entries.push_back(get(item.first));
    1110          48 :         }
    1111             :     }
    1112      253112 :     for (const auto& tx : entries) {
    1113          48 :         removeRecursive(*tx, MemPoolRemovalReason::EXPIRY);
    1114             :     }
    1115      253064 : }
    1116             : 
    1117       26676 : void CTxMemPool::_clear()
    1118             : {
    1119       26676 :     vTxHashes.clear();
    1120       26676 :     mapTx.clear();
    1121       26676 :     mapNextTx.clear();
    1122       26676 :     mapProTxAddresses.clear();
    1123       26676 :     mapProTxPubKeyIDs.clear();
    1124       26676 :     totalTxSize = 0;
    1125       26676 :     m_total_fee = 0;
    1126       26676 :     cachedInnerUsage = 0;
    1127       26676 :     lastRollingFeeUpdate = GetTime();
    1128       26676 :     blockSinceLastRollingFeeBump = false;
    1129       26676 :     rollingMinimumFeeRate = 0;
    1130       26676 :     ++nTransactionsUpdated;
    1131       26676 : }
    1132             : 
    1133          12 : void CTxMemPool::clear()
    1134             : {
    1135          12 :     LOCK(cs);
    1136          12 :     _clear();
    1137          12 : }
    1138             : 
    1139      292328 : void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) const
    1140             : {
    1141      292328 :     if (m_check_ratio == 0) return;
    1142             : 
    1143      292314 :     if (GetRand(m_check_ratio) >= 1) return;
    1144             : 
    1145      292314 :     AssertLockHeld(::cs_main);
    1146      292314 :     LOCK(cs);
    1147      292314 :     LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
    1148             : 
    1149      292314 :     uint64_t checkTotal = 0;
    1150      292314 :     CAmount check_total_fee{0};
    1151      292314 :     uint64_t innerUsage = 0;
    1152      292314 :     uint64_t prev_ancestor_count{0};
    1153             : 
    1154      292314 :     CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
    1155             : 
    1156     8314602 :     for (const auto& it : GetSortedDepthAndScore()) {
    1157     8022288 :         checkTotal += it->GetTxSize();
    1158     8022288 :         check_total_fee += it->GetFee();
    1159     8022288 :         innerUsage += it->DynamicMemoryUsage();
    1160     8022288 :         const CTransaction& tx = it->GetTx();
    1161     8022288 :         innerUsage += memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
    1162     8022288 :         CTxMemPoolEntry::Parents setParentCheck;
    1163    19181962 :         for (const CTxIn &txin : tx.vin) {
    1164             :             // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
    1165    11159674 :             indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
    1166    11159674 :             if (it2 != mapTx.end()) {
    1167      168906 :                 const CTransaction& tx2 = it2->GetTx();
    1168      168906 :                 assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
    1169      168906 :                 setParentCheck.insert(*it2);
    1170      168906 :             }
    1171             :             // We are iterating through the mempool entries sorted in order by ancestor count.
    1172             :             // All parents must have been checked before their children and their coins added to
    1173             :             // the mempoolDuplicate coins cache.
    1174    11159674 :             assert(mempoolDuplicate.HaveCoin(txin.prevout));
    1175             :             // Check whether its inputs are marked in mapNextTx.
    1176    11159674 :             auto it3 = mapNextTx.find(txin.prevout);
    1177    11159674 :             assert(it3 != mapNextTx.end());
    1178    11159674 :             assert(it3->first == &txin.prevout);
    1179    11159674 :             assert(it3->second == &tx);
    1180             :         }
    1181     8359326 :         auto comp = [](const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) -> bool {
    1182      337038 :             return a.GetTx().GetHash() == b.GetTx().GetHash();
    1183             :         };
    1184     8022288 :         assert(setParentCheck.size() == it->GetMemPoolParentsConst().size());
    1185     8022288 :         assert(std::equal(setParentCheck.begin(), setParentCheck.end(), it->GetMemPoolParentsConst().begin(), comp));
    1186             :         // Verify ancestor state is correct.
    1187     8022288 :         setEntries setAncestors;
    1188     8022288 :         uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
    1189     8022288 :         std::string dummy;
    1190     8022288 :         CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
    1191     8022288 :         uint64_t nCountCheck = setAncestors.size() + 1;
    1192     8022288 :         uint64_t nSizeCheck = it->GetTxSize();
    1193     8022288 :         CAmount nFeesCheck = it->GetModifiedFee();
    1194     8022288 :         unsigned int nSigOpCheck = it->GetSigOpCount();
    1195             : 
    1196     8285471 :         for (txiter ancestorIt : setAncestors) {
    1197      263183 :             nSizeCheck += ancestorIt->GetTxSize();
    1198      263183 :             nFeesCheck += ancestorIt->GetModifiedFee();
    1199      263183 :             nSigOpCheck += ancestorIt->GetSigOpCount();
    1200             :         }
    1201             : 
    1202     8022288 :         assert(it->GetCountWithAncestors() == nCountCheck);
    1203     8022288 :         assert(it->GetSizeWithAncestors() == nSizeCheck);
    1204     8022288 :         assert(it->GetSigOpCountWithAncestors() == nSigOpCheck);
    1205     8022288 :         assert(it->GetModFeesWithAncestors() == nFeesCheck);
    1206             :         // Sanity check: we are walking in ascending ancestor count order.
    1207     8022288 :         assert(prev_ancestor_count <= it->GetCountWithAncestors());
    1208     8022288 :         prev_ancestor_count = it->GetCountWithAncestors();
    1209             : 
    1210             :         // Check children against mapNextTx
    1211     8022288 :         CTxMemPoolEntry::Children setChildrenCheck;
    1212     8022288 :         auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
    1213     8022288 :         uint64_t child_sizes = 0;
    1214    16172646 :         for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) {
    1215      168906 :             txiter childit = mapTx.find(iter->second->GetHash());
    1216      168906 :             assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
    1217      168906 :             if (setChildrenCheck.insert(*childit).second) {
    1218      168519 :                 child_sizes += childit->GetTxSize();
    1219      168519 :             }
    1220      168906 :         }
    1221     8022288 :         assert(setChildrenCheck.size() == it->GetMemPoolChildrenConst().size());
    1222     8022288 :         assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(), it->GetMemPoolChildrenConst().begin(), comp));
    1223             :         // Also check to make sure size is greater than sum with immediate children.
    1224             :         // just a sanity check, not definitive that this calc is correct...
    1225     8022288 :         assert(it->GetSizeWithDescendants() >= child_sizes + it->GetTxSize());
    1226             : 
    1227     8022288 :         TxValidationState dummy_state; // Not used. CheckTxInputs() should always pass
    1228     8022288 :         CAmount txfee = 0;
    1229     8022288 :         assert(!tx.IsCoinBase());
    1230     8022288 :         assert(Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate, spendheight, txfee));
    1231    19181962 :         for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout);
    1232     8022288 :         AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
    1233     8022288 :     }
    1234    11451988 :     for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
    1235    11159674 :         uint256 hash = it->second->GetHash();
    1236    11159674 :         indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
    1237    11159674 :         const CTransaction& tx = it2->GetTx();
    1238    11159674 :         assert(it2 != mapTx.end());
    1239    11159674 :         assert(&tx == it->second);
    1240    11159674 :     }
    1241             : 
    1242      292314 :     assert(totalTxSize == checkTotal);
    1243      292314 :     assert(m_total_fee == check_total_fee);
    1244      292314 :     assert(innerUsage == cachedInnerUsage);
    1245      292328 : }
    1246             : 
    1247       98609 : bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb)
    1248             : {
    1249             :     /* Return `true` if hasha should be considered sooner than hashb. Namely when:
    1250             :      *   a is not in the mempool, but b is
    1251             :      *   both are in the mempool and a has fewer ancestors than b
    1252             :      *   both are in the mempool and a has a higher score than b
    1253             :      */
    1254       98609 :     LOCK(cs);
    1255       98609 :     indexed_transaction_set::const_iterator j = mapTx.find(hashb);
    1256       98609 :     if (j == mapTx.end()) return false;
    1257       69492 :     indexed_transaction_set::const_iterator i = mapTx.find(hasha);
    1258       69492 :     if (i == mapTx.end()) return true;
    1259       65566 :     uint64_t counta = i->GetCountWithAncestors();
    1260       65566 :     uint64_t countb = j->GetCountWithAncestors();
    1261       65566 :     if (counta == countb) {
    1262       64129 :         return CompareTxMemPoolEntryByScore()(*i, *j);
    1263             :     }
    1264        1437 :     return counta < countb;
    1265       98609 : }
    1266             : 
    1267             : namespace {
    1268             : class DepthAndScoreComparator
    1269             : {
    1270             : public:
    1271    80636883 :     bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b)
    1272             :     {
    1273    80636883 :         uint64_t counta = a->GetCountWithAncestors();
    1274    80636883 :         uint64_t countb = b->GetCountWithAncestors();
    1275    80636883 :         if (counta == countb) {
    1276    80211762 :             return CompareTxMemPoolEntryByScore()(*a, *b);
    1277             :         }
    1278      425121 :         return counta < countb;
    1279    80636883 :     }
    1280             : };
    1281             : } // namespace
    1282             : 
    1283      317269 : std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedDepthAndScore() const
    1284             : {
    1285      317269 :     std::vector<indexed_transaction_set::const_iterator> iters;
    1286      317269 :     AssertLockHeld(cs);
    1287             : 
    1288      317269 :     iters.reserve(mapTx.size());
    1289             : 
    1290     8623640 :     for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
    1291     8306371 :         iters.push_back(mi);
    1292     8306371 :     }
    1293      317269 :     std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
    1294      317269 :     return iters;
    1295      317269 : }
    1296             : 
    1297       22069 : void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) const
    1298             : {
    1299       22069 :     LOCK(cs);
    1300       22069 :     auto iters = GetSortedDepthAndScore();
    1301             : 
    1302       22069 :     vtxid.clear();
    1303       22069 :     vtxid.reserve(mapTx.size());
    1304             : 
    1305      304055 :     for (auto it : iters) {
    1306      281986 :         vtxid.push_back(it->GetTx().GetHash());
    1307             :     }
    1308       22069 : }
    1309             : 
    1310       52001 : static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
    1311       52001 :     return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
    1312           0 : }
    1313             : 
    1314        2886 : std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
    1315             : {
    1316        2886 :     LOCK(cs);
    1317        2886 :     auto iters = GetSortedDepthAndScore();
    1318             : 
    1319        2886 :     std::vector<TxMempoolInfo> ret;
    1320        2886 :     ret.reserve(mapTx.size());
    1321        4983 :     for (auto it : iters) {
    1322        2097 :         ret.push_back(GetInfo(it));
    1323             :     }
    1324             : 
    1325        2886 :     return ret;
    1326        2886 : }
    1327             : 
    1328      349879 : CTransactionRef CTxMemPool::get(const uint256& hash) const
    1329             : {
    1330      349879 :     LOCK(cs);
    1331      349879 :     indexed_transaction_set::const_iterator i = mapTx.find(hash);
    1332      349879 :     if (i == mapTx.end())
    1333      275074 :         return nullptr;
    1334       74805 :     return i->GetSharedTx();
    1335      349879 : }
    1336             : 
    1337       58053 : TxMempoolInfo CTxMemPool::info(const uint256& hash) const
    1338             : {
    1339       58053 :     LOCK(cs);
    1340       58053 :     indexed_transaction_set::const_iterator i = mapTx.find(hash);
    1341       58053 :     if (i == mapTx.end())
    1342        8149 :         return TxMempoolInfo();
    1343       49904 :     return GetInfo(i);
    1344       58053 : }
    1345             : 
    1346       46063 : bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const {
    1347       46063 :     auto dmnman = Assert(m_dmnman.load(std::memory_order_acquire));
    1348             : 
    1349       46063 :     LOCK(cs);
    1350             : 
    1351       46090 :     auto hasKeyChangeInMempool = [&](const uint256& proTxHash) EXCLUSIVE_LOCKS_REQUIRED(cs) {
    1352          27 :         AssertLockHeld(cs);
    1353          27 :         for (auto its = mapProTxRefs.equal_range(proTxHash); its.first != its.second; ++its.first) {
    1354           0 :             auto txit = mapTx.find(its.first->second);
    1355           0 :             if (txit == mapTx.end()) {
    1356           0 :                 continue;
    1357             :             }
    1358           0 :             if (txit->isKeyChangeProTx) {
    1359           0 :                 return true;
    1360             :             }
    1361           0 :         }
    1362          27 :         return false;
    1363          27 :     };
    1364             : 
    1365       46063 :     const uint256 tx_hash{tx.GetHash()};
    1366       46063 :     if (tx.nType == TRANSACTION_PROVIDER_REGISTER) {
    1367        1046 :         const auto opt_proTx = GetTxPayload<CProRegTx>(tx);
    1368        1046 :         if (!opt_proTx) {
    1369           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1370           0 :             return true; // i.e. can't decode payload == conflict
    1371             :         }
    1372        1046 :         auto& proTx = *opt_proTx;
    1373        2150 :         for (const auto& entry : proTx.netInfo->GetEntries()) {
    1374        1104 :             if (mapProTxAddresses.count(entry)) {
    1375           0 :                 return true;
    1376             :             }
    1377             :         }
    1378        1046 :         if (mapProTxPubKeyIDs.count(proTx.keyIDOwner) || mapProTxBlsPubKeyHashes.count(proTx.pubKeyOperator.GetHash())) {
    1379           0 :             return true;
    1380             :         }
    1381        1046 :         if (!proTx.collateralOutpoint.hash.IsNull()) {
    1382         640 :             if (mapProTxCollaterals.count(proTx.collateralOutpoint)) {
    1383             :                 // there is another ProRegTx that refers to the same collateral
    1384           2 :                 return true;
    1385             :             }
    1386         638 :             if (mapNextTx.count(proTx.collateralOutpoint)) {
    1387             :                 // there is another tx that spends the collateral
    1388           0 :                 return true;
    1389             :             }
    1390         638 :         }
    1391        1044 :         return false;
    1392       46063 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_SERVICE) {
    1393         872 :         const auto opt_proTx = GetTxPayload<CProUpServTx>(tx);
    1394         872 :         if (!opt_proTx) {
    1395           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1396           0 :             return true; // i.e. can't decode payload == conflict
    1397             :         }
    1398        1820 :         for (const auto& entry : opt_proTx->netInfo->GetEntries()) {
    1399         948 :             auto it = mapProTxAddresses.find(entry);
    1400         948 :             if (it != mapProTxAddresses.end() && it->second != opt_proTx->proTxHash) {
    1401           0 :                 return true;
    1402             :             }
    1403             :         }
    1404       45017 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REGISTRAR) {
    1405          16 :         const auto opt_proTx = GetTxPayload<CProUpRegTx>(tx);
    1406          16 :         if (!opt_proTx) {
    1407           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1408           0 :             return true; // i.e. can't decode payload == conflict
    1409             :         }
    1410          16 :         auto& proTx = *opt_proTx;
    1411             : 
    1412             :         // this method should only be called with validated ProTxs
    1413          16 :         auto dmn = dmnman->GetListAtChainTip().GetMN(proTx.proTxHash);
    1414          16 :         if (!dmn) {
    1415           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Masternode is not in the list, proTxHash: %s\n", __func__, proTx.proTxHash.ToString());
    1416           0 :             return true; // i.e. failed to find validated ProTx == conflict
    1417             :         }
    1418             :         // only allow one operator key change in the mempool
    1419          16 :         if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) {
    1420           0 :             if (hasKeyChangeInMempool(proTx.proTxHash)) {
    1421           0 :                 return true;
    1422             :             }
    1423           0 :         }
    1424             : 
    1425          16 :         auto it = mapProTxBlsPubKeyHashes.find(proTx.pubKeyOperator.GetHash());
    1426          16 :         return it != mapProTxBlsPubKeyHashes.end() && it->second != proTx.proTxHash;
    1427       44145 :     } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) {
    1428          27 :         const auto opt_proTx = GetTxPayload<CProUpRevTx>(tx);
    1429          27 :         if (!opt_proTx) {
    1430           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Invalid transaction payload, tx: %s\n", __func__, tx_hash.ToString());
    1431           0 :             return true; // i.e. can't decode payload == conflict
    1432             :         }
    1433          27 :         auto& proTx = *opt_proTx;
    1434             :         // this method should only be called with validated ProTxs
    1435          27 :         auto dmn = dmnman->GetListAtChainTip().GetMN(proTx.proTxHash);
    1436          27 :         if (!dmn) {
    1437           0 :             LogPrint(BCLog::MEMPOOL, "%s: ERROR: Masternode is not in the list, proTxHash: %s\n", __func__, proTx.proTxHash.ToString());
    1438           0 :             return true; // i.e. failed to find validated ProTx == conflict
    1439             :         }
    1440             :         // only allow one operator key change in the mempool
    1441          27 :         if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) {
    1442          27 :             if (hasKeyChangeInMempool(proTx.proTxHash)) {
    1443           0 :                 return true;
    1444             :             }
    1445          27 :         }
    1446          27 :     }
    1447       45001 :     return false;
    1448       46063 : }
    1449             : 
    1450         447 : void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta)
    1451             : {
    1452             :     {
    1453         447 :         LOCK(cs);
    1454         447 :         CAmount &delta = mapDeltas[hash];
    1455         447 :         delta = SaturatingAdd(delta, nFeeDelta);
    1456         447 :         txiter it = mapTx.find(hash);
    1457         447 :         if (it != mapTx.end()) {
    1458         740 :             mapTx.modify(it, [&nFeeDelta](CTxMemPoolEntry& e) { e.UpdateModifiedFee(nFeeDelta); });
    1459             :             // Now update all ancestors' modified fees with descendants
    1460         370 :             setEntries setAncestors;
    1461         370 :             uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
    1462         370 :             std::string dummy;
    1463         370 :             CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
    1464         416 :             for (txiter ancestorIt : setAncestors) {
    1465          92 :                 mapTx.modify(ancestorIt, [=](CTxMemPoolEntry& e){ e.UpdateDescendantState(0, nFeeDelta, 0);});
    1466             :             }
    1467             :             // Now update all descendants' modified fees with ancestors
    1468         370 :             setEntries setDescendants;
    1469         370 :             CalculateDescendants(it, setDescendants);
    1470         370 :             setDescendants.erase(it);
    1471         424 :             for (txiter descendantIt : setDescendants) {
    1472         108 :                 mapTx.modify(descendantIt, [=](CTxMemPoolEntry& e){ e.UpdateAncestorState(0, nFeeDelta, 0, 0); });
    1473             :             }
    1474         370 :             ++nTransactionsUpdated;
    1475         370 :         }
    1476         447 :     }
    1477         447 :     LogPrint(BCLog::MEMPOOL, "PrioritiseTransaction: %s fee += %s\n", hash.ToString(), FormatMoney(nFeeDelta));
    1478         447 : }
    1479             : 
    1480      109987 : void CTxMemPool::ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const
    1481             : {
    1482      109987 :     AssertLockHeld(cs);
    1483      109987 :     std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
    1484      109987 :     if (pos == mapDeltas.end())
    1485      109853 :         return;
    1486         134 :     const CAmount &delta = pos->second;
    1487         134 :     nFeeDelta += delta;
    1488      109987 : }
    1489             : 
    1490      558387 : void CTxMemPool::ClearPrioritisation(const uint256& hash)
    1491             : {
    1492      558387 :     AssertLockHeld(cs);
    1493      558387 :     mapDeltas.erase(hash);
    1494      558387 : }
    1495             : 
    1496      139216 : const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
    1497             : {
    1498      139216 :     const auto it = mapNextTx.find(prevout);
    1499      139216 :     return it == mapNextTx.end() ? nullptr : it->second;
    1500             : }
    1501             : 
    1502    11473088 : std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const
    1503             : {
    1504    11473088 :     auto it = mapTx.find(txid);
    1505    11473088 :     if (it != mapTx.end()) return it;
    1506    11250755 :     return std::nullopt;
    1507    11473088 : }
    1508             : 
    1509       63716 : CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const
    1510             : {
    1511       63716 :     CTxMemPool::setEntries ret;
    1512      167299 :     for (const auto& h : hashes) {
    1513      103583 :         const auto mi = GetIter(h);
    1514      103583 :         if (mi) ret.insert(*mi);
    1515             :     }
    1516       63716 :     return ret;
    1517       63716 : }
    1518             : 
    1519       35233 : bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
    1520             : {
    1521       97514 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
    1522       65180 :         if (exists(tx.vin[i].prevout.hash))
    1523        2899 :             return false;
    1524       32334 :     return true;
    1525       35233 : }
    1526             : 
    1527      158454 : CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
    1528             : 
    1529      162336 : bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
    1530             :     // Check to see if the inputs are made available by another tx in the package.
    1531             :     // These Coins would not be available in the underlying CoinsView.
    1532      162336 :     if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
    1533        1025 :         coin = it->second;
    1534        1025 :         return true;
    1535             :     }
    1536             : 
    1537             :     // If an entry in the mempool exists, always return that one, as it's guaranteed to never
    1538             :     // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
    1539             :     // transactions. First checking the underlying cache risks returning a pruned entry instead.
    1540      161311 :     CTransactionRef ptx = mempool.get(outpoint.hash);
    1541      161311 :     if (ptx) {
    1542       25256 :         if (outpoint.n < ptx->vout.size()) {
    1543       25256 :             coin = Coin(ptx->vout[outpoint.n], MEMPOOL_HEIGHT, false);
    1544       25256 :             return true;
    1545             :         } else {
    1546           0 :             return false;
    1547             :         }
    1548             :     }
    1549      136055 :     return base->GetCoin(outpoint, coin);
    1550      162336 : }
    1551             : 
    1552        1182 : void CCoinsViewMemPool::PackageAddTransaction(const CTransactionRef& tx)
    1553             : {
    1554        2388 :     for (unsigned int n = 0; n < tx->vout.size(); ++n) {
    1555        1206 :         m_temp_added.emplace(COutPoint(tx->GetHash(), n), Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
    1556        1206 :     }
    1557        1182 : }
    1558             : 
    1559      869301 : size_t CTxMemPool::DynamicMemoryUsage() const {
    1560      869301 :     LOCK(cs);
    1561             :     // Estimate the overhead of mapTx to be 12 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
    1562      869301 :     return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 12 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage;
    1563      869301 : }
    1564             : 
    1565       79533 : void CTxMemPool::RemoveUnbroadcastTx(const uint256& txid, const bool unchecked) {
    1566       79533 :     LOCK(cs);
    1567             : 
    1568       79533 :     if (m_unbroadcast_txids.erase(txid))
    1569             :     {
    1570       15463 :         LogPrint(BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n", txid.GetHex(), (unchecked ? " before confirmation that txn was sent out" : ""));
    1571       15463 :     }
    1572       79533 : }
    1573             : 
    1574      144563 : void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) {
    1575      144563 :     AssertLockHeld(cs);
    1576      144563 :     UpdateForRemoveFromMempool(stage, updateDescendants);
    1577      203993 :     for (txiter it : stage) {
    1578       59430 :         removeUnchecked(it, reason);
    1579             :     }
    1580      144563 : }
    1581             : 
    1582       42380 : int CTxMemPool::Expire(std::chrono::seconds time)
    1583             : {
    1584       42380 :     AssertLockHeld(cs);
    1585       42380 :     auto isman = Assert(m_isman.load(std::memory_order_acquire));
    1586       42380 :     indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin();
    1587       42380 :     setEntries toremove;
    1588       42384 :     while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) {
    1589             :         // locked txes do not expire until mined and have sufficient confirmations
    1590           4 :         if (isman->IsLocked(it->GetTx().GetHash())) {
    1591           0 :             it++;
    1592           0 :             continue;
    1593             :         }
    1594           4 :         toremove.insert(mapTx.project<0>(it));
    1595           4 :         it++;
    1596             :     }
    1597       42380 :     setEntries stage;
    1598       42384 :     for (txiter removeit : toremove) {
    1599           4 :         CalculateDescendants(removeit, stage);
    1600             :     }
    1601       42380 :     RemoveStaged(stage, false, MemPoolRemovalReason::EXPIRY);
    1602       42380 :     return stage.size();
    1603       42380 : }
    1604             : 
    1605       26822 : void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate)
    1606             : {
    1607       26822 :     setEntries setAncestors;
    1608       26822 :     uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
    1609       26822 :     std::string dummy;
    1610       26822 :     CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
    1611       26822 :     return addUnchecked(entry, setAncestors, validFeeEstimate);
    1612       26822 : }
    1613             : 
    1614       22999 : void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)
    1615             : {
    1616       22999 :     AssertLockHeld(cs);
    1617       22999 :     CTxMemPoolEntry::Children s;
    1618       22999 :     if (add && entry->GetMemPoolChildren().insert(*child).second) {
    1619       22924 :         cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
    1620       22999 :     } else if (!add && entry->GetMemPoolChildren().erase(*child)) {
    1621          75 :         cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
    1622          75 :     }
    1623       22999 : }
    1624             : 
    1625       28397 : void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add)
    1626             : {
    1627       28397 :     AssertLockHeld(cs);
    1628       28397 :     CTxMemPoolEntry::Parents s;
    1629       28397 :     if (add && entry->GetMemPoolParents().insert(*parent).second) {
    1630       22924 :         cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
    1631       28397 :     } else if (!add && entry->GetMemPoolParents().erase(*parent)) {
    1632        5473 :         cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
    1633        5473 :     }
    1634       28397 : }
    1635             : 
    1636       61070 : CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
    1637       61070 :     LOCK(cs);
    1638       61070 :     if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
    1639       61065 :         return CFeeRate(llround(rollingMinimumFeeRate));
    1640             : 
    1641           5 :     int64_t time = GetTime();
    1642           5 :     if (time > lastRollingFeeUpdate + 10) {
    1643           5 :         double halflife = ROLLING_FEE_HALFLIFE;
    1644           5 :         if (DynamicMemoryUsage() < sizelimit / 4)
    1645           1 :             halflife /= 4;
    1646           4 :         else if (DynamicMemoryUsage() < sizelimit / 2)
    1647           1 :             halflife /= 2;
    1648             : 
    1649           5 :         rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
    1650           5 :         lastRollingFeeUpdate = time;
    1651             : 
    1652           5 :         if (rollingMinimumFeeRate < (double)incrementalRelayFee.GetFeePerK() / 2) {
    1653           1 :             rollingMinimumFeeRate = 0;
    1654           1 :             return CFeeRate(0);
    1655             :         }
    1656           4 :     }
    1657           4 :     return std::max(CFeeRate(llround(rollingMinimumFeeRate)), incrementalRelayFee);
    1658       61070 : }
    1659             : 
    1660          14 : void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
    1661          14 :     AssertLockHeld(cs);
    1662          14 :     if (rate.GetFeePerK() > rollingMinimumFeeRate) {
    1663          12 :         rollingMinimumFeeRate = rate.GetFeePerK();
    1664          12 :         blockSinceLastRollingFeeBump = false;
    1665          12 :     }
    1666          14 : }
    1667             : 
    1668       42387 : void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining) {
    1669       42387 :     AssertLockHeld(cs);
    1670             : 
    1671       42387 :     unsigned nTxnRemoved = 0;
    1672       42387 :     CFeeRate maxFeeRateRemoved(0);
    1673       42401 :     while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
    1674          14 :         indexed_transaction_set::index<descendant_score>::type::iterator it = mapTx.get<descendant_score>().begin();
    1675             : 
    1676             :         // We set the new mempool min fee to the feerate of the removed set, plus the
    1677             :         // "minimum reasonable fee rate" (ie some value under which we consider txn
    1678             :         // to have 0 fee). This way, we don't allow txn to enter mempool with feerate
    1679             :         // equal to txn which were removed with no block in between.
    1680          14 :         CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
    1681          14 :         removed += incrementalRelayFee;
    1682          14 :         trackPackageRemoved(removed);
    1683          14 :         maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
    1684             : 
    1685          14 :         setEntries stage;
    1686          14 :         CalculateDescendants(mapTx.project<0>(it), stage);
    1687          14 :         nTxnRemoved += stage.size();
    1688             : 
    1689          14 :         std::vector<CTransaction> txn;
    1690          14 :         if (pvNoSpendsRemaining) {
    1691           8 :             txn.reserve(stage.size());
    1692          18 :             for (txiter iter : stage)
    1693          10 :                 txn.push_back(iter->GetTx());
    1694           8 :         }
    1695          14 :         RemoveStaged(stage, false, MemPoolRemovalReason::SIZELIMIT);
    1696          14 :         if (pvNoSpendsRemaining) {
    1697          18 :             for (const CTransaction& tx : txn) {
    1698          20 :                 for (const CTxIn& txin : tx.vin) {
    1699          10 :                     if (exists(txin.prevout.hash)) continue;
    1700           8 :                     pvNoSpendsRemaining->push_back(txin.prevout);
    1701             :                 }
    1702             :             }
    1703           8 :         }
    1704          14 :     }
    1705             : 
    1706       42387 :     if (maxFeeRateRemoved > CFeeRate(0)) {
    1707          12 :         LogPrint(BCLog::MEMPOOL, "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString());
    1708          12 :     }
    1709       42387 : }
    1710             : 
    1711     1050628 : uint64_t CTxMemPool::CalculateDescendantMaximum(txiter entry) const {
    1712             :     // find parent with highest descendant count
    1713     1050628 :     std::vector<txiter> candidates;
    1714     1050628 :     setEntries counted;
    1715     1050628 :     candidates.push_back(entry);
    1716     1050628 :     uint64_t maximum = 0;
    1717     2725625 :     while (candidates.size()) {
    1718     1674997 :         txiter candidate = candidates.back();
    1719     1674997 :         candidates.pop_back();
    1720     1674997 :         if (!counted.insert(candidate).second) continue;
    1721     1674420 :         const CTxMemPoolEntry::Parents& parents = candidate->GetMemPoolParentsConst();
    1722     1674420 :         if (parents.size() == 0) {
    1723     1058541 :             maximum = std::max(maximum, candidate->GetCountWithDescendants());
    1724     1058541 :         } else {
    1725     1240248 :             for (const CTxMemPoolEntry& i : parents) {
    1726      624369 :                 candidates.push_back(mapTx.iterator_to(i));
    1727             :             }
    1728             :         }
    1729             :     }
    1730     1050628 :     return maximum;
    1731     1050628 : }
    1732             : 
    1733     2375553 : void CTxMemPool::GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* const ancestorsize, CAmount* const ancestorfees) const {
    1734     2375553 :     LOCK(cs);
    1735     2375553 :     auto it = mapTx.find(txid);
    1736     2375553 :     ancestors = descendants = 0;
    1737     2375553 :     if (it != mapTx.end()) {
    1738     1050628 :         ancestors = it->GetCountWithAncestors();
    1739     1050628 :         if (ancestorsize) *ancestorsize = it->GetSizeWithAncestors();
    1740     1050628 :         if (ancestorfees) *ancestorfees = it->GetModFeesWithAncestors();
    1741     1050628 :         descendants = CalculateDescendantMaximum(it);
    1742     1050628 :     }
    1743     2375553 : }
    1744             : 
    1745        7127 : bool CTxMemPool::IsLoaded() const
    1746             : {
    1747        7127 :     LOCK(cs);
    1748        7127 :     return m_is_loaded;
    1749        7127 : }
    1750             : 
    1751        2831 : void CTxMemPool::SetIsLoaded(bool loaded)
    1752             : {
    1753        2831 :     LOCK(cs);
    1754        2831 :     m_is_loaded = loaded;
    1755        2831 : }
    1756             : 
    1757             : 
    1758         832 : std::string RemovalReasonToString(const MemPoolRemovalReason& r) noexcept
    1759             : {
    1760         832 :     switch (r) {
    1761         114 :         case MemPoolRemovalReason::EXPIRY: return "expiry";
    1762          39 :         case MemPoolRemovalReason::SIZELIMIT: return "sizelimit";
    1763         213 :         case MemPoolRemovalReason::REORG: return "reorg";
    1764           0 :         case MemPoolRemovalReason::BLOCK: return "block";
    1765         430 :         case MemPoolRemovalReason::CONFLICT: return "conflict";
    1766          38 :         case MemPoolRemovalReason::MANUAL: return "manual";
    1767             :     }
    1768           0 :     assert(false);
    1769         832 : }

Generated by: LCOV version 1.16