LCOV - code coverage report
Current view: top level - src - txmempool.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 805 814 98.9 %
Date: 2021-06-29 14:35:33 Functions: 61 62 98.4 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 290 314 92.4 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
#       2                 :            : // Copyright (c) 2009-2020 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 <consensus/consensus.h>
#       9                 :            : #include <consensus/tx_verify.h>
#      10                 :            : #include <consensus/validation.h>
#      11                 :            : #include <policy/fees.h>
#      12                 :            : #include <policy/policy.h>
#      13                 :            : #include <policy/settings.h>
#      14                 :            : #include <reverse_iterator.h>
#      15                 :            : #include <util/moneystr.h>
#      16                 :            : #include <util/system.h>
#      17                 :            : #include <util/time.h>
#      18                 :            : #include <validation.h>
#      19                 :            : #include <validationinterface.h>
#      20                 :            : 
#      21                 :            : #include <cmath>
#      22                 :            : #include <optional>
#      23                 :            : 
#      24                 :            : CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee,
#      25                 :            :                                  int64_t _nTime, unsigned int _entryHeight,
#      26                 :            :                                  bool _spendsCoinbase, int64_t _sigOpsCost, LockPoints lp)
#      27                 :            :     : tx(_tx), nFee(_nFee), nTxWeight(GetTransactionWeight(*tx)), nUsageSize(RecursiveDynamicUsage(tx)), nTime(_nTime), entryHeight(_entryHeight),
#      28                 :            :     spendsCoinbase(_spendsCoinbase), sigOpCost(_sigOpsCost), lockPoints(lp)
#      29                 :      79943 : {
#      30                 :      79943 :     nCountWithDescendants = 1;
#      31                 :      79943 :     nSizeWithDescendants = GetTxSize();
#      32                 :      79943 :     nModFeesWithDescendants = nFee;
#      33                 :            : 
#      34                 :      79943 :     feeDelta = 0;
#      35                 :            : 
#      36                 :      79943 :     nCountWithAncestors = 1;
#      37                 :      79943 :     nSizeWithAncestors = GetTxSize();
#      38                 :      79943 :     nModFeesWithAncestors = nFee;
#      39                 :      79943 :     nSigOpCostWithAncestors = sigOpCost;
#      40                 :      79943 : }
#      41                 :            : 
#      42                 :            : void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta)
#      43                 :         17 : {
#      44                 :         17 :     nModFeesWithDescendants += newFeeDelta - feeDelta;
#      45                 :         17 :     nModFeesWithAncestors += newFeeDelta - feeDelta;
#      46                 :         17 :     feeDelta = newFeeDelta;
#      47                 :         17 : }
#      48                 :            : 
#      49                 :            : void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp)
#      50                 :          5 : {
#      51                 :          5 :     lockPoints = lp;
#      52                 :          5 : }
#      53                 :            : 
#      54                 :            : size_t CTxMemPoolEntry::GetTxSize() const
#      55                 :  177670885 : {
#      56                 :  177670885 :     return GetVirtualTransactionSize(nTxWeight, sigOpCost);
#      57                 :  177670885 : }
#      58                 :            : 
#      59                 :            : // Update the given tx for any in-mempool descendants.
#      60                 :            : // Assumes that CTxMemPool::m_children is correct for the given tx and all
#      61                 :            : // descendants.
#      62                 :            : void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap &cachedDescendants, const std::set<uint256> &setExclude)
#      63                 :        293 : {
#      64                 :        293 :     CTxMemPoolEntry::Children stageEntries, descendants;
#      65                 :        293 :     stageEntries = updateIt->GetMemPoolChildrenConst();
#      66                 :            : 
#      67         [ +  + ]:       5326 :     while (!stageEntries.empty()) {
#      68                 :       5033 :         const CTxMemPoolEntry& descendant = *stageEntries.begin();
#      69                 :       5033 :         descendants.insert(descendant);
#      70                 :       5033 :         stageEntries.erase(descendant);
#      71                 :       5033 :         const CTxMemPoolEntry::Children& children = descendant.GetMemPoolChildrenConst();
#      72         [ +  + ]:     159712 :         for (const CTxMemPoolEntry& childEntry : children) {
#      73                 :     159712 :             cacheMap::iterator cacheIt = cachedDescendants.find(mapTx.iterator_to(childEntry));
#      74         [ +  + ]:     159712 :             if (cacheIt != cachedDescendants.end()) {
#      75                 :            :                 // We've already calculated this one, just add the entries for this set
#      76                 :            :                 // but don't traverse again.
#      77         [ +  + ]:     345005 :                 for (txiter cacheEntry : cacheIt->second) {
#      78                 :     345005 :                     descendants.insert(*cacheEntry);
#      79                 :     345005 :                 }
#      80         [ +  + ]:     152807 :             } else if (!descendants.count(childEntry)) {
#      81                 :            :                 // Schedule for later processing
#      82                 :      15150 :                 stageEntries.insert(childEntry);
#      83                 :      15150 :             }
#      84                 :     159712 :         }
#      85                 :       5033 :     }
#      86                 :            :     // descendants now contains all in-mempool descendants of updateIt.
#      87                 :            :     // Update and add to cached descendant map
#      88                 :        293 :     int64_t modifySize = 0;
#      89                 :        293 :     CAmount modifyFee = 0;
#      90                 :        293 :     int64_t modifyCount = 0;
#      91         [ +  + ]:       5038 :     for (const CTxMemPoolEntry& descendant : descendants) {
#      92         [ +  + ]:       5038 :         if (!setExclude.count(descendant.GetTx().GetHash())) {
#      93                 :       3767 :             modifySize += descendant.GetTxSize();
#      94                 :       3767 :             modifyFee += descendant.GetModifiedFee();
#      95                 :       3767 :             modifyCount++;
#      96                 :       3767 :             cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant));
#      97                 :            :             // Update ancestor state for each descendant
#      98                 :       3767 :             mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost()));
#      99                 :       3767 :         }
#     100                 :       5038 :     }
#     101                 :        293 :     mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount));
#     102                 :        293 : }
#     103                 :            : 
#     104                 :            : // vHashesToUpdate is the set of transaction hashes from a disconnected block
#     105                 :            : // which has been re-added to the mempool.
#     106                 :            : // for each entry, look for descendants that are outside vHashesToUpdate, and
#     107                 :            : // add fee/size information for such descendants to the parent.
#     108                 :            : // for each such descendant, also update the ancestor state to include the parent.
#     109                 :            : void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate)
#     110                 :       2040 : {
#     111                 :       2040 :     AssertLockHeld(cs);
#     112                 :            :     // For each entry in vHashesToUpdate, store the set of in-mempool, but not
#     113                 :            :     // in-vHashesToUpdate transactions, so that we don't have to recalculate
#     114                 :            :     // descendants when we come across a previously seen entry.
#     115                 :       2040 :     cacheMap mapMemPoolDescendantsToUpdate;
#     116                 :            : 
#     117                 :            :     // Use a set for lookups into vHashesToUpdate (these entries are already
#     118                 :            :     // accounted for in the state of their ancestors)
#     119                 :       2040 :     std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
#     120                 :            : 
#     121                 :            :     // Iterate in reverse, so that whenever we are looking at a transaction
#     122                 :            :     // we are sure that all in-mempool descendants have already been processed.
#     123                 :            :     // This maximizes the benefit of the descendant cache and guarantees that
#     124                 :            :     // CTxMemPool::m_children will be updated, an assumption made in
#     125                 :            :     // UpdateForDescendants.
#     126         [ +  + ]:       2040 :     for (const uint256 &hash : reverse_iterate(vHashesToUpdate)) {
#     127                 :            :         // calculate children from mapNextTx
#     128                 :        293 :         txiter it = mapTx.find(hash);
#     129         [ -  + ]:        293 :         if (it == mapTx.end()) {
#     130                 :          0 :             continue;
#     131                 :          0 :         }
#     132                 :        293 :         auto iter = mapNextTx.lower_bound(COutPoint(hash, 0));
#     133                 :            :         // First calculate the children, and update CTxMemPool::m_children to
#     134                 :            :         // include them, and update their CTxMemPoolEntry::m_parents to include this tx.
#     135                 :            :         // we cache the in-mempool children to avoid duplicate updates
#     136                 :        293 :         {
#     137                 :        293 :             WITH_FRESH_EPOCH(m_epoch);
#     138 [ +  + ][ +  + ]:       5026 :             for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
#                 [ +  + ]
#     139                 :       4733 :                 const uint256 &childHash = iter->second->GetHash();
#     140                 :       4733 :                 txiter childIter = mapTx.find(childHash);
#     141                 :       4733 :                 assert(childIter != mapTx.end());
#     142                 :            :                 // We can skip updating entries we've encountered before or that
#     143                 :            :                 // are in the block (which are already accounted for).
#     144 [ +  + ][ +  + ]:       4733 :                 if (!visited(childIter) && !setAlreadyIncluded.count(childHash)) {
#     145                 :       3761 :                     UpdateChild(it, childIter, true);
#     146                 :       3761 :                     UpdateParent(childIter, it, true);
#     147                 :       3761 :                 }
#     148                 :       4733 :             }
#     149                 :        293 :         } // release epoch guard for UpdateForDescendants
#     150                 :        293 :         UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded);
#     151                 :        293 :     }
#     152                 :       2040 : }
#     153                 :            : 
#     154                 :            : bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) const
#     155                 :    5426336 : {
#     156                 :    5426336 :     CTxMemPoolEntry::Parents staged_ancestors;
#     157                 :    5426336 :     const CTransaction &tx = entry.GetTx();
#     158                 :            : 
#     159         [ +  + ]:    5426336 :     if (fSearchForParents) {
#     160                 :            :         // Get parents of this transaction that are in the mempool
#     161                 :            :         // GetMemPoolParents() is only valid for entries in the mempool, so we
#     162                 :            :         // iterate mapTx to find parents.
#     163         [ +  + ]:   12961300 :         for (unsigned int i = 0; i < tx.vin.size(); i++) {
#     164                 :    7655210 :             std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
#     165         [ +  + ]:    7655210 :             if (piter) {
#     166                 :      39998 :                 staged_ancestors.insert(**piter);
#     167         [ +  + ]:      39998 :                 if (staged_ancestors.size() + 1 > limitAncestorCount) {
#     168                 :          1 :                     errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
#     169                 :          1 :                     return false;
#     170                 :          1 :                 }
#     171                 :      39998 :             }
#     172                 :    7655210 :         }
#     173                 :    5306091 :     } else {
#     174                 :            :         // If we're not searching for parents, we require this to be an
#     175                 :            :         // entry in the mempool already.
#     176                 :     120245 :         txiter it = mapTx.iterator_to(entry);
#     177                 :     120245 :         staged_ancestors = it->GetMemPoolParentsConst();
#     178                 :     120245 :     }
#     179                 :            : 
#     180                 :    5426336 :     size_t totalSizeWithAncestors = entry.GetTxSize();
#     181                 :            : 
#     182         [ +  + ]:    9524932 :     while (!staged_ancestors.empty()) {
#     183                 :    4098712 :         const CTxMemPoolEntry& stage = staged_ancestors.begin()->get();
#     184                 :    4098712 :         txiter stageit = mapTx.iterator_to(stage);
#     185                 :            : 
#     186                 :    4098712 :         setAncestors.insert(stageit);
#     187                 :    4098712 :         staged_ancestors.erase(stage);
#     188                 :    4098712 :         totalSizeWithAncestors += stageit->GetTxSize();
#     189                 :            : 
#     190         [ +  + ]:    4098712 :         if (stageit->GetSizeWithDescendants() + entry.GetTxSize() > limitDescendantSize) {
#     191                 :         19 :             errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize);
#     192                 :         19 :             return false;
#     193         [ +  + ]:    4098693 :         } else if (stageit->GetCountWithDescendants() + 1 > limitDescendantCount) {
#     194                 :         46 :             errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount);
#     195                 :         46 :             return false;
#     196         [ -  + ]:    4098647 :         } else if (totalSizeWithAncestors > limitAncestorSize) {
#     197                 :          0 :             errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize);
#     198                 :          0 :             return false;
#     199                 :          0 :         }
#     200                 :            : 
#     201                 :    4098647 :         const CTxMemPoolEntry::Parents& parents = stageit->GetMemPoolParentsConst();
#     202         [ +  + ]:   66837719 :         for (const CTxMemPoolEntry& parent : parents) {
#     203                 :   66837719 :             txiter parent_it = mapTx.iterator_to(parent);
#     204                 :            : 
#     205                 :            :             // If this is a new ancestor, add it.
#     206         [ +  + ]:   66837719 :             if (setAncestors.count(parent_it) == 0) {
#     207                 :   35565947 :                 staged_ancestors.insert(parent);
#     208                 :   35565947 :             }
#     209         [ +  + ]:   66837719 :             if (staged_ancestors.size() + setAncestors.size() + 1 > limitAncestorCount) {
#     210                 :         50 :                 errString = strprintf("too many unconfirmed ancestors [limit: %u]", limitAncestorCount);
#     211                 :         50 :                 return false;
#     212                 :         50 :             }
#     213                 :   66837719 :         }
#     214                 :    4098647 :     }
#     215                 :            : 
#     216                 :    5426335 :     return true;
#     217                 :    5426335 : }
#     218                 :            : 
#     219                 :            : void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors)
#     220                 :     142389 : {
#     221                 :     142389 :     CTxMemPoolEntry::Parents parents = it->GetMemPoolParents();
#     222                 :            :     // add or remove this tx as a child of each parent
#     223         [ +  + ]:     142389 :     for (const CTxMemPoolEntry& parent : parents) {
#     224                 :       8530 :         UpdateChild(mapTx.iterator_to(parent), it, add);
#     225                 :       8530 :     }
#     226         [ +  + ]:     142389 :     const int64_t updateCount = (add ? 1 : -1);
#     227                 :     142389 :     const int64_t updateSize = updateCount * it->GetTxSize();
#     228                 :     142389 :     const CAmount updateFee = updateCount * it->GetModifiedFee();
#     229         [ +  + ]:    2028705 :     for (txiter ancestorIt : setAncestors) {
#     230                 :    2028705 :         mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount));
#     231                 :    2028705 :     }
#     232                 :     142389 : }
#     233                 :            : 
#     234                 :            : void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncestors)
#     235                 :      73755 : {
#     236                 :      73755 :     int64_t updateCount = setAncestors.size();
#     237                 :      73755 :     int64_t updateSize = 0;
#     238                 :      73755 :     CAmount updateFee = 0;
#     239                 :      73755 :     int64_t updateSigOpsCost = 0;
#     240         [ +  + ]:    2027071 :     for (txiter ancestorIt : setAncestors) {
#     241                 :    2027071 :         updateSize += ancestorIt->GetTxSize();
#     242                 :    2027071 :         updateFee += ancestorIt->GetModifiedFee();
#     243                 :    2027071 :         updateSigOpsCost += ancestorIt->GetSigOpCost();
#     244                 :    2027071 :     }
#     245                 :      73755 :     mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost));
#     246                 :      73755 : }
#     247                 :            : 
#     248                 :            : void CTxMemPool::UpdateChildrenForRemoval(txiter it)
#     249                 :      68634 : {
#     250                 :      68634 :     const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
#     251         [ +  + ]:      68634 :     for (const CTxMemPoolEntry& updateIt : children) {
#     252                 :       2279 :         UpdateParent(mapTx.iterator_to(updateIt), it, false);
#     253                 :       2279 :     }
#     254                 :      68634 : }
#     255                 :            : 
#     256                 :            : void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants)
#     257                 :     122737 : {
#     258                 :            :     // For each entry, walk back all ancestors and decrement size associated with this
#     259                 :            :     // transaction
#     260                 :     122737 :     const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     261         [ +  + ]:     122737 :     if (updateDescendants) {
#     262                 :            :         // updateDescendants should be true whenever we're not recursively
#     263                 :            :         // removing a tx and all its descendants, eg when a transaction is
#     264                 :            :         // confirmed in a block.
#     265                 :            :         // Here we only update statistics and not data in CTxMemPool::Parents
#     266                 :            :         // and CTxMemPoolEntry::Children (which we need to preserve until we're
#     267                 :            :         // finished with all operations that need to traverse the mempool).
#     268         [ +  + ]:      67999 :         for (txiter removeIt : entriesToRemove) {
#     269                 :      67999 :             setEntries setDescendants;
#     270                 :      67999 :             CalculateDescendants(removeIt, setDescendants);
#     271                 :      67999 :             setDescendants.erase(removeIt); // don't update state for self
#     272                 :      67999 :             int64_t modifySize = -((int64_t)removeIt->GetTxSize());
#     273                 :      67999 :             CAmount modifyFee = -removeIt->GetModifiedFee();
#     274                 :      67999 :             int modifySigOps = -removeIt->GetSigOpCost();
#     275         [ +  + ]:      67999 :             for (txiter dit : setDescendants) {
#     276                 :       5411 :                 mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps));
#     277                 :       5411 :             }
#     278                 :      67999 :         }
#     279                 :      67999 :     }
#     280         [ +  + ]:     122737 :     for (txiter removeIt : entriesToRemove) {
#     281                 :      68634 :         setEntries setAncestors;
#     282                 :      68634 :         const CTxMemPoolEntry &entry = *removeIt;
#     283                 :      68634 :         std::string dummy;
#     284                 :            :         // Since this is a tx that is already in the mempool, we can call CMPA
#     285                 :            :         // with fSearchForParents = false.  If the mempool is in a consistent
#     286                 :            :         // state, then using true or false should both be correct, though false
#     287                 :            :         // should be a bit faster.
#     288                 :            :         // However, if we happen to be in the middle of processing a reorg, then
#     289                 :            :         // the mempool can be in an inconsistent state.  In this case, the set
#     290                 :            :         // of ancestors reachable via GetMemPoolParents()/GetMemPoolChildren()
#     291                 :            :         // will be the same as the set of ancestors whose packages include this
#     292                 :            :         // transaction, because when we add a new transaction to the mempool in
#     293                 :            :         // addUnchecked(), we assume it has no children, and in the case of a
#     294                 :            :         // reorg where that assumption is false, the in-mempool children aren't
#     295                 :            :         // linked to the in-block tx's until UpdateTransactionsFromBlock() is
#     296                 :            :         // called.
#     297                 :            :         // So if we're being called during a reorg, ie before
#     298                 :            :         // UpdateTransactionsFromBlock() has been called, then
#     299                 :            :         // GetMemPoolParents()/GetMemPoolChildren() will differ from the set of
#     300                 :            :         // mempool parents we'd calculate by searching, and it's important that
#     301                 :            :         // we use the cached notion of ancestor transactions as the set of
#     302                 :            :         // things to update for removal.
#     303                 :      68634 :         CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
#     304                 :            :         // Note that UpdateAncestorsOf severs the child links that point to
#     305                 :            :         // removeIt in the entries for the parents of removeIt.
#     306                 :      68634 :         UpdateAncestorsOf(false, removeIt, setAncestors);
#     307                 :      68634 :     }
#     308                 :            :     // After updating all the ancestor sizes, we can now sever the link between each
#     309                 :            :     // transaction being removed and any mempool children (ie, update CTxMemPoolEntry::m_parents
#     310                 :            :     // for each direct child of a transaction being removed).
#     311         [ +  + ]:     122737 :     for (txiter removeIt : entriesToRemove) {
#     312                 :      68634 :         UpdateChildrenForRemoval(removeIt);
#     313                 :      68634 :     }
#     314                 :     122737 : }
#     315                 :            : 
#     316                 :            : void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
#     317                 :    2029023 : {
#     318                 :    2029023 :     nSizeWithDescendants += modifySize;
#     319                 :    2029023 :     assert(int64_t(nSizeWithDescendants) > 0);
#     320                 :    2029023 :     nModFeesWithDescendants += modifyFee;
#     321                 :    2029023 :     nCountWithDescendants += modifyCount;
#     322                 :    2029023 :     assert(int64_t(nCountWithDescendants) > 0);
#     323                 :    2029023 : }
#     324                 :            : 
#     325                 :            : void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
#     326                 :      82981 : {
#     327                 :      82981 :     nSizeWithAncestors += modifySize;
#     328                 :      82981 :     assert(int64_t(nSizeWithAncestors) > 0);
#     329                 :      82981 :     nModFeesWithAncestors += modifyFee;
#     330                 :      82981 :     nCountWithAncestors += modifyCount;
#     331                 :      82981 :     assert(int64_t(nCountWithAncestors) > 0);
#     332                 :      82981 :     nSigOpCostWithAncestors += modifySigOps;
#     333                 :      82981 :     assert(int(nSigOpCostWithAncestors) >= 0);
#     334                 :      82981 : }
#     335                 :            : 
#     336                 :            : CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
#     337                 :            :     : m_check_ratio(check_ratio), minerPolicyEstimator(estimator)
#     338                 :       4825 : {
#     339                 :       4825 :     _clear(); //lock free clear
#     340                 :       4825 : }
#     341                 :            : 
#     342                 :            : bool CTxMemPool::isSpent(const COutPoint& outpoint) const
#     343                 :       4989 : {
#     344                 :       4989 :     LOCK(cs);
#     345                 :       4989 :     return mapNextTx.count(outpoint);
#     346                 :       4989 : }
#     347                 :            : 
#     348                 :            : unsigned int CTxMemPool::GetTransactionsUpdated() const
#     349                 :         54 : {
#     350                 :         54 :     return nTransactionsUpdated;
#     351                 :         54 : }
#     352                 :            : 
#     353                 :            : void CTxMemPool::AddTransactionsUpdated(unsigned int n)
#     354                 :      73513 : {
#     355                 :      73513 :     nTransactionsUpdated += n;
#     356                 :      73513 : }
#     357                 :            : 
#     358                 :            : void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
#     359                 :      73755 : {
#     360                 :            :     // Add to memory pool without checking anything.
#     361                 :            :     // Used by AcceptToMemoryPool(), which DOES do
#     362                 :            :     // all the appropriate checks.
#     363                 :      73755 :     indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
#     364                 :            : 
#     365                 :            :     // Update transaction for any feeDelta created by PrioritiseTransaction
#     366                 :            :     // TODO: refactor so that the fee delta is calculated before inserting
#     367                 :            :     // into mapTx.
#     368                 :      73755 :     CAmount delta{0};
#     369                 :      73755 :     ApplyDelta(entry.GetTx().GetHash(), delta);
#     370         [ +  + ]:      73755 :     if (delta) {
#     371                 :          8 :             mapTx.modify(newit, update_fee_delta(delta));
#     372                 :          8 :     }
#     373                 :            : 
#     374                 :            :     // Update cachedInnerUsage to include contained transaction's usage.
#     375                 :            :     // (When we update the entry for in-mempool parents, memory usage will be
#     376                 :            :     // further updated.)
#     377                 :      73755 :     cachedInnerUsage += entry.DynamicMemoryUsage();
#     378                 :            : 
#     379                 :      73755 :     const CTransaction& tx = newit->GetTx();
#     380                 :      73755 :     std::set<uint256> setParentTransactions;
#     381         [ +  + ]:     166864 :     for (unsigned int i = 0; i < tx.vin.size(); i++) {
#     382                 :      93109 :         mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, &tx));
#     383                 :      93109 :         setParentTransactions.insert(tx.vin[i].prevout.hash);
#     384                 :      93109 :     }
#     385                 :            :     // Don't bother worrying about child transactions of this one.
#     386                 :            :     // Normal case of a new transaction arriving is that there can't be any
#     387                 :            :     // children, because such children would be orphans.
#     388                 :            :     // An exception to that is if a transaction enters that used to be in a block.
#     389                 :            :     // In that case, our disconnect block logic will call UpdateTransactionsFromBlock
#     390                 :            :     // to clean up the mess we're leaving here.
#     391                 :            : 
#     392                 :            :     // Update ancestors with information about this tx
#     393         [ +  + ]:      73755 :     for (const auto& pit : GetIterSet(setParentTransactions)) {
#     394                 :       8223 :             UpdateParent(newit, pit, true);
#     395                 :       8223 :     }
#     396                 :      73755 :     UpdateAncestorsOf(true, newit, setAncestors);
#     397                 :      73755 :     UpdateEntryForAncestors(newit, setAncestors);
#     398                 :            : 
#     399                 :      73755 :     nTransactionsUpdated++;
#     400                 :      73755 :     totalTxSize += entry.GetTxSize();
#     401                 :      73755 :     m_total_fee += entry.GetFee();
#     402         [ +  + ]:      73755 :     if (minerPolicyEstimator) {
#     403                 :      73631 :         minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
#     404                 :      73631 :     }
#     405                 :            : 
#     406                 :      73755 :     vTxHashes.emplace_back(tx.GetWitnessHash(), newit);
#     407                 :      73755 :     newit->vTxHashesIdx = vTxHashes.size() - 1;
#     408                 :      73755 : }
#     409                 :            : 
#     410                 :            : void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
#     411                 :      68634 : {
#     412                 :            :     // We increment mempool sequence value no matter removal reason
#     413                 :            :     // even if not directly reported below.
#     414                 :      68634 :     uint64_t mempool_sequence = GetAndIncrementSequence();
#     415                 :            : 
#     416         [ +  + ]:      68634 :     if (reason != MemPoolRemovalReason::BLOCK) {
#     417                 :            :         // Notify clients that a transaction has been removed from the mempool
#     418                 :            :         // for any reason except being included in a block. Clients interested
#     419                 :            :         // in transactions included in blocks can subscribe to the BlockConnected
#     420                 :            :         // notification.
#     421                 :        635 :         GetMainSignals().TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence);
#     422                 :        635 :     }
#     423                 :            : 
#     424                 :      68634 :     const uint256 hash = it->GetTx().GetHash();
#     425         [ +  + ]:      68634 :     for (const CTxIn& txin : it->GetTx().vin)
#     426                 :      81808 :         mapNextTx.erase(txin.prevout);
#     427                 :            : 
#     428                 :      68634 :     RemoveUnbroadcastTx(hash, true /* add logging because unchecked */ );
#     429                 :            : 
#     430         [ +  + ]:      68634 :     if (vTxHashes.size() > 1) {
#     431                 :      66274 :         vTxHashes[it->vTxHashesIdx] = std::move(vTxHashes.back());
#     432                 :      66274 :         vTxHashes[it->vTxHashesIdx].second->vTxHashesIdx = it->vTxHashesIdx;
#     433                 :      66274 :         vTxHashes.pop_back();
#     434         [ +  + ]:      66274 :         if (vTxHashes.size() * 2 < vTxHashes.capacity())
#     435                 :       5043 :             vTxHashes.shrink_to_fit();
#     436                 :      66274 :     } else
#     437                 :       2360 :         vTxHashes.clear();
#     438                 :            : 
#     439                 :      68634 :     totalTxSize -= it->GetTxSize();
#     440                 :      68634 :     m_total_fee -= it->GetFee();
#     441                 :      68634 :     cachedInnerUsage -= it->DynamicMemoryUsage();
#     442                 :      68634 :     cachedInnerUsage -= memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
#     443                 :      68634 :     mapTx.erase(it);
#     444                 :      68634 :     nTransactionsUpdated++;
#     445         [ +  + ]:      68634 :     if (minerPolicyEstimator) {minerPolicyEstimator->removeTx(hash, false);}
#     446                 :      68634 : }
#     447                 :            : 
#     448                 :            : // Calculates descendants of entry that are not already in setDescendants, and adds to
#     449                 :            : // setDescendants. Assumes entryit is already a tx in the mempool and CTxMemPoolEntry::m_children
#     450                 :            : // is correct for tx and all descendants.
#     451                 :            : // Also assumes that if an entry is in setDescendants already, then all
#     452                 :            : // in-mempool descendants of it are already in setDescendants as well, so that we
#     453                 :            : // can save time by not iterating over those entries.
#     454                 :            : void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants) const
#     455                 :      82136 : {
#     456                 :      82136 :     setEntries stage;
#     457         [ +  - ]:      82136 :     if (setDescendants.count(entryit) == 0) {
#     458                 :      82136 :         stage.insert(entryit);
#     459                 :      82136 :     }
#     460                 :            :     // Traverse down the children of entry, only adding children that are not
#     461                 :            :     // accounted for in setDescendants already (because those children have either
#     462                 :            :     // already been walked, or will be walked in this iteration).
#     463         [ +  + ]:    2193186 :     while (!stage.empty()) {
#     464                 :    2111050 :         txiter it = *stage.begin();
#     465                 :    2111050 :         setDescendants.insert(it);
#     466                 :    2111050 :         stage.erase(it);
#     467                 :            : 
#     468                 :    2111050 :         const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
#     469         [ +  + ]:    2111050 :         for (const CTxMemPoolEntry& child : children) {
#     470                 :    2042724 :             txiter childiter = mapTx.iterator_to(child);
#     471         [ +  + ]:    2042724 :             if (!setDescendants.count(childiter)) {
#     472                 :    2035194 :                 stage.insert(childiter);
#     473                 :    2035194 :             }
#     474                 :    2042724 :         }
#     475                 :    2111050 :     }
#     476                 :      82136 : }
#     477                 :            : 
#     478                 :            : void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReason reason)
#     479                 :      10659 : {
#     480                 :            :     // Remove transaction from memory pool
#     481                 :      10659 :     AssertLockHeld(cs);
#     482                 :      10659 :         setEntries txToRemove;
#     483                 :      10659 :         txiter origit = mapTx.find(origTx.GetHash());
#     484         [ +  + ]:      10659 :         if (origit != mapTx.end()) {
#     485                 :         68 :             txToRemove.insert(origit);
#     486                 :      10591 :         } else {
#     487                 :            :             // When recursively removing but origTx isn't in the mempool
#     488                 :            :             // be sure to remove any children that are in the pool. This can
#     489                 :            :             // happen during chain re-orgs if origTx isn't re-accepted into
#     490                 :            :             // the mempool for any reason.
#     491         [ +  + ]:      25612 :             for (unsigned int i = 0; i < origTx.vout.size(); i++) {
#     492                 :      15021 :                 auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
#     493         [ +  + ]:      15021 :                 if (it == mapNextTx.end())
#     494                 :      14947 :                     continue;
#     495                 :         74 :                 txiter nextit = mapTx.find(it->second->GetHash());
#     496                 :         74 :                 assert(nextit != mapTx.end());
#     497                 :         74 :                 txToRemove.insert(nextit);
#     498                 :         74 :             }
#     499                 :      10591 :         }
#     500                 :      10659 :         setEntries setAllRemoves;
#     501         [ +  + ]:      10659 :         for (txiter it : txToRemove) {
#     502                 :        142 :             CalculateDescendants(it, setAllRemoves);
#     503                 :        142 :         }
#     504                 :            : 
#     505                 :      10659 :         RemoveStaged(setAllRemoves, false, reason);
#     506                 :      10659 : }
#     507                 :            : 
#     508                 :            : void CTxMemPool::removeForReorg(CChainState& active_chainstate, int flags)
#     509                 :       2040 : {
#     510                 :            :     // Remove transactions spending a coinbase which are now immature and no-longer-final transactions
#     511                 :       2040 :     AssertLockHeld(cs);
#     512                 :       2040 :     setEntries txToRemove;
#     513         [ +  + ]:       2742 :     for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
#     514                 :        702 :         const CTransaction& tx = it->GetTx();
#     515                 :        702 :         LockPoints lp = it->GetLockPoints();
#     516                 :        702 :         assert(std::addressof(::ChainstateActive()) == std::addressof(active_chainstate));
#     517                 :        702 :         bool validLP =  TestLockPointValidity(active_chainstate.m_chain, &lp);
#     518                 :        702 :         CCoinsViewMemPool viewMempool(&active_chainstate.CoinsTip(), *this);
#     519         [ +  + ]:        702 :         if (!CheckFinalTx(active_chainstate.m_chain.Tip(), tx, flags)
#     520         [ +  + ]:        702 :             || !CheckSequenceLocks(active_chainstate.m_chain.Tip(), viewMempool, tx, flags, &lp, validLP)) {
#     521                 :            :             // Note if CheckSequenceLocks fails the LockPoints may still be invalid
#     522                 :            :             // So it's critical that we remove the tx and not depend on the LockPoints.
#     523                 :          4 :             txToRemove.insert(it);
#     524         [ +  + ]:        698 :         } else if (it->GetSpendsCoinbase()) {
#     525         [ +  + ]:         68 :             for (const CTxIn& txin : tx.vin) {
#     526                 :         68 :                 indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
#     527         [ -  + ]:         68 :                 if (it2 != mapTx.end())
#     528                 :          0 :                     continue;
#     529                 :         68 :                 const Coin &coin = active_chainstate.CoinsTip().AccessCoin(txin.prevout);
#     530         [ +  - ]:         68 :                 if (m_check_ratio != 0) assert(!coin.IsSpent());
#     531                 :         68 :                 unsigned int nMemPoolHeight = active_chainstate.m_chain.Tip()->nHeight + 1;
#     532 [ -  + ][ +  + ]:         68 :                 if (coin.IsSpent() || (coin.IsCoinBase() && ((signed long)nMemPoolHeight) - coin.nHeight < COINBASE_MATURITY)) {
#                 [ +  + ]
#     533                 :          7 :                     txToRemove.insert(it);
#     534                 :          7 :                     break;
#     535                 :          7 :                 }
#     536                 :         68 :             }
#     537                 :         65 :         }
#     538         [ +  + ]:        702 :         if (!validLP) {
#     539                 :          5 :             mapTx.modify(it, update_lock_points(lp));
#     540                 :          5 :         }
#     541                 :        702 :     }
#     542                 :       2040 :     setEntries setAllRemoves;
#     543         [ +  + ]:       2040 :     for (txiter it : txToRemove) {
#     544                 :         11 :         CalculateDescendants(it, setAllRemoves);
#     545                 :         11 :     }
#     546                 :       2040 :     RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG);
#     547                 :       2040 : }
#     548                 :            : 
#     549                 :            : void CTxMemPool::removeConflicts(const CTransaction &tx)
#     550                 :     168781 : {
#     551                 :            :     // Remove transactions which depend on inputs of tx, recursively
#     552                 :     168781 :     AssertLockHeld(cs);
#     553         [ +  + ]:     207151 :     for (const CTxIn &txin : tx.vin) {
#     554                 :     207151 :         auto it = mapNextTx.find(txin.prevout);
#     555         [ +  + ]:     207151 :         if (it != mapNextTx.end()) {
#     556                 :         52 :             const CTransaction &txConflict = *it->second;
#     557         [ +  - ]:         52 :             if (txConflict != tx)
#     558                 :         52 :             {
#     559                 :         52 :                 ClearPrioritisation(txConflict.GetHash());
#     560                 :         52 :                 removeRecursive(txConflict, MemPoolRemovalReason::CONFLICT);
#     561                 :         52 :             }
#     562                 :         52 :         }
#     563                 :     207151 :     }
#     564                 :     168781 : }
#     565                 :            : 
#     566                 :            : /**
#     567                 :            :  * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
#     568                 :            :  */
#     569                 :            : void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight)
#     570                 :      69498 : {
#     571                 :      69498 :     AssertLockHeld(cs);
#     572                 :      69498 :     std::vector<const CTxMemPoolEntry*> entries;
#     573         [ +  + ]:      69498 :     for (const auto& tx : vtx)
#     574                 :     168781 :     {
#     575                 :     168781 :         uint256 hash = tx->GetHash();
#     576                 :            : 
#     577                 :     168781 :         indexed_transaction_set::iterator i = mapTx.find(hash);
#     578         [ +  + ]:     168781 :         if (i != mapTx.end())
#     579                 :      67999 :             entries.push_back(&*i);
#     580                 :     168781 :     }
#     581                 :            :     // Before the txs in the new block have been removed from the mempool, update policy estimates
#     582         [ +  + ]:      69498 :     if (minerPolicyEstimator) {minerPolicyEstimator->processBlock(nBlockHeight, entries);}
#     583         [ +  + ]:      69498 :     for (const auto& tx : vtx)
#     584                 :     168781 :     {
#     585                 :     168781 :         txiter it = mapTx.find(tx->GetHash());
#     586         [ +  + ]:     168781 :         if (it != mapTx.end()) {
#     587                 :      67999 :             setEntries stage;
#     588                 :      67999 :             stage.insert(it);
#     589                 :      67999 :             RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
#     590                 :      67999 :         }
#     591                 :     168781 :         removeConflicts(*tx);
#     592                 :     168781 :         ClearPrioritisation(tx->GetHash());
#     593                 :     168781 :     }
#     594                 :      69498 :     lastRollingFeeUpdate = GetTime();
#     595                 :      69498 :     blockSinceLastRollingFeeBump = true;
#     596                 :      69498 : }
#     597                 :            : 
#     598                 :            : void CTxMemPool::_clear()
#     599                 :       5632 : {
#     600                 :       5632 :     mapTx.clear();
#     601                 :       5632 :     mapNextTx.clear();
#     602                 :       5632 :     totalTxSize = 0;
#     603                 :       5632 :     m_total_fee = 0;
#     604                 :       5632 :     cachedInnerUsage = 0;
#     605                 :       5632 :     lastRollingFeeUpdate = GetTime();
#     606                 :       5632 :     blockSinceLastRollingFeeBump = false;
#     607                 :       5632 :     rollingMinimumFeeRate = 0;
#     608                 :       5632 :     ++nTransactionsUpdated;
#     609                 :       5632 : }
#     610                 :            : 
#     611                 :            : void CTxMemPool::clear()
#     612                 :        807 : {
#     613                 :        807 :     LOCK(cs);
#     614                 :        807 :     _clear();
#     615                 :        807 : }
#     616                 :            : 
#     617                 :            : static void CheckInputsAndUpdateCoins(const CTransaction& tx, CCoinsViewCache& mempoolDuplicate, const int64_t spendheight)
#     618                 :    5226130 : {
#     619                 :    5226130 :     TxValidationState dummy_state; // Not used. CheckTxInputs() should always pass
#     620                 :    5226130 :     CAmount txfee = 0;
#     621 [ -  + ][ +  - ]:    5226130 :     bool fCheckResult = tx.IsCoinBase() || Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate, spendheight, txfee);
#     622                 :    5226130 :     assert(fCheckResult);
#     623                 :    5226130 :     UpdateCoins(tx, mempoolDuplicate, std::numeric_limits<int>::max());
#     624                 :    5226130 : }
#     625                 :            : 
#     626                 :            : void CTxMemPool::check(CChainState& active_chainstate) const
#     627                 :      86296 : {
#     628         [ +  + ]:      86296 :     if (m_check_ratio == 0) return;
#     629                 :            : 
#     630         [ -  + ]:      86276 :     if (GetRand(m_check_ratio) >= 1) return;
#     631                 :            : 
#     632                 :      86276 :     AssertLockHeld(::cs_main);
#     633                 :      86276 :     LOCK(cs);
#     634         [ +  - ]:      86276 :     LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
#     635                 :            : 
#     636                 :      86276 :     uint64_t checkTotal = 0;
#     637                 :      86276 :     CAmount check_total_fee{0};
#     638                 :      86276 :     uint64_t innerUsage = 0;
#     639                 :            : 
#     640                 :      86276 :     CCoinsViewCache& active_coins_tip = active_chainstate.CoinsTip();
#     641                 :      86276 :     assert(std::addressof(::ChainstateActive().CoinsTip()) == std::addressof(active_coins_tip)); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
#     642                 :      86276 :     CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
#     643                 :      86276 :     const int64_t spendheight = active_chainstate.m_chain.Height() + 1;
#     644                 :      86276 :     assert(g_chainman.m_blockman.GetSpendHeight(mempoolDuplicate) == spendheight); // TODO: REVIEW-ONLY, REMOVE IN FUTURE COMMIT
#     645                 :            : 
#     646                 :      86276 :     std::list<const CTxMemPoolEntry*> waitingOnDependants;
#     647         [ +  + ]:    5312406 :     for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
#     648                 :    5226130 :         unsigned int i = 0;
#     649                 :    5226130 :         checkTotal += it->GetTxSize();
#     650                 :    5226130 :         check_total_fee += it->GetFee();
#     651                 :    5226130 :         innerUsage += it->DynamicMemoryUsage();
#     652                 :    5226130 :         const CTransaction& tx = it->GetTx();
#     653                 :    5226130 :         innerUsage += memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
#     654                 :    5226130 :         bool fDependsWait = false;
#     655                 :    5226130 :         CTxMemPoolEntry::Parents setParentCheck;
#     656         [ +  + ]:    7543893 :         for (const CTxIn &txin : tx.vin) {
#     657                 :            :             // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
#     658                 :    7543893 :             indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
#     659         [ +  + ]:    7543893 :             if (it2 != mapTx.end()) {
#     660                 :      29430 :                 const CTransaction& tx2 = it2->GetTx();
#     661                 :      29430 :                 assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
#     662                 :      29430 :                 fDependsWait = true;
#     663                 :      29430 :                 setParentCheck.insert(*it2);
#     664                 :    7514463 :             } else {
#     665                 :    7514463 :                 assert(active_coins_tip.HaveCoin(txin.prevout));
#     666                 :    7514463 :             }
#     667                 :            :             // Check whether its inputs are marked in mapNextTx.
#     668                 :    7543893 :             auto it3 = mapNextTx.find(txin.prevout);
#     669                 :    7543893 :             assert(it3 != mapNextTx.end());
#     670                 :    7543893 :             assert(it3->first == &txin.prevout);
#     671                 :    7543893 :             assert(it3->second == &tx);
#     672                 :    7543893 :             i++;
#     673                 :    7543893 :         }
#     674                 :    5226130 :         auto comp = [](const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) -> bool {
#     675                 :      58836 :             return a.GetTx().GetHash() == b.GetTx().GetHash();
#     676                 :      58836 :         };
#     677                 :    5226130 :         assert(setParentCheck.size() == it->GetMemPoolParentsConst().size());
#     678                 :    5226130 :         assert(std::equal(setParentCheck.begin(), setParentCheck.end(), it->GetMemPoolParentsConst().begin(), comp));
#     679                 :            :         // Verify ancestor state is correct.
#     680                 :    5226130 :         setEntries setAncestors;
#     681                 :    5226130 :         uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     682                 :    5226130 :         std::string dummy;
#     683                 :    5226130 :         CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
#     684                 :    5226130 :         uint64_t nCountCheck = setAncestors.size() + 1;
#     685                 :    5226130 :         uint64_t nSizeCheck = it->GetTxSize();
#     686                 :    5226130 :         CAmount nFeesCheck = it->GetModifiedFee();
#     687                 :    5226130 :         int64_t nSigOpCheck = it->GetSigOpCost();
#     688                 :            : 
#     689         [ +  + ]:    5226130 :         for (txiter ancestorIt : setAncestors) {
#     690                 :      40782 :             nSizeCheck += ancestorIt->GetTxSize();
#     691                 :      40782 :             nFeesCheck += ancestorIt->GetModifiedFee();
#     692                 :      40782 :             nSigOpCheck += ancestorIt->GetSigOpCost();
#     693                 :      40782 :         }
#     694                 :            : 
#     695                 :    5226130 :         assert(it->GetCountWithAncestors() == nCountCheck);
#     696                 :    5226130 :         assert(it->GetSizeWithAncestors() == nSizeCheck);
#     697                 :    5226130 :         assert(it->GetSigOpCostWithAncestors() == nSigOpCheck);
#     698                 :    5226130 :         assert(it->GetModFeesWithAncestors() == nFeesCheck);
#     699                 :            : 
#     700                 :            :         // Check children against mapNextTx
#     701                 :    5226130 :         CTxMemPoolEntry::Children setChildrenCheck;
#     702                 :    5226130 :         auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
#     703                 :    5226130 :         uint64_t child_sizes = 0;
#     704 [ +  + ][ +  + ]:    5255560 :         for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) {
#                 [ +  + ]
#     705                 :      29430 :             txiter childit = mapTx.find(iter->second->GetHash());
#     706                 :      29430 :             assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
#     707         [ +  + ]:      29430 :             if (setChildrenCheck.insert(*childit).second) {
#     708                 :      29418 :                 child_sizes += childit->GetTxSize();
#     709                 :      29418 :             }
#     710                 :      29430 :         }
#     711                 :    5226130 :         assert(setChildrenCheck.size() == it->GetMemPoolChildrenConst().size());
#     712                 :    5226130 :         assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(), it->GetMemPoolChildrenConst().begin(), comp));
#     713                 :            :         // Also check to make sure size is greater than sum with immediate children.
#     714                 :            :         // just a sanity check, not definitive that this calc is correct...
#     715                 :    5226130 :         assert(it->GetSizeWithDescendants() >= child_sizes + it->GetTxSize());
#     716                 :            : 
#     717         [ +  + ]:    5226130 :         if (fDependsWait)
#     718                 :      28736 :             waitingOnDependants.push_back(&(*it));
#     719                 :    5197394 :         else {
#     720                 :    5197394 :             CheckInputsAndUpdateCoins(tx, mempoolDuplicate, spendheight);
#     721                 :    5197394 :         }
#     722                 :    5226130 :     }
#     723                 :      86276 :     unsigned int stepsSinceLastRemove = 0;
#     724         [ +  + ]:     119310 :     while (!waitingOnDependants.empty()) {
#     725                 :      33034 :         const CTxMemPoolEntry* entry = waitingOnDependants.front();
#     726                 :      33034 :         waitingOnDependants.pop_front();
#     727         [ +  + ]:      33034 :         if (!mempoolDuplicate.HaveInputs(entry->GetTx())) {
#     728                 :       4298 :             waitingOnDependants.push_back(entry);
#     729                 :       4298 :             stepsSinceLastRemove++;
#     730                 :       4298 :             assert(stepsSinceLastRemove < waitingOnDependants.size());
#     731                 :      28736 :         } else {
#     732                 :      28736 :             CheckInputsAndUpdateCoins(entry->GetTx(), mempoolDuplicate, spendheight);
#     733                 :      28736 :             stepsSinceLastRemove = 0;
#     734                 :      28736 :         }
#     735                 :      33034 :     }
#     736         [ +  + ]:    7630169 :     for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
#     737                 :    7543893 :         uint256 hash = it->second->GetHash();
#     738                 :    7543893 :         indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
#     739                 :    7543893 :         const CTransaction& tx = it2->GetTx();
#     740                 :    7543893 :         assert(it2 != mapTx.end());
#     741                 :    7543893 :         assert(&tx == it->second);
#     742                 :    7543893 :     }
#     743                 :            : 
#     744                 :      86276 :     assert(totalTxSize == checkTotal);
#     745                 :      86276 :     assert(m_total_fee == check_total_fee);
#     746                 :      86276 :     assert(innerUsage == cachedInnerUsage);
#     747                 :      86276 : }
#     748                 :            : 
#     749                 :            : bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb, bool wtxid)
#     750                 :      96659 : {
#     751                 :      96659 :     LOCK(cs);
#     752         [ +  + ]:      96659 :     indexed_transaction_set::const_iterator i = wtxid ? get_iter_from_wtxid(hasha) : mapTx.find(hasha);
#     753         [ +  + ]:      96659 :     if (i == mapTx.end()) return false;
#     754         [ +  + ]:      45195 :     indexed_transaction_set::const_iterator j = wtxid ? get_iter_from_wtxid(hashb) : mapTx.find(hashb);
#     755         [ +  + ]:      45195 :     if (j == mapTx.end()) return true;
#     756                 :      43479 :     uint64_t counta = i->GetCountWithAncestors();
#     757                 :      43479 :     uint64_t countb = j->GetCountWithAncestors();
#     758         [ +  + ]:      43479 :     if (counta == countb) {
#     759                 :      42611 :         return CompareTxMemPoolEntryByScore()(*i, *j);
#     760                 :      42611 :     }
#     761                 :        868 :     return counta < countb;
#     762                 :        868 : }
#     763                 :            : 
#     764                 :            : namespace {
#     765                 :            : class DepthAndScoreComparator
#     766                 :            : {
#     767                 :            : public:
#     768                 :            :     bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b)
#     769                 :    4228285 :     {
#     770                 :    4228285 :         uint64_t counta = a->GetCountWithAncestors();
#     771                 :    4228285 :         uint64_t countb = b->GetCountWithAncestors();
#     772         [ +  + ]:    4228285 :         if (counta == countb) {
#     773                 :    4223439 :             return CompareTxMemPoolEntryByScore()(*a, *b);
#     774                 :    4223439 :         }
#     775                 :       4846 :         return counta < countb;
#     776                 :       4846 :     }
#     777                 :            : };
#     778                 :            : } // namespace
#     779                 :            : 
#     780                 :            : std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedDepthAndScore() const
#     781                 :       5892 : {
#     782                 :       5892 :     std::vector<indexed_transaction_set::const_iterator> iters;
#     783                 :       5892 :     AssertLockHeld(cs);
#     784                 :            : 
#     785                 :       5892 :     iters.reserve(mapTx.size());
#     786                 :            : 
#     787         [ +  + ]:     394757 :     for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
#     788                 :     388865 :         iters.push_back(mi);
#     789                 :     388865 :     }
#     790                 :       5892 :     std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
#     791                 :       5892 :     return iters;
#     792                 :       5892 : }
#     793                 :            : 
#     794                 :            : void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) const
#     795                 :       5274 : {
#     796                 :       5274 :     LOCK(cs);
#     797                 :       5274 :     auto iters = GetSortedDepthAndScore();
#     798                 :            : 
#     799                 :       5274 :     vtxid.clear();
#     800                 :       5274 :     vtxid.reserve(mapTx.size());
#     801                 :            : 
#     802         [ +  + ]:     388110 :     for (auto it : iters) {
#     803                 :     388110 :         vtxid.push_back(it->GetTx().GetHash());
#     804                 :     388110 :     }
#     805                 :       5274 : }
#     806                 :            : 
#     807                 :      25293 : static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
#     808                 :      25293 :     return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
#     809                 :      25293 : }
#     810                 :            : 
#     811                 :            : std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
#     812                 :        618 : {
#     813                 :        618 :     LOCK(cs);
#     814                 :        618 :     auto iters = GetSortedDepthAndScore();
#     815                 :            : 
#     816                 :        618 :     std::vector<TxMempoolInfo> ret;
#     817                 :        618 :     ret.reserve(mapTx.size());
#     818         [ +  + ]:        755 :     for (auto it : iters) {
#     819                 :        755 :         ret.push_back(GetInfo(it));
#     820                 :        755 :     }
#     821                 :            : 
#     822                 :        618 :     return ret;
#     823                 :        618 : }
#     824                 :            : 
#     825                 :            : CTransactionRef CTxMemPool::get(const uint256& hash) const
#     826                 :     179731 : {
#     827                 :     179731 :     LOCK(cs);
#     828                 :     179731 :     indexed_transaction_set::const_iterator i = mapTx.find(hash);
#     829         [ +  + ]:     179731 :     if (i == mapTx.end())
#     830                 :     115031 :         return nullptr;
#     831                 :      64700 :     return i->GetSharedTx();
#     832                 :      64700 : }
#     833                 :            : 
#     834                 :            : TxMempoolInfo CTxMemPool::info(const GenTxid& gtxid) const
#     835                 :      26711 : {
#     836                 :      26711 :     LOCK(cs);
#     837         [ +  + ]:      26711 :     indexed_transaction_set::const_iterator i = (gtxid.IsWtxid() ? get_iter_from_wtxid(gtxid.GetHash()) : mapTx.find(gtxid.GetHash()));
#     838         [ +  + ]:      26711 :     if (i == mapTx.end())
#     839                 :       2173 :         return TxMempoolInfo();
#     840                 :      24538 :     return GetInfo(i);
#     841                 :      24538 : }
#     842                 :            : 
#     843                 :          0 : TxMempoolInfo CTxMemPool::info(const uint256& txid) const { return info(GenTxid{false, txid}); }
#     844                 :            : 
#     845                 :            : void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta)
#     846                 :         17 : {
#     847                 :         17 :     {
#     848                 :         17 :         LOCK(cs);
#     849                 :         17 :         CAmount &delta = mapDeltas[hash];
#     850                 :         17 :         delta += nFeeDelta;
#     851                 :         17 :         txiter it = mapTx.find(hash);
#     852         [ +  + ]:         17 :         if (it != mapTx.end()) {
#     853                 :          9 :             mapTx.modify(it, update_fee_delta(delta));
#     854                 :            :             // Now update all ancestors' modified fees with descendants
#     855                 :          9 :             setEntries setAncestors;
#     856                 :          9 :             uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     857                 :          9 :             std::string dummy;
#     858                 :          9 :             CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
#     859         [ +  + ]:         25 :             for (txiter ancestorIt : setAncestors) {
#     860                 :         25 :                 mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0));
#     861                 :         25 :             }
#     862                 :            :             // Now update all descendants' modified fees with ancestors
#     863                 :          9 :             setEntries setDescendants;
#     864                 :          9 :             CalculateDescendants(it, setDescendants);
#     865                 :          9 :             setDescendants.erase(it);
#     866         [ +  + ]:         48 :             for (txiter descendantIt : setDescendants) {
#     867                 :         48 :                 mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0));
#     868                 :         48 :             }
#     869                 :          9 :             ++nTransactionsUpdated;
#     870                 :          9 :         }
#     871                 :         17 :     }
#     872                 :         17 :     LogPrintf("PrioritiseTransaction: %s feerate += %s\n", hash.ToString(), FormatMoney(nFeeDelta));
#     873                 :         17 : }
#     874                 :            : 
#     875                 :            : void CTxMemPool::ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const
#     876                 :     100064 : {
#     877                 :     100064 :     AssertLockHeld(cs);
#     878                 :     100064 :     std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
#     879         [ +  + ]:     100064 :     if (pos == mapDeltas.end())
#     880                 :     100047 :         return;
#     881                 :         17 :     const CAmount &delta = pos->second;
#     882                 :         17 :     nFeeDelta += delta;
#     883                 :         17 : }
#     884                 :            : 
#     885                 :            : void CTxMemPool::ClearPrioritisation(const uint256& hash)
#     886                 :     168833 : {
#     887                 :     168833 :     AssertLockHeld(cs);
#     888                 :     168833 :     mapDeltas.erase(hash);
#     889                 :     168833 : }
#     890                 :            : 
#     891                 :            : const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
#     892                 :      67668 : {
#     893                 :      67668 :     const auto it = mapNextTx.find(prevout);
#     894         [ +  + ]:      67668 :     return it == mapNextTx.end() ? nullptr : it->second;
#     895                 :      67668 : }
#     896                 :            : 
#     897                 :            : std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const
#     898                 :    7756978 : {
#     899                 :    7756978 :     auto it = mapTx.find(txid);
#     900         [ +  + ]:    7756978 :     if (it != mapTx.end()) return it;
#     901                 :    7698054 :     return std::nullopt;
#     902                 :    7698054 : }
#     903                 :            : 
#     904                 :            : CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const
#     905                 :     100040 : {
#     906                 :     100040 :     CTxMemPool::setEntries ret;
#     907         [ +  + ]:     100040 :     for (const auto& h : hashes) {
#     908                 :      91586 :         const auto mi = GetIter(h);
#     909         [ +  + ]:      91586 :         if (mi) ret.insert(*mi);
#     910                 :      91586 :     }
#     911                 :     100040 :     return ret;
#     912                 :     100040 : }
#     913                 :            : 
#     914                 :            : bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
#     915                 :      19484 : {
#     916         [ +  + ]:      52526 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
#     917         [ +  + ]:      34768 :         if (exists(tx.vin[i].prevout.hash))
#     918                 :       1726 :             return false;
#     919                 :      19484 :     return true;
#     920                 :      19484 : }
#     921                 :            : 
#     922                 :      39019 : CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
#     923                 :            : 
#     924                 :      78200 : bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
#     925                 :            :     // Check to see if the inputs are made available by another tx in the package.
#     926                 :            :     // These Coins would not be available in the underlying CoinsView.
#     927         [ +  + ]:      78200 :     if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
#     928                 :        390 :         coin = it->second;
#     929                 :        390 :         return true;
#     930                 :        390 :     }
#     931                 :            : 
#     932                 :            :     // If an entry in the mempool exists, always return that one, as it's guaranteed to never
#     933                 :            :     // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
#     934                 :            :     // transactions. First checking the underlying cache risks returning a pruned entry instead.
#     935                 :      77810 :     CTransactionRef ptx = mempool.get(outpoint.hash);
#     936         [ +  + ]:      77810 :     if (ptx) {
#     937         [ +  - ]:       8760 :         if (outpoint.n < ptx->vout.size()) {
#     938                 :       8760 :             coin = Coin(ptx->vout[outpoint.n], MEMPOOL_HEIGHT, false);
#     939                 :       8760 :             return true;
#     940                 :       8760 :         } else {
#     941                 :          0 :             return false;
#     942                 :          0 :         }
#     943                 :      69050 :     }
#     944                 :      69050 :     return base->GetCoin(outpoint, coin);
#     945                 :      69050 : }
#     946                 :            : 
#     947                 :            : void CCoinsViewMemPool::PackageAddTransaction(const CTransactionRef& tx)
#     948                 :        441 : {
#     949         [ +  + ]:        884 :     for (unsigned int n = 0; n < tx->vout.size(); ++n) {
#     950                 :        443 :         m_temp_added.emplace(COutPoint(tx->GetHash(), n), Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
#     951                 :        443 :     }
#     952                 :        441 : }
#     953                 :            : 
#     954                 :     267583 : size_t CTxMemPool::DynamicMemoryUsage() const {
#     955                 :     267583 :     LOCK(cs);
#     956                 :            :     // Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
#     957                 :     267583 :     return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage;
#     958                 :     267583 : }
#     959                 :            : 
#     960                 :      78502 : void CTxMemPool::RemoveUnbroadcastTx(const uint256& txid, const bool unchecked) {
#     961                 :      78502 :     LOCK(cs);
#     962                 :            : 
#     963         [ +  + ]:      78502 :     if (m_unbroadcast_txids.erase(txid))
#     964                 :       9711 :     {
#     965 [ +  - ][ +  + ]:       9711 :         LogPrint(BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n", txid.GetHex(), (unchecked ? " before confirmation that txn was sent out" : ""));
#     966                 :       9711 :     }
#     967                 :      78502 : }
#     968                 :            : 
#     969                 :     122737 : void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) {
#     970                 :     122737 :     AssertLockHeld(cs);
#     971                 :     122737 :     UpdateForRemoveFromMempool(stage, updateDescendants);
#     972         [ +  + ]:     122737 :     for (txiter it : stage) {
#     973                 :      68634 :         removeUnchecked(it, reason);
#     974                 :      68634 :     }
#     975                 :     122737 : }
#     976                 :            : 
#     977                 :            : int CTxMemPool::Expire(std::chrono::seconds time)
#     978                 :      21872 : {
#     979                 :      21872 :     AssertLockHeld(cs);
#     980                 :      21872 :     indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin();
#     981                 :      21872 :     setEntries toremove;
#     982 [ +  + ][ +  + ]:      21874 :     while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) {
#                 [ +  + ]
#     983                 :          2 :         toremove.insert(mapTx.project<0>(it));
#     984                 :          2 :         it++;
#     985                 :          2 :     }
#     986                 :      21872 :     setEntries stage;
#     987         [ +  + ]:      21872 :     for (txiter removeit : toremove) {
#     988                 :          2 :         CalculateDescendants(removeit, stage);
#     989                 :          2 :     }
#     990                 :      21872 :     RemoveStaged(stage, false, MemPoolRemovalReason::EXPIRY);
#     991                 :      21872 :     return stage.size();
#     992                 :      21872 : }
#     993                 :            : 
#     994                 :            : void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate)
#     995                 :      53616 : {
#     996                 :      53616 :     setEntries setAncestors;
#     997                 :      53616 :     uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     998                 :      53616 :     std::string dummy;
#     999                 :      53616 :     CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
#    1000                 :      53616 :     return addUnchecked(entry, setAncestors, validFeeEstimate);
#    1001                 :      53616 : }
#    1002                 :            : 
#    1003                 :            : void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)
#    1004                 :      12291 : {
#    1005                 :      12291 :     AssertLockHeld(cs);
#    1006                 :      12291 :     CTxMemPoolEntry::Children s;
#    1007 [ +  + ][ +  + ]:      12291 :     if (add && entry->GetMemPoolChildren().insert(*child).second) {
#                 [ +  - ]
#    1008                 :      11984 :         cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
#    1009 [ +  - ][ +  - ]:      11984 :     } else if (!add && entry->GetMemPoolChildren().erase(*child)) {
#                 [ +  - ]
#    1010                 :        307 :         cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
#    1011                 :        307 :     }
#    1012                 :      12291 : }
#    1013                 :            : 
#    1014                 :            : void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add)
#    1015                 :      14263 : {
#    1016                 :      14263 :     AssertLockHeld(cs);
#    1017                 :      14263 :     CTxMemPoolEntry::Parents s;
#    1018 [ +  + ][ +  + ]:      14263 :     if (add && entry->GetMemPoolParents().insert(*parent).second) {
#                 [ +  - ]
#    1019                 :      11984 :         cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
#    1020 [ +  - ][ +  - ]:      11984 :     } else if (!add && entry->GetMemPoolParents().erase(*parent)) {
#                 [ +  - ]
#    1021                 :       2279 :         cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
#    1022                 :       2279 :     }
#    1023                 :      14263 : }
#    1024                 :            : 
#    1025                 :     400868 : CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
#    1026                 :     400868 :     LOCK(cs);
#    1027 [ +  + ][ +  + ]:     400868 :     if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
#    1028                 :     400858 :         return CFeeRate(llround(rollingMinimumFeeRate));
#    1029                 :            : 
#    1030                 :         10 :     int64_t time = GetTime();
#    1031         [ +  - ]:         10 :     if (time > lastRollingFeeUpdate + 10) {
#    1032                 :         10 :         double halflife = ROLLING_FEE_HALFLIFE;
#    1033         [ +  + ]:         10 :         if (DynamicMemoryUsage() < sizelimit / 4)
#    1034                 :          2 :             halflife /= 4;
#    1035         [ +  + ]:          8 :         else if (DynamicMemoryUsage() < sizelimit / 2)
#    1036                 :          2 :             halflife /= 2;
#    1037                 :            : 
#    1038                 :         10 :         rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
#    1039                 :         10 :         lastRollingFeeUpdate = time;
#    1040                 :            : 
#    1041         [ +  + ]:         10 :         if (rollingMinimumFeeRate < (double)incrementalRelayFee.GetFeePerK() / 2) {
#    1042                 :          2 :             rollingMinimumFeeRate = 0;
#    1043                 :          2 :             return CFeeRate(0);
#    1044                 :          2 :         }
#    1045                 :          8 :     }
#    1046                 :          8 :     return std::max(CFeeRate(llround(rollingMinimumFeeRate)), incrementalRelayFee);
#    1047                 :          8 : }
#    1048                 :            : 
#    1049                 :         36 : void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
#    1050                 :         36 :     AssertLockHeld(cs);
#    1051         [ +  + ]:         36 :     if (rate.GetFeePerK() > rollingMinimumFeeRate) {
#    1052                 :          9 :         rollingMinimumFeeRate = rate.GetFeePerK();
#    1053                 :          9 :         blockSinceLastRollingFeeBump = false;
#    1054                 :          9 :     }
#    1055                 :         36 : }
#    1056                 :            : 
#    1057                 :      21884 : void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining) {
#    1058                 :      21884 :     AssertLockHeld(cs);
#    1059                 :            : 
#    1060                 :      21884 :     unsigned nTxnRemoved = 0;
#    1061                 :      21884 :     CFeeRate maxFeeRateRemoved(0);
#    1062 [ +  + ][ +  + ]:      21920 :     while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
#    1063                 :         36 :         indexed_transaction_set::index<descendant_score>::type::iterator it = mapTx.get<descendant_score>().begin();
#    1064                 :            : 
#    1065                 :            :         // We set the new mempool min fee to the feerate of the removed set, plus the
#    1066                 :            :         // "minimum reasonable fee rate" (ie some value under which we consider txn
#    1067                 :            :         // to have 0 fee). This way, we don't allow txn to enter mempool with feerate
#    1068                 :            :         // equal to txn which were removed with no block in between.
#    1069                 :         36 :         CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
#    1070                 :         36 :         removed += incrementalRelayFee;
#    1071                 :         36 :         trackPackageRemoved(removed);
#    1072                 :         36 :         maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
#    1073                 :            : 
#    1074                 :         36 :         setEntries stage;
#    1075                 :         36 :         CalculateDescendants(mapTx.project<0>(it), stage);
#    1076                 :         36 :         nTxnRemoved += stage.size();
#    1077                 :            : 
#    1078                 :         36 :         std::vector<CTransaction> txn;
#    1079         [ +  + ]:         36 :         if (pvNoSpendsRemaining) {
#    1080                 :         26 :             txn.reserve(stage.size());
#    1081         [ +  + ]:         26 :             for (txiter iter : stage)
#    1082                 :         26 :                 txn.push_back(iter->GetTx());
#    1083                 :         26 :         }
#    1084                 :         36 :         RemoveStaged(stage, false, MemPoolRemovalReason::SIZELIMIT);
#    1085         [ +  + ]:         36 :         if (pvNoSpendsRemaining) {
#    1086         [ +  + ]:         26 :             for (const CTransaction& tx : txn) {
#    1087         [ +  + ]:         26 :                 for (const CTxIn& txin : tx.vin) {
#    1088         [ -  + ]:         26 :                     if (exists(txin.prevout.hash)) continue;
#    1089                 :         26 :                     pvNoSpendsRemaining->push_back(txin.prevout);
#    1090                 :         26 :                 }
#    1091                 :         26 :             }
#    1092                 :         26 :         }
#    1093                 :         36 :     }
#    1094                 :            : 
#    1095         [ +  + ]:      21884 :     if (maxFeeRateRemoved > CFeeRate(0)) {
#    1096         [ +  - ]:         35 :         LogPrint(BCLog::MEMPOOL, "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString());
#    1097                 :         35 :     }
#    1098                 :      21884 : }
#    1099                 :            : 
#    1100                 :     406728 : uint64_t CTxMemPool::CalculateDescendantMaximum(txiter entry) const {
#    1101                 :            :     // find parent with highest descendant count
#    1102                 :     406728 :     std::vector<txiter> candidates;
#    1103                 :     406728 :     setEntries counted;
#    1104                 :     406728 :     candidates.push_back(entry);
#    1105                 :     406728 :     uint64_t maximum = 0;
#    1106         [ +  + ]:    1016410 :     while (candidates.size()) {
#    1107                 :     609682 :         txiter candidate = candidates.back();
#    1108                 :     609682 :         candidates.pop_back();
#    1109         [ +  + ]:     609682 :         if (!counted.insert(candidate).second) continue;
#    1110                 :     609552 :         const CTxMemPoolEntry::Parents& parents = candidate->GetMemPoolParentsConst();
#    1111         [ +  + ]:     609552 :         if (parents.size() == 0) {
#    1112                 :     412574 :             maximum = std::max(maximum, candidate->GetCountWithDescendants());
#    1113                 :     412574 :         } else {
#    1114         [ +  + ]:     202954 :             for (const CTxMemPoolEntry& i : parents) {
#    1115                 :     202954 :                 candidates.push_back(mapTx.iterator_to(i));
#    1116                 :     202954 :             }
#    1117                 :     196978 :         }
#    1118                 :     609552 :     }
#    1119                 :     406728 :     return maximum;
#    1120                 :     406728 : }
#    1121                 :            : 
#    1122                 :     903640 : void CTxMemPool::GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants) const {
#    1123                 :     903640 :     LOCK(cs);
#    1124                 :     903640 :     auto it = mapTx.find(txid);
#    1125                 :     903640 :     ancestors = descendants = 0;
#    1126         [ +  + ]:     903640 :     if (it != mapTx.end()) {
#    1127                 :     406728 :         ancestors = it->GetCountWithAncestors();
#    1128                 :     406728 :         descendants = CalculateDescendantMaximum(it);
#    1129                 :     406728 :     }
#    1130                 :     903640 : }
#    1131                 :            : 
#    1132                 :            : bool CTxMemPool::IsLoaded() const
#    1133                 :       1437 : {
#    1134                 :       1437 :     LOCK(cs);
#    1135                 :       1437 :     return m_is_loaded;
#    1136                 :       1437 : }
#    1137                 :            : 
#    1138                 :            : void CTxMemPool::SetIsLoaded(bool loaded)
#    1139                 :        621 : {
#    1140                 :        621 :     LOCK(cs);
#    1141                 :        621 :     m_is_loaded = loaded;
#    1142                 :        621 : }

Generated by: LCOV version 1.14