LCOV - code coverage report
Current view: top level - src - txmempool.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 780 813 95.9 %
Date: 2022-04-21 14:51:19 Functions: 69 69 100.0 %
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: 292 316 92.4 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2009-2010 Satoshi Nakamoto
#       2                 :            : // Copyright (c) 2009-2021 The Bitcoin Core developers
#       3                 :            : // Distributed under the MIT software license, see the accompanying
#       4                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       5                 :            : 
#       6                 :            : #include <txmempool.h>
#       7                 :            : 
#       8                 :            : #include <chain.h>
#       9                 :            : #include <coins.h>
#      10                 :            : #include <consensus/consensus.h>
#      11                 :            : #include <consensus/tx_verify.h>
#      12                 :            : #include <consensus/validation.h>
#      13                 :            : #include <policy/fees.h>
#      14                 :            : #include <policy/policy.h>
#      15                 :            : #include <policy/settings.h>
#      16                 :            : #include <reverse_iterator.h>
#      17                 :            : #include <util/moneystr.h>
#      18                 :            : #include <util/system.h>
#      19                 :            : #include <util/time.h>
#      20                 :            : #include <validationinterface.h>
#      21                 :            : 
#      22                 :            : #include <cmath>
#      23                 :            : #include <optional>
#      24                 :            : 
#      25                 :            : // Helpers for modifying CTxMemPool::mapTx, which is a boost multi_index.
#      26                 :            : struct update_descendant_state
#      27                 :            : {
#      28                 :            :     update_descendant_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount) :
#      29                 :            :         modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount)
#      30                 :    2035097 :     {}
#      31                 :            : 
#      32                 :            :     void operator() (CTxMemPoolEntry &e)
#      33                 :    2035097 :         { e.UpdateDescendantState(modifySize, modifyFee, modifyCount); }
#      34                 :            : 
#      35                 :            :     private:
#      36                 :            :         int64_t modifySize;
#      37                 :            :         CAmount modifyFee;
#      38                 :            :         int64_t modifyCount;
#      39                 :            : };
#      40                 :            : 
#      41                 :            : struct update_ancestor_state
#      42                 :            : {
#      43                 :            :     update_ancestor_state(int64_t _modifySize, CAmount _modifyFee, int64_t _modifyCount, int64_t _modifySigOpsCost) :
#      44                 :            :         modifySize(_modifySize), modifyFee(_modifyFee), modifyCount(_modifyCount), modifySigOpsCost(_modifySigOpsCost)
#      45                 :      85822 :     {}
#      46                 :            : 
#      47                 :            :     void operator() (CTxMemPoolEntry &e)
#      48                 :      85822 :         { e.UpdateAncestorState(modifySize, modifyFee, modifyCount, modifySigOpsCost); }
#      49                 :            : 
#      50                 :            :     private:
#      51                 :            :         int64_t modifySize;
#      52                 :            :         CAmount modifyFee;
#      53                 :            :         int64_t modifyCount;
#      54                 :            :         int64_t modifySigOpsCost;
#      55                 :            : };
#      56                 :            : 
#      57                 :            : bool TestLockPointValidity(CChain& active_chain, const LockPoints& lp)
#      58                 :       1610 : {
#      59                 :       1610 :     AssertLockHeld(cs_main);
#      60                 :            :     // If there are relative lock times then the maxInputBlock will be set
#      61                 :            :     // If there are no relative lock times, the LockPoints don't depend on the chain
#      62         [ +  - ]:       1610 :     if (lp.maxInputBlock) {
#      63                 :            :         // Check whether active_chain is an extension of the block at which the LockPoints
#      64                 :            :         // calculation was valid.  If not LockPoints are no longer valid
#      65         [ +  + ]:       1610 :         if (!active_chain.Contains(lp.maxInputBlock)) {
#      66                 :          9 :             return false;
#      67                 :          9 :         }
#      68                 :       1610 :     }
#      69                 :            : 
#      70                 :            :     // LockPoints still valid
#      71                 :       1601 :     return true;
#      72                 :       1610 : }
#      73                 :            : 
#      74                 :            : CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee,
#      75                 :            :                                  int64_t time, unsigned int entry_height,
#      76                 :            :                                  bool spends_coinbase, int64_t sigops_cost, LockPoints lp)
#      77                 :            :     : tx{tx},
#      78                 :            :       nFee{fee},
#      79                 :            :       nTxWeight(GetTransactionWeight(*tx)),
#      80                 :            :       nUsageSize{RecursiveDynamicUsage(tx)},
#      81                 :            :       nTime{time},
#      82                 :            :       entryHeight{entry_height},
#      83                 :            :       spendsCoinbase{spends_coinbase},
#      84                 :            :       sigOpCost{sigops_cost},
#      85                 :            :       lockPoints{lp},
#      86                 :            :       nSizeWithDescendants{GetTxSize()},
#      87                 :            :       nModFeesWithDescendants{nFee},
#      88                 :            :       nSizeWithAncestors{GetTxSize()},
#      89                 :            :       nModFeesWithAncestors{nFee},
#      90                 :      90980 :       nSigOpCostWithAncestors{sigOpCost} {}
#      91                 :            : 
#      92                 :            : void CTxMemPoolEntry::UpdateFeeDelta(CAmount newFeeDelta)
#      93                 :        251 : {
#      94                 :        251 :     nModFeesWithDescendants += newFeeDelta - feeDelta;
#      95                 :        251 :     nModFeesWithAncestors += newFeeDelta - feeDelta;
#      96                 :        251 :     feeDelta = newFeeDelta;
#      97                 :        251 : }
#      98                 :            : 
#      99                 :            : void CTxMemPoolEntry::UpdateLockPoints(const LockPoints& lp)
#     100                 :          7 : {
#     101                 :          7 :     lockPoints = lp;
#     102                 :          7 : }
#     103                 :            : 
#     104                 :            : size_t CTxMemPoolEntry::GetTxSize() const
#     105                 :  447772342 : {
#     106                 :  447772342 :     return GetVirtualTransactionSize(nTxWeight, sigOpCost);
#     107                 :  447772342 : }
#     108                 :            : 
#     109                 :            : void CTxMemPool::UpdateForDescendants(txiter updateIt, cacheMap& cachedDescendants,
#     110                 :            :                                       const std::set<uint256>& setExclude, std::set<uint256>& descendants_to_remove,
#     111                 :            :                                       uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
#     112                 :        294 : {
#     113                 :        294 :     CTxMemPoolEntry::Children stageEntries, descendants;
#     114                 :        294 :     stageEntries = updateIt->GetMemPoolChildrenConst();
#     115                 :            : 
#     116         [ +  + ]:       5330 :     while (!stageEntries.empty()) {
#     117                 :       5036 :         const CTxMemPoolEntry& descendant = *stageEntries.begin();
#     118                 :       5036 :         descendants.insert(descendant);
#     119                 :       5036 :         stageEntries.erase(descendant);
#     120                 :       5036 :         const CTxMemPoolEntry::Children& children = descendant.GetMemPoolChildrenConst();
#     121         [ +  + ]:     159715 :         for (const CTxMemPoolEntry& childEntry : children) {
#     122                 :     159715 :             cacheMap::iterator cacheIt = cachedDescendants.find(mapTx.iterator_to(childEntry));
#     123         [ +  + ]:     159715 :             if (cacheIt != cachedDescendants.end()) {
#     124                 :            :                 // We've already calculated this one, just add the entries for this set
#     125                 :            :                 // but don't traverse again.
#     126         [ +  + ]:     345005 :                 for (txiter cacheEntry : cacheIt->second) {
#     127                 :     345005 :                     descendants.insert(*cacheEntry);
#     128                 :     345005 :                 }
#     129         [ +  + ]:     152810 :             } else if (!descendants.count(childEntry)) {
#     130                 :            :                 // Schedule for later processing
#     131                 :      11742 :                 stageEntries.insert(childEntry);
#     132                 :      11742 :             }
#     133                 :     159715 :         }
#     134                 :       5036 :     }
#     135                 :            :     // descendants now contains all in-mempool descendants of updateIt.
#     136                 :            :     // Update and add to cached descendant map
#     137                 :        294 :     int64_t modifySize = 0;
#     138                 :        294 :     CAmount modifyFee = 0;
#     139                 :        294 :     int64_t modifyCount = 0;
#     140         [ +  + ]:       5041 :     for (const CTxMemPoolEntry& descendant : descendants) {
#     141         [ +  + ]:       5041 :         if (!setExclude.count(descendant.GetTx().GetHash())) {
#     142                 :       3767 :             modifySize += descendant.GetTxSize();
#     143                 :       3767 :             modifyFee += descendant.GetModifiedFee();
#     144                 :       3767 :             modifyCount++;
#     145                 :       3767 :             cachedDescendants[updateIt].insert(mapTx.iterator_to(descendant));
#     146                 :            :             // Update ancestor state for each descendant
#     147                 :       3767 :             mapTx.modify(mapTx.iterator_to(descendant), update_ancestor_state(updateIt->GetTxSize(), updateIt->GetModifiedFee(), 1, updateIt->GetSigOpCost()));
#     148                 :            :             // Don't directly remove the transaction here -- doing so would
#     149                 :            :             // invalidate iterators in cachedDescendants. Mark it for removal
#     150                 :            :             // by inserting into descendants_to_remove.
#     151 [ -  + ][ -  + ]:       3767 :             if (descendant.GetCountWithAncestors() > ancestor_count_limit || descendant.GetSizeWithAncestors() > ancestor_size_limit) {
#     152                 :          0 :                 descendants_to_remove.insert(descendant.GetTx().GetHash());
#     153                 :          0 :             }
#     154                 :       3767 :         }
#     155                 :       5041 :     }
#     156                 :        294 :     mapTx.modify(updateIt, update_descendant_state(modifySize, modifyFee, modifyCount));
#     157                 :        294 : }
#     158                 :            : 
#     159                 :            : void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate, uint64_t ancestor_size_limit, uint64_t ancestor_count_limit)
#     160                 :       1036 : {
#     161                 :       1036 :     AssertLockHeld(cs);
#     162                 :            :     // For each entry in vHashesToUpdate, store the set of in-mempool, but not
#     163                 :            :     // in-vHashesToUpdate transactions, so that we don't have to recalculate
#     164                 :            :     // descendants when we come across a previously seen entry.
#     165                 :       1036 :     cacheMap mapMemPoolDescendantsToUpdate;
#     166                 :            : 
#     167                 :            :     // Use a set for lookups into vHashesToUpdate (these entries are already
#     168                 :            :     // accounted for in the state of their ancestors)
#     169                 :       1036 :     std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end());
#     170                 :            : 
#     171                 :       1036 :     std::set<uint256> descendants_to_remove;
#     172                 :            : 
#     173                 :            :     // Iterate in reverse, so that whenever we are looking at a transaction
#     174                 :            :     // we are sure that all in-mempool descendants have already been processed.
#     175                 :            :     // This maximizes the benefit of the descendant cache and guarantees that
#     176                 :            :     // CTxMemPool::m_children will be updated, an assumption made in
#     177                 :            :     // UpdateForDescendants.
#     178         [ +  + ]:       1036 :     for (const uint256 &hash : reverse_iterate(vHashesToUpdate)) {
#     179                 :            :         // calculate children from mapNextTx
#     180                 :        294 :         txiter it = mapTx.find(hash);
#     181         [ -  + ]:        294 :         if (it == mapTx.end()) {
#     182                 :          0 :             continue;
#     183                 :          0 :         }
#     184                 :        294 :         auto iter = mapNextTx.lower_bound(COutPoint(hash, 0));
#     185                 :            :         // First calculate the children, and update CTxMemPool::m_children to
#     186                 :            :         // include them, and update their CTxMemPoolEntry::m_parents to include this tx.
#     187                 :            :         // we cache the in-mempool children to avoid duplicate updates
#     188                 :        294 :         {
#     189                 :        294 :             WITH_FRESH_EPOCH(m_epoch);
#     190 [ +  + ][ +  + ]:       5027 :             for (; iter != mapNextTx.end() && iter->first->hash == hash; ++iter) {
#                 [ +  + ]
#     191                 :       4733 :                 const uint256 &childHash = iter->second->GetHash();
#     192                 :       4733 :                 txiter childIter = mapTx.find(childHash);
#     193                 :       4733 :                 assert(childIter != mapTx.end());
#     194                 :            :                 // We can skip updating entries we've encountered before or that
#     195                 :            :                 // are in the block (which are already accounted for).
#     196 [ +  + ][ +  + ]:       4733 :                 if (!visited(childIter) && !setAlreadyIncluded.count(childHash)) {
#     197                 :       3761 :                     UpdateChild(it, childIter, true);
#     198                 :       3761 :                     UpdateParent(childIter, it, true);
#     199                 :       3761 :                 }
#     200                 :       4733 :             }
#     201                 :        294 :         } // release epoch guard for UpdateForDescendants
#     202                 :        294 :         UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded, descendants_to_remove, ancestor_size_limit, ancestor_count_limit);
#     203                 :        294 :     }
#     204                 :            : 
#     205         [ -  + ]:       1036 :     for (const auto& txid : descendants_to_remove) {
#     206                 :            :         // This txid may have been removed already in a prior call to removeRecursive.
#     207                 :            :         // Therefore we ensure it is not yet removed already.
#     208         [ #  # ]:          0 :         if (const std::optional<txiter> txiter = GetIter(txid)) {
#     209                 :          0 :             removeRecursive((*txiter)->GetTx(), MemPoolRemovalReason::SIZELIMIT);
#     210                 :          0 :         }
#     211                 :          0 :     }
#     212                 :       1036 : }
#     213                 :            : 
#     214                 :            : bool CTxMemPool::CalculateAncestorsAndCheckLimits(size_t entry_size,
#     215                 :            :                                                   size_t entry_count,
#     216                 :            :                                                   setEntries& setAncestors,
#     217                 :            :                                                   CTxMemPoolEntry::Parents& staged_ancestors,
#     218                 :            :                                                   uint64_t limitAncestorCount,
#     219                 :            :                                                   uint64_t limitAncestorSize,
#     220                 :            :                                                   uint64_t limitDescendantCount,
#     221                 :            :                                                   uint64_t limitDescendantSize,
#     222                 :            :                                                   std::string &errString) const
#     223                 :   11177250 : {
#     224                 :   11177250 :     size_t totalSizeWithAncestors = entry_size;
#     225                 :            : 
#     226         [ +  + ]:   13831255 :     while (!staged_ancestors.empty()) {
#     227                 :    2654131 :         const CTxMemPoolEntry& stage = staged_ancestors.begin()->get();
#     228                 :    2654131 :         txiter stageit = mapTx.iterator_to(stage);
#     229                 :            : 
#     230                 :    2654131 :         setAncestors.insert(stageit);
#     231                 :    2654131 :         staged_ancestors.erase(stage);
#     232                 :    2654131 :         totalSizeWithAncestors += stageit->GetTxSize();
#     233                 :            : 
#     234         [ +  + ]:    2654131 :         if (stageit->GetSizeWithDescendants() + entry_size > limitDescendantSize) {
#     235                 :         20 :             errString = strprintf("exceeds descendant size limit for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantSize);
#     236                 :         20 :             return false;
#     237         [ +  + ]:    2654111 :         } else if (stageit->GetCountWithDescendants() + entry_count > limitDescendantCount) {
#     238                 :         51 :             errString = strprintf("too many descendants for tx %s [limit: %u]", stageit->GetTx().GetHash().ToString(), limitDescendantCount);
#     239                 :         51 :             return false;
#     240         [ +  + ]:    2654060 :         } else if (totalSizeWithAncestors > limitAncestorSize) {
#     241                 :          1 :             errString = strprintf("exceeds ancestor size limit [limit: %u]", limitAncestorSize);
#     242                 :          1 :             return false;
#     243                 :          1 :         }
#     244                 :            : 
#     245                 :    2654059 :         const CTxMemPoolEntry::Parents& parents = stageit->GetMemPoolParentsConst();
#     246         [ +  + ]:    2794225 :         for (const CTxMemPoolEntry& parent : parents) {
#     247                 :    2794225 :             txiter parent_it = mapTx.iterator_to(parent);
#     248                 :            : 
#     249                 :            :             // If this is a new ancestor, add it.
#     250         [ +  + ]:    2794225 :             if (setAncestors.count(parent_it) == 0) {
#     251                 :    2637464 :                 staged_ancestors.insert(parent);
#     252                 :    2637464 :             }
#     253         [ +  + ]:    2794225 :             if (staged_ancestors.size() + setAncestors.size() + entry_count > limitAncestorCount) {
#     254                 :         54 :                 errString = strprintf("too many unconfirmed ancestors [limit: %u]", limitAncestorCount);
#     255                 :         54 :                 return false;
#     256                 :         54 :             }
#     257                 :    2794225 :         }
#     258                 :    2654059 :     }
#     259                 :            : 
#     260                 :   11177124 :     return true;
#     261                 :   11177250 : }
#     262                 :            : 
#     263                 :            : bool CTxMemPool::CheckPackageLimits(const Package& package,
#     264                 :            :                                     uint64_t limitAncestorCount,
#     265                 :            :                                     uint64_t limitAncestorSize,
#     266                 :            :                                     uint64_t limitDescendantCount,
#     267                 :            :                                     uint64_t limitDescendantSize,
#     268                 :            :                                     std::string &errString) const
#     269                 :         64 : {
#     270                 :         64 :     CTxMemPoolEntry::Parents staged_ancestors;
#     271                 :         64 :     size_t total_size = 0;
#     272         [ +  + ]:        563 :     for (const auto& tx : package) {
#     273                 :        563 :         total_size += GetVirtualTransactionSize(*tx);
#     274         [ +  + ]:        937 :         for (const auto& input : tx->vin) {
#     275                 :        937 :             std::optional<txiter> piter = GetIter(input.prevout.hash);
#     276         [ +  + ]:        937 :             if (piter) {
#     277                 :         38 :                 staged_ancestors.insert(**piter);
#     278         [ +  + ]:         38 :                 if (staged_ancestors.size() + package.size() > limitAncestorCount) {
#     279                 :          1 :                     errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
#     280                 :          1 :                     return false;
#     281                 :          1 :                 }
#     282                 :         38 :             }
#     283                 :        937 :         }
#     284                 :        563 :     }
#     285                 :            :     // When multiple transactions are passed in, the ancestors and descendants of all transactions
#     286                 :            :     // considered together must be within limits even if they are not interdependent. This may be
#     287                 :            :     // stricter than the limits for each individual transaction.
#     288                 :         63 :     setEntries setAncestors;
#     289                 :         63 :     const auto ret = CalculateAncestorsAndCheckLimits(total_size, package.size(),
#     290                 :         63 :                                                       setAncestors, staged_ancestors,
#     291                 :         63 :                                                       limitAncestorCount, limitAncestorSize,
#     292                 :         63 :                                                       limitDescendantCount, limitDescendantSize, errString);
#     293                 :            :     // It's possible to overestimate the ancestor/descendant totals.
#     294         [ +  + ]:         63 :     if (!ret) errString.insert(0, "possibly ");
#     295                 :         63 :     return ret;
#     296                 :         64 : }
#     297                 :            : 
#     298                 :            : bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry,
#     299                 :            :                                            setEntries &setAncestors,
#     300                 :            :                                            uint64_t limitAncestorCount,
#     301                 :            :                                            uint64_t limitAncestorSize,
#     302                 :            :                                            uint64_t limitDescendantCount,
#     303                 :            :                                            uint64_t limitDescendantSize,
#     304                 :            :                                            std::string &errString,
#     305                 :            :                                            bool fSearchForParents /* = true */) const
#     306                 :   11177188 : {
#     307                 :   11177188 :     CTxMemPoolEntry::Parents staged_ancestors;
#     308                 :   11177188 :     const CTransaction &tx = entry.GetTx();
#     309                 :            : 
#     310         [ +  + ]:   11177188 :     if (fSearchForParents) {
#     311                 :            :         // Get parents of this transaction that are in the mempool
#     312                 :            :         // GetMemPoolParents() is only valid for entries in the mempool, so we
#     313                 :            :         // iterate mapTx to find parents.
#     314         [ +  + ]:   25258853 :         for (unsigned int i = 0; i < tx.vin.size(); i++) {
#     315                 :   14158790 :             std::optional<txiter> piter = GetIter(tx.vin[i].prevout.hash);
#     316         [ +  + ]:   14158790 :             if (piter) {
#     317                 :     165942 :                 staged_ancestors.insert(**piter);
#     318         [ +  + ]:     165942 :                 if (staged_ancestors.size() + 1 > limitAncestorCount) {
#     319                 :          1 :                     errString = strprintf("too many unconfirmed parents [limit: %u]", limitAncestorCount);
#     320                 :          1 :                     return false;
#     321                 :          1 :                 }
#     322                 :     165942 :             }
#     323                 :   14158790 :         }
#     324                 :   11100064 :     } else {
#     325                 :            :         // If we're not searching for parents, we require this to already be an
#     326                 :            :         // entry in the mempool and use the entry's cached parents.
#     327                 :      77124 :         txiter it = mapTx.iterator_to(entry);
#     328                 :      77124 :         staged_ancestors = it->GetMemPoolParentsConst();
#     329                 :      77124 :     }
#     330                 :            : 
#     331                 :   11177187 :     return CalculateAncestorsAndCheckLimits(entry.GetTxSize(), /*entry_count=*/1,
#     332                 :   11177187 :                                             setAncestors, staged_ancestors,
#     333                 :   11177187 :                                             limitAncestorCount, limitAncestorSize,
#     334                 :   11177187 :                                             limitDescendantCount, limitDescendantSize, errString);
#     335                 :   11177188 : }
#     336                 :            : 
#     337                 :            : void CTxMemPool::UpdateAncestorsOf(bool add, txiter it, setEntries &setAncestors)
#     338                 :     142163 : {
#     339                 :     142163 :     const CTxMemPoolEntry::Parents& parents = it->GetMemPoolParentsConst();
#     340                 :            :     // add or remove this tx as a child of each parent
#     341         [ +  + ]:     142163 :     for (const CTxMemPoolEntry& parent : parents) {
#     342                 :       9438 :         UpdateChild(mapTx.iterator_to(parent), it, add);
#     343                 :       9438 :     }
#     344         [ +  + ]:     142163 :     const int64_t updateCount = (add ? 1 : -1);
#     345                 :     142163 :     const int64_t updateSize = updateCount * it->GetTxSize();
#     346                 :     142163 :     const CAmount updateFee = updateCount * it->GetModifiedFee();
#     347         [ +  + ]:    2034775 :     for (txiter ancestorIt : setAncestors) {
#     348                 :    2034775 :         mapTx.modify(ancestorIt, update_descendant_state(updateSize, updateFee, updateCount));
#     349                 :    2034775 :     }
#     350                 :     142163 : }
#     351                 :            : 
#     352                 :            : void CTxMemPool::UpdateEntryForAncestors(txiter it, const setEntries &setAncestors)
#     353                 :      73632 : {
#     354                 :      73632 :     int64_t updateCount = setAncestors.size();
#     355                 :      73632 :     int64_t updateSize = 0;
#     356                 :      73632 :     CAmount updateFee = 0;
#     357                 :      73632 :     int64_t updateSigOpsCost = 0;
#     358         [ +  + ]:    2031597 :     for (txiter ancestorIt : setAncestors) {
#     359                 :    2031597 :         updateSize += ancestorIt->GetTxSize();
#     360                 :    2031597 :         updateFee += ancestorIt->GetModifiedFee();
#     361                 :    2031597 :         updateSigOpsCost += ancestorIt->GetSigOpCost();
#     362                 :    2031597 :     }
#     363                 :      73632 :     mapTx.modify(it, update_ancestor_state(updateSize, updateFee, updateCount, updateSigOpsCost));
#     364                 :      73632 : }
#     365                 :            : 
#     366                 :            : void CTxMemPool::UpdateChildrenForRemoval(txiter it)
#     367                 :      68531 : {
#     368                 :      68531 :     const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
#     369         [ +  + ]:      68531 :     for (const CTxMemPoolEntry& updateIt : children) {
#     370                 :       2684 :         UpdateParent(mapTx.iterator_to(updateIt), it, false);
#     371                 :       2684 :     }
#     372                 :      68531 : }
#     373                 :            : 
#     374                 :            : void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants)
#     375                 :     118473 : {
#     376                 :            :     // For each entry, walk back all ancestors and decrement size associated with this
#     377                 :            :     // transaction
#     378                 :     118473 :     const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     379         [ +  + ]:     118473 :     if (updateDescendants) {
#     380                 :            :         // updateDescendants should be true whenever we're not recursively
#     381                 :            :         // removing a tx and all its descendants, eg when a transaction is
#     382                 :            :         // confirmed in a block.
#     383                 :            :         // Here we only update statistics and not data in CTxMemPool::Parents
#     384                 :            :         // and CTxMemPoolEntry::Children (which we need to preserve until we're
#     385                 :            :         // finished with all operations that need to traverse the mempool).
#     386         [ +  + ]:      66986 :         for (txiter removeIt : entriesToRemove) {
#     387                 :      66986 :             setEntries setDescendants;
#     388                 :      66986 :             CalculateDescendants(removeIt, setDescendants);
#     389                 :      66986 :             setDescendants.erase(removeIt); // don't update state for self
#     390                 :      66986 :             int64_t modifySize = -((int64_t)removeIt->GetTxSize());
#     391                 :      66986 :             CAmount modifyFee = -removeIt->GetModifiedFee();
#     392                 :      66986 :             int modifySigOps = -removeIt->GetSigOpCost();
#     393         [ +  + ]:      66986 :             for (txiter dit : setDescendants) {
#     394                 :       8372 :                 mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps));
#     395                 :       8372 :             }
#     396                 :      66986 :         }
#     397                 :      66986 :     }
#     398         [ +  + ]:     118473 :     for (txiter removeIt : entriesToRemove) {
#     399                 :      68531 :         setEntries setAncestors;
#     400                 :      68531 :         const CTxMemPoolEntry &entry = *removeIt;
#     401                 :      68531 :         std::string dummy;
#     402                 :            :         // Since this is a tx that is already in the mempool, we can call CMPA
#     403                 :            :         // with fSearchForParents = false.  If the mempool is in a consistent
#     404                 :            :         // state, then using true or false should both be correct, though false
#     405                 :            :         // should be a bit faster.
#     406                 :            :         // However, if we happen to be in the middle of processing a reorg, then
#     407                 :            :         // the mempool can be in an inconsistent state.  In this case, the set
#     408                 :            :         // of ancestors reachable via GetMemPoolParents()/GetMemPoolChildren()
#     409                 :            :         // will be the same as the set of ancestors whose packages include this
#     410                 :            :         // transaction, because when we add a new transaction to the mempool in
#     411                 :            :         // addUnchecked(), we assume it has no children, and in the case of a
#     412                 :            :         // reorg where that assumption is false, the in-mempool children aren't
#     413                 :            :         // linked to the in-block tx's until UpdateTransactionsFromBlock() is
#     414                 :            :         // called.
#     415                 :            :         // So if we're being called during a reorg, ie before
#     416                 :            :         // UpdateTransactionsFromBlock() has been called, then
#     417                 :            :         // GetMemPoolParents()/GetMemPoolChildren() will differ from the set of
#     418                 :            :         // mempool parents we'd calculate by searching, and it's important that
#     419                 :            :         // we use the cached notion of ancestor transactions as the set of
#     420                 :            :         // things to update for removal.
#     421                 :      68531 :         CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
#     422                 :            :         // Note that UpdateAncestorsOf severs the child links that point to
#     423                 :            :         // removeIt in the entries for the parents of removeIt.
#     424                 :      68531 :         UpdateAncestorsOf(false, removeIt, setAncestors);
#     425                 :      68531 :     }
#     426                 :            :     // After updating all the ancestor sizes, we can now sever the link between each
#     427                 :            :     // transaction being removed and any mempool children (ie, update CTxMemPoolEntry::m_parents
#     428                 :            :     // for each direct child of a transaction being removed).
#     429         [ +  + ]:     118473 :     for (txiter removeIt : entriesToRemove) {
#     430                 :      68531 :         UpdateChildrenForRemoval(removeIt);
#     431                 :      68531 :     }
#     432                 :     118473 : }
#     433                 :            : 
#     434                 :            : void CTxMemPoolEntry::UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount)
#     435                 :    2035097 : {
#     436                 :    2035097 :     nSizeWithDescendants += modifySize;
#     437                 :    2035097 :     assert(int64_t(nSizeWithDescendants) > 0);
#     438                 :          0 :     nModFeesWithDescendants += modifyFee;
#     439                 :    2035097 :     nCountWithDescendants += modifyCount;
#     440                 :    2035097 :     assert(int64_t(nCountWithDescendants) > 0);
#     441                 :    2035097 : }
#     442                 :            : 
#     443                 :            : void CTxMemPoolEntry::UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps)
#     444                 :      85822 : {
#     445                 :      85822 :     nSizeWithAncestors += modifySize;
#     446                 :      85822 :     assert(int64_t(nSizeWithAncestors) > 0);
#     447                 :          0 :     nModFeesWithAncestors += modifyFee;
#     448                 :      85822 :     nCountWithAncestors += modifyCount;
#     449                 :      85822 :     assert(int64_t(nCountWithAncestors) > 0);
#     450                 :          0 :     nSigOpCostWithAncestors += modifySigOps;
#     451                 :      85822 :     assert(int(nSigOpCostWithAncestors) >= 0);
#     452                 :      85822 : }
#     453                 :            : 
#     454                 :            : CTxMemPool::CTxMemPool(CBlockPolicyEstimator* estimator, int check_ratio)
#     455                 :            :     : m_check_ratio(check_ratio), minerPolicyEstimator(estimator)
#     456                 :       6734 : {
#     457                 :       6734 :     _clear(); //lock free clear
#     458                 :       6734 : }
#     459                 :            : 
#     460                 :            : bool CTxMemPool::isSpent(const COutPoint& outpoint) const
#     461                 :       4989 : {
#     462                 :       4989 :     LOCK(cs);
#     463                 :       4989 :     return mapNextTx.count(outpoint);
#     464                 :       4989 : }
#     465                 :            : 
#     466                 :            : unsigned int CTxMemPool::GetTransactionsUpdated() const
#     467                 :         58 : {
#     468                 :         58 :     return nTransactionsUpdated;
#     469                 :         58 : }
#     470                 :            : 
#     471                 :            : void CTxMemPool::AddTransactionsUpdated(unsigned int n)
#     472                 :      66452 : {
#     473                 :      66452 :     nTransactionsUpdated += n;
#     474                 :      66452 : }
#     475                 :            : 
#     476                 :            : void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, setEntries &setAncestors, bool validFeeEstimate)
#     477                 :      73632 : {
#     478                 :            :     // Add to memory pool without checking anything.
#     479                 :            :     // Used by AcceptToMemoryPool(), which DOES do
#     480                 :            :     // all the appropriate checks.
#     481                 :      73632 :     indexed_transaction_set::iterator newit = mapTx.insert(entry).first;
#     482                 :            : 
#     483                 :            :     // Update transaction for any feeDelta created by PrioritiseTransaction
#     484                 :      73632 :     CAmount delta{0};
#     485                 :      73632 :     ApplyDelta(entry.GetTx().GetHash(), delta);
#     486         [ +  + ]:      73632 :     if (delta) {
#     487                 :         13 :         mapTx.modify(newit, [&delta](CTxMemPoolEntry& e) { e.UpdateFeeDelta(delta); });
#     488                 :         13 :     }
#     489                 :            : 
#     490                 :            :     // Update cachedInnerUsage to include contained transaction's usage.
#     491                 :            :     // (When we update the entry for in-mempool parents, memory usage will be
#     492                 :            :     // further updated.)
#     493                 :      73632 :     cachedInnerUsage += entry.DynamicMemoryUsage();
#     494                 :            : 
#     495                 :      73632 :     const CTransaction& tx = newit->GetTx();
#     496                 :      73632 :     std::set<uint256> setParentTransactions;
#     497         [ +  + ]:     165038 :     for (unsigned int i = 0; i < tx.vin.size(); i++) {
#     498                 :      91406 :         mapNextTx.insert(std::make_pair(&tx.vin[i].prevout, &tx));
#     499                 :      91406 :         setParentTransactions.insert(tx.vin[i].prevout.hash);
#     500                 :      91406 :     }
#     501                 :            :     // Don't bother worrying about child transactions of this one.
#     502                 :            :     // Normal case of a new transaction arriving is that there can't be any
#     503                 :            :     // children, because such children would be orphans.
#     504                 :            :     // An exception to that is if a transaction enters that used to be in a block.
#     505                 :            :     // In that case, our disconnect block logic will call UpdateTransactionsFromBlock
#     506                 :            :     // to clean up the mess we're leaving here.
#     507                 :            : 
#     508                 :            :     // Update ancestors with information about this tx
#     509         [ +  + ]:      73632 :     for (const auto& pit : GetIterSet(setParentTransactions)) {
#     510                 :       8886 :             UpdateParent(newit, pit, true);
#     511                 :       8886 :     }
#     512                 :      73632 :     UpdateAncestorsOf(true, newit, setAncestors);
#     513                 :      73632 :     UpdateEntryForAncestors(newit, setAncestors);
#     514                 :            : 
#     515                 :      73632 :     nTransactionsUpdated++;
#     516                 :      73632 :     totalTxSize += entry.GetTxSize();
#     517                 :      73632 :     m_total_fee += entry.GetFee();
#     518         [ +  + ]:      73632 :     if (minerPolicyEstimator) {
#     519                 :      73508 :         minerPolicyEstimator->processTransaction(entry, validFeeEstimate);
#     520                 :      73508 :     }
#     521                 :            : 
#     522                 :      73632 :     vTxHashes.emplace_back(tx.GetWitnessHash(), newit);
#     523                 :      73632 :     newit->vTxHashesIdx = vTxHashes.size() - 1;
#     524                 :      73632 : }
#     525                 :            : 
#     526                 :            : void CTxMemPool::removeUnchecked(txiter it, MemPoolRemovalReason reason)
#     527                 :      68531 : {
#     528                 :            :     // We increment mempool sequence value no matter removal reason
#     529                 :            :     // even if not directly reported below.
#     530                 :      68531 :     uint64_t mempool_sequence = GetAndIncrementSequence();
#     531                 :            : 
#     532         [ +  + ]:      68531 :     if (reason != MemPoolRemovalReason::BLOCK) {
#     533                 :            :         // Notify clients that a transaction has been removed from the mempool
#     534                 :            :         // for any reason except being included in a block. Clients interested
#     535                 :            :         // in transactions included in blocks can subscribe to the BlockConnected
#     536                 :            :         // notification.
#     537                 :       1545 :         GetMainSignals().TransactionRemovedFromMempool(it->GetSharedTx(), reason, mempool_sequence);
#     538                 :       1545 :     }
#     539                 :            : 
#     540                 :      68531 :     const uint256 hash = it->GetTx().GetHash();
#     541         [ +  + ]:      68531 :     for (const CTxIn& txin : it->GetTx().vin)
#     542                 :      80131 :         mapNextTx.erase(txin.prevout);
#     543                 :            : 
#     544                 :      68531 :     RemoveUnbroadcastTx(hash, true /* add logging because unchecked */ );
#     545                 :            : 
#     546         [ +  + ]:      68531 :     if (vTxHashes.size() > 1) {
#     547                 :      65862 :         vTxHashes[it->vTxHashesIdx] = std::move(vTxHashes.back());
#     548                 :      65862 :         vTxHashes[it->vTxHashesIdx].second->vTxHashesIdx = it->vTxHashesIdx;
#     549                 :      65862 :         vTxHashes.pop_back();
#     550         [ +  + ]:      65862 :         if (vTxHashes.size() * 2 < vTxHashes.capacity())
#     551                 :       5070 :             vTxHashes.shrink_to_fit();
#     552                 :      65862 :     } else
#     553                 :       2669 :         vTxHashes.clear();
#     554                 :            : 
#     555                 :      68531 :     totalTxSize -= it->GetTxSize();
#     556                 :      68531 :     m_total_fee -= it->GetFee();
#     557                 :      68531 :     cachedInnerUsage -= it->DynamicMemoryUsage();
#     558                 :      68531 :     cachedInnerUsage -= memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
#     559                 :      68531 :     mapTx.erase(it);
#     560                 :      68531 :     nTransactionsUpdated++;
#     561         [ +  + ]:      68531 :     if (minerPolicyEstimator) {minerPolicyEstimator->removeTx(hash, false);}
#     562                 :      68531 : }
#     563                 :            : 
#     564                 :            : // Calculates descendants of entry that are not already in setDescendants, and adds to
#     565                 :            : // setDescendants. Assumes entryit is already a tx in the mempool and CTxMemPoolEntry::m_children
#     566                 :            : // is correct for tx and all descendants.
#     567                 :            : // Also assumes that if an entry is in setDescendants already, then all
#     568                 :            : // in-mempool descendants of it are already in setDescendants as well, so that we
#     569                 :            : // can save time by not iterating over those entries.
#     570                 :            : void CTxMemPool::CalculateDescendants(txiter entryit, setEntries& setDescendants) const
#     571                 :      81459 : {
#     572                 :      81459 :     setEntries stage;
#     573         [ +  - ]:      81459 :     if (setDescendants.count(entryit) == 0) {
#     574                 :      81459 :         stage.insert(entryit);
#     575                 :      81459 :     }
#     576                 :            :     // Traverse down the children of entry, only adding children that are not
#     577                 :            :     // accounted for in setDescendants already (because those children have either
#     578                 :            :     // already been walked, or will be walked in this iteration).
#     579         [ +  + ]:    2198050 :     while (!stage.empty()) {
#     580                 :    2116591 :         txiter it = *stage.begin();
#     581                 :    2116591 :         setDescendants.insert(it);
#     582                 :    2116591 :         stage.erase(it);
#     583                 :            : 
#     584                 :    2116591 :         const CTxMemPoolEntry::Children& children = it->GetMemPoolChildrenConst();
#     585         [ +  + ]:    2116591 :         for (const CTxMemPoolEntry& child : children) {
#     586                 :    2048948 :             txiter childiter = mapTx.iterator_to(child);
#     587         [ +  + ]:    2048948 :             if (!setDescendants.count(childiter)) {
#     588                 :    2042424 :                 stage.insert(childiter);
#     589                 :    2042424 :             }
#     590                 :    2048948 :         }
#     591                 :    2116591 :     }
#     592                 :      81459 : }
#     593                 :            : 
#     594                 :            : void CTxMemPool::removeRecursive(const CTransaction &origTx, MemPoolRemovalReason reason)
#     595                 :       9678 : {
#     596                 :            :     // Remove transaction from memory pool
#     597                 :       9678 :     AssertLockHeld(cs);
#     598                 :       9678 :         setEntries txToRemove;
#     599                 :       9678 :         txiter origit = mapTx.find(origTx.GetHash());
#     600         [ +  + ]:       9678 :         if (origit != mapTx.end()) {
#     601                 :         94 :             txToRemove.insert(origit);
#     602                 :       9584 :         } else {
#     603                 :            :             // When recursively removing but origTx isn't in the mempool
#     604                 :            :             // be sure to remove any children that are in the pool. This can
#     605                 :            :             // happen during chain re-orgs if origTx isn't re-accepted into
#     606                 :            :             // the mempool for any reason.
#     607         [ +  + ]:      21199 :             for (unsigned int i = 0; i < origTx.vout.size(); i++) {
#     608                 :      11615 :                 auto it = mapNextTx.find(COutPoint(origTx.GetHash(), i));
#     609         [ +  + ]:      11615 :                 if (it == mapNextTx.end())
#     610                 :      11540 :                     continue;
#     611                 :         75 :                 txiter nextit = mapTx.find(it->second->GetHash());
#     612                 :         75 :                 assert(nextit != mapTx.end());
#     613                 :          0 :                 txToRemove.insert(nextit);
#     614                 :         75 :             }
#     615                 :       9584 :         }
#     616                 :       9678 :         setEntries setAllRemoves;
#     617         [ +  + ]:       9678 :         for (txiter it : txToRemove) {
#     618                 :        169 :             CalculateDescendants(it, setAllRemoves);
#     619                 :        169 :         }
#     620                 :            : 
#     621                 :       9678 :         RemoveStaged(setAllRemoves, false, reason);
#     622                 :       9678 : }
#     623                 :            : 
#     624                 :            : void CTxMemPool::removeForReorg(CChain& chain, std::function<bool(txiter)> check_final_and_mature)
#     625                 :       1036 : {
#     626                 :            :     // Remove transactions spending a coinbase which are now immature and no-longer-final transactions
#     627                 :       1036 :     AssertLockHeld(cs);
#     628                 :       1036 :     AssertLockHeld(::cs_main);
#     629                 :            : 
#     630                 :       1036 :     setEntries txToRemove;
#     631         [ +  + ]:       1850 :     for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
#     632         [ +  + ]:        814 :         if (check_final_and_mature(it)) txToRemove.insert(it);
#     633                 :        814 :     }
#     634                 :       1036 :     setEntries setAllRemoves;
#     635         [ +  + ]:       1036 :     for (txiter it : txToRemove) {
#     636                 :         16 :         CalculateDescendants(it, setAllRemoves);
#     637                 :         16 :     }
#     638                 :       1036 :     RemoveStaged(setAllRemoves, false, MemPoolRemovalReason::REORG);
#     639         [ +  + ]:       1834 :     for (indexed_transaction_set::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) {
#     640                 :        798 :         assert(TestLockPointValidity(chain, it->GetLockPoints()));
#     641                 :        798 :     }
#     642                 :       1036 : }
#     643                 :            : 
#     644                 :            : void CTxMemPool::removeConflicts(const CTransaction &tx)
#     645                 :     154852 : {
#     646                 :            :     // Remove transactions which depend on inputs of tx, recursively
#     647                 :     154852 :     AssertLockHeld(cs);
#     648         [ +  + ]:     182059 :     for (const CTxIn &txin : tx.vin) {
#     649                 :     182059 :         auto it = mapNextTx.find(txin.prevout);
#     650         [ +  + ]:     182059 :         if (it != mapNextTx.end()) {
#     651                 :         78 :             const CTransaction &txConflict = *it->second;
#     652         [ +  - ]:         78 :             if (txConflict != tx)
#     653                 :         78 :             {
#     654                 :         78 :                 ClearPrioritisation(txConflict.GetHash());
#     655                 :         78 :                 removeRecursive(txConflict, MemPoolRemovalReason::CONFLICT);
#     656                 :         78 :             }
#     657                 :         78 :         }
#     658                 :     182059 :     }
#     659                 :     154852 : }
#     660                 :            : 
#     661                 :            : /**
#     662                 :            :  * Called when a block is connected. Removes from mempool and updates the miner fee estimator.
#     663                 :            :  */
#     664                 :            : void CTxMemPool::removeForBlock(const std::vector<CTransactionRef>& vtx, unsigned int nBlockHeight)
#     665                 :      63159 : {
#     666                 :      63159 :     AssertLockHeld(cs);
#     667                 :      63159 :     std::vector<const CTxMemPoolEntry*> entries;
#     668         [ +  + ]:      63159 :     for (const auto& tx : vtx)
#     669                 :     154852 :     {
#     670                 :     154852 :         uint256 hash = tx->GetHash();
#     671                 :            : 
#     672                 :     154852 :         indexed_transaction_set::iterator i = mapTx.find(hash);
#     673         [ +  + ]:     154852 :         if (i != mapTx.end())
#     674                 :      66986 :             entries.push_back(&*i);
#     675                 :     154852 :     }
#     676                 :            :     // Before the txs in the new block have been removed from the mempool, update policy estimates
#     677         [ +  + ]:      63159 :     if (minerPolicyEstimator) {minerPolicyEstimator->processBlock(nBlockHeight, entries);}
#     678         [ +  + ]:      63159 :     for (const auto& tx : vtx)
#     679                 :     154852 :     {
#     680                 :     154852 :         txiter it = mapTx.find(tx->GetHash());
#     681         [ +  + ]:     154852 :         if (it != mapTx.end()) {
#     682                 :      66986 :             setEntries stage;
#     683                 :      66986 :             stage.insert(it);
#     684                 :      66986 :             RemoveStaged(stage, true, MemPoolRemovalReason::BLOCK);
#     685                 :      66986 :         }
#     686                 :     154852 :         removeConflicts(*tx);
#     687                 :     154852 :         ClearPrioritisation(tx->GetHash());
#     688                 :     154852 :     }
#     689                 :      63159 :     lastRollingFeeUpdate = GetTime();
#     690                 :      63159 :     blockSinceLastRollingFeeBump = true;
#     691                 :      63159 : }
#     692                 :            : 
#     693                 :            : void CTxMemPool::_clear()
#     694                 :       7902 : {
#     695                 :       7902 :     vTxHashes.clear();
#     696                 :       7902 :     mapTx.clear();
#     697                 :       7902 :     mapNextTx.clear();
#     698                 :       7902 :     totalTxSize = 0;
#     699                 :       7902 :     m_total_fee = 0;
#     700                 :       7902 :     cachedInnerUsage = 0;
#     701                 :       7902 :     lastRollingFeeUpdate = GetTime();
#     702                 :       7902 :     blockSinceLastRollingFeeBump = false;
#     703                 :       7902 :     rollingMinimumFeeRate = 0;
#     704                 :       7902 :     ++nTransactionsUpdated;
#     705                 :       7902 : }
#     706                 :            : 
#     707                 :            : void CTxMemPool::clear()
#     708                 :       1168 : {
#     709                 :       1168 :     LOCK(cs);
#     710                 :       1168 :     _clear();
#     711                 :       1168 : }
#     712                 :            : 
#     713                 :            : void CTxMemPool::check(const CCoinsViewCache& active_coins_tip, int64_t spendheight) const
#     714                 :      96312 : {
#     715         [ +  + ]:      96312 :     if (m_check_ratio == 0) return;
#     716                 :            : 
#     717         [ -  + ]:      96288 :     if (GetRand(m_check_ratio) >= 1) return;
#     718                 :            : 
#     719                 :      96288 :     AssertLockHeld(::cs_main);
#     720                 :      96288 :     LOCK(cs);
#     721         [ +  - ]:      96288 :     LogPrint(BCLog::MEMPOOL, "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size());
#     722                 :            : 
#     723                 :      96288 :     uint64_t checkTotal = 0;
#     724                 :      96288 :     CAmount check_total_fee{0};
#     725                 :      96288 :     uint64_t innerUsage = 0;
#     726                 :      96288 :     uint64_t prev_ancestor_count{0};
#     727                 :            : 
#     728                 :      96288 :     CCoinsViewCache mempoolDuplicate(const_cast<CCoinsViewCache*>(&active_coins_tip));
#     729                 :            : 
#     730         [ +  + ]:   11013105 :     for (const auto& it : GetSortedDepthAndScore()) {
#     731                 :   11013105 :         checkTotal += it->GetTxSize();
#     732                 :   11013105 :         check_total_fee += it->GetFee();
#     733                 :   11013105 :         innerUsage += it->DynamicMemoryUsage();
#     734                 :   11013105 :         const CTransaction& tx = it->GetTx();
#     735                 :   11013105 :         innerUsage += memusage::DynamicUsage(it->GetMemPoolParentsConst()) + memusage::DynamicUsage(it->GetMemPoolChildrenConst());
#     736                 :   11013105 :         CTxMemPoolEntry::Parents setParentCheck;
#     737         [ +  + ]:   14028842 :         for (const CTxIn &txin : tx.vin) {
#     738                 :            :             // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's.
#     739                 :   14028842 :             indexed_transaction_set::const_iterator it2 = mapTx.find(txin.prevout.hash);
#     740         [ +  + ]:   14028842 :             if (it2 != mapTx.end()) {
#     741                 :     153385 :                 const CTransaction& tx2 = it2->GetTx();
#     742                 :     153385 :                 assert(tx2.vout.size() > txin.prevout.n && !tx2.vout[txin.prevout.n].IsNull());
#     743                 :          0 :                 setParentCheck.insert(*it2);
#     744                 :     153385 :             }
#     745                 :            :             // We are iterating through the mempool entries sorted in order by ancestor count.
#     746                 :            :             // All parents must have been checked before their children and their coins added to
#     747                 :            :             // the mempoolDuplicate coins cache.
#     748                 :          0 :             assert(mempoolDuplicate.HaveCoin(txin.prevout));
#     749                 :            :             // Check whether its inputs are marked in mapNextTx.
#     750                 :          0 :             auto it3 = mapNextTx.find(txin.prevout);
#     751                 :   14028842 :             assert(it3 != mapNextTx.end());
#     752                 :          0 :             assert(it3->first == &txin.prevout);
#     753                 :          0 :             assert(it3->second == &tx);
#     754                 :   14028842 :         }
#     755                 :   11013105 :         auto comp = [](const CTxMemPoolEntry& a, const CTxMemPoolEntry& b) -> bool {
#     756                 :     305132 :             return a.GetTx().GetHash() == b.GetTx().GetHash();
#     757                 :     305132 :         };
#     758                 :   11013105 :         assert(setParentCheck.size() == it->GetMemPoolParentsConst().size());
#     759                 :          0 :         assert(std::equal(setParentCheck.begin(), setParentCheck.end(), it->GetMemPoolParentsConst().begin(), comp));
#     760                 :            :         // Verify ancestor state is correct.
#     761                 :          0 :         setEntries setAncestors;
#     762                 :   11013105 :         uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     763                 :   11013105 :         std::string dummy;
#     764                 :   11013105 :         CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
#     765                 :   11013105 :         uint64_t nCountCheck = setAncestors.size() + 1;
#     766                 :   11013105 :         uint64_t nSizeCheck = it->GetTxSize();
#     767                 :   11013105 :         CAmount nFeesCheck = it->GetModifiedFee();
#     768                 :   11013105 :         int64_t nSigOpCheck = it->GetSigOpCost();
#     769                 :            : 
#     770         [ +  + ]:   11013105 :         for (txiter ancestorIt : setAncestors) {
#     771                 :     584937 :             nSizeCheck += ancestorIt->GetTxSize();
#     772                 :     584937 :             nFeesCheck += ancestorIt->GetModifiedFee();
#     773                 :     584937 :             nSigOpCheck += ancestorIt->GetSigOpCost();
#     774                 :     584937 :         }
#     775                 :            : 
#     776                 :   11013105 :         assert(it->GetCountWithAncestors() == nCountCheck);
#     777                 :          0 :         assert(it->GetSizeWithAncestors() == nSizeCheck);
#     778                 :          0 :         assert(it->GetSigOpCostWithAncestors() == nSigOpCheck);
#     779                 :          0 :         assert(it->GetModFeesWithAncestors() == nFeesCheck);
#     780                 :            :         // Sanity check: we are walking in ascending ancestor count order.
#     781                 :          0 :         assert(prev_ancestor_count <= it->GetCountWithAncestors());
#     782                 :          0 :         prev_ancestor_count = it->GetCountWithAncestors();
#     783                 :            : 
#     784                 :            :         // Check children against mapNextTx
#     785                 :   11013105 :         CTxMemPoolEntry::Children setChildrenCheck;
#     786                 :   11013105 :         auto iter = mapNextTx.lower_bound(COutPoint(it->GetTx().GetHash(), 0));
#     787                 :   11013105 :         uint64_t child_sizes = 0;
#     788 [ +  + ][ +  + ]:   11166490 :         for (; iter != mapNextTx.end() && iter->first->hash == it->GetTx().GetHash(); ++iter) {
#                 [ +  + ]
#     789                 :     153385 :             txiter childit = mapTx.find(iter->second->GetHash());
#     790                 :     153385 :             assert(childit != mapTx.end()); // mapNextTx points to in-mempool transactions
#     791         [ +  + ]:     153385 :             if (setChildrenCheck.insert(*childit).second) {
#     792                 :     152566 :                 child_sizes += childit->GetTxSize();
#     793                 :     152566 :             }
#     794                 :     153385 :         }
#     795                 :   11013105 :         assert(setChildrenCheck.size() == it->GetMemPoolChildrenConst().size());
#     796                 :          0 :         assert(std::equal(setChildrenCheck.begin(), setChildrenCheck.end(), it->GetMemPoolChildrenConst().begin(), comp));
#     797                 :            :         // Also check to make sure size is greater than sum with immediate children.
#     798                 :            :         // just a sanity check, not definitive that this calc is correct...
#     799                 :          0 :         assert(it->GetSizeWithDescendants() >= child_sizes + it->GetTxSize());
#     800                 :            : 
#     801                 :          0 :         TxValidationState dummy_state; // Not used. CheckTxInputs() should always pass
#     802                 :   11013105 :         CAmount txfee = 0;
#     803                 :   11013105 :         assert(!tx.IsCoinBase());
#     804                 :          0 :         assert(Consensus::CheckTxInputs(tx, dummy_state, mempoolDuplicate, spendheight, txfee));
#     805         [ +  + ]:   14028842 :         for (const auto& input: tx.vin) mempoolDuplicate.SpendCoin(input.prevout);
#     806                 :   11013105 :         AddCoins(mempoolDuplicate, tx, std::numeric_limits<int>::max());
#     807                 :   11013105 :     }
#     808         [ +  + ]:   14125130 :     for (auto it = mapNextTx.cbegin(); it != mapNextTx.cend(); it++) {
#     809                 :   14028842 :         uint256 hash = it->second->GetHash();
#     810                 :   14028842 :         indexed_transaction_set::const_iterator it2 = mapTx.find(hash);
#     811                 :   14028842 :         const CTransaction& tx = it2->GetTx();
#     812                 :   14028842 :         assert(it2 != mapTx.end());
#     813                 :          0 :         assert(&tx == it->second);
#     814                 :   14028842 :     }
#     815                 :            : 
#     816                 :      96288 :     assert(totalTxSize == checkTotal);
#     817                 :          0 :     assert(m_total_fee == check_total_fee);
#     818                 :          0 :     assert(innerUsage == cachedInnerUsage);
#     819                 :      96288 : }
#     820                 :            : 
#     821                 :            : bool CTxMemPool::CompareDepthAndScore(const uint256& hasha, const uint256& hashb, bool wtxid)
#     822                 :      62475 : {
#     823                 :      62475 :     LOCK(cs);
#     824         [ +  + ]:      62475 :     indexed_transaction_set::const_iterator i = wtxid ? get_iter_from_wtxid(hasha) : mapTx.find(hasha);
#     825         [ +  + ]:      62475 :     if (i == mapTx.end()) return false;
#     826         [ +  + ]:      37863 :     indexed_transaction_set::const_iterator j = wtxid ? get_iter_from_wtxid(hashb) : mapTx.find(hashb);
#     827         [ +  + ]:      37863 :     if (j == mapTx.end()) return true;
#     828                 :      37010 :     uint64_t counta = i->GetCountWithAncestors();
#     829                 :      37010 :     uint64_t countb = j->GetCountWithAncestors();
#     830         [ +  + ]:      37010 :     if (counta == countb) {
#     831                 :      35988 :         return CompareTxMemPoolEntryByScore()(*i, *j);
#     832                 :      35988 :     }
#     833                 :       1022 :     return counta < countb;
#     834                 :      37010 : }
#     835                 :            : 
#     836                 :            : namespace {
#     837                 :            : class DepthAndScoreComparator
#     838                 :            : {
#     839                 :            : public:
#     840                 :            :     bool operator()(const CTxMemPool::indexed_transaction_set::const_iterator& a, const CTxMemPool::indexed_transaction_set::const_iterator& b)
#     841                 :  133217179 :     {
#     842                 :  133217179 :         uint64_t counta = a->GetCountWithAncestors();
#     843                 :  133217179 :         uint64_t countb = b->GetCountWithAncestors();
#     844         [ +  + ]:  133217179 :         if (counta == countb) {
#     845                 :  132868160 :             return CompareTxMemPoolEntryByScore()(*a, *b);
#     846                 :  132868160 :         }
#     847                 :     349019 :         return counta < countb;
#     848                 :  133217179 :     }
#     849                 :            : };
#     850                 :            : } // namespace
#     851                 :            : 
#     852                 :            : std::vector<CTxMemPool::indexed_transaction_set::const_iterator> CTxMemPool::GetSortedDepthAndScore() const
#     853                 :     105989 : {
#     854                 :     105989 :     std::vector<indexed_transaction_set::const_iterator> iters;
#     855                 :     105989 :     AssertLockHeld(cs);
#     856                 :            : 
#     857                 :     105989 :     iters.reserve(mapTx.size());
#     858                 :            : 
#     859         [ +  + ]:   11513585 :     for (indexed_transaction_set::iterator mi = mapTx.begin(); mi != mapTx.end(); ++mi) {
#     860                 :   11407596 :         iters.push_back(mi);
#     861                 :   11407596 :     }
#     862                 :     105989 :     std::sort(iters.begin(), iters.end(), DepthAndScoreComparator());
#     863                 :     105989 :     return iters;
#     864                 :     105989 : }
#     865                 :            : 
#     866                 :            : void CTxMemPool::queryHashes(std::vector<uint256>& vtxid) const
#     867                 :       8983 : {
#     868                 :       8983 :     LOCK(cs);
#     869                 :       8983 :     auto iters = GetSortedDepthAndScore();
#     870                 :            : 
#     871                 :       8983 :     vtxid.clear();
#     872                 :       8983 :     vtxid.reserve(mapTx.size());
#     873                 :            : 
#     874         [ +  + ]:     393787 :     for (auto it : iters) {
#     875                 :     393787 :         vtxid.push_back(it->GetTx().GetHash());
#     876                 :     393787 :     }
#     877                 :       8983 : }
#     878                 :            : 
#     879                 :      25978 : static TxMempoolInfo GetInfo(CTxMemPool::indexed_transaction_set::const_iterator it) {
#     880                 :      25978 :     return TxMempoolInfo{it->GetSharedTx(), it->GetTime(), it->GetFee(), it->GetTxSize(), it->GetModifiedFee() - it->GetFee()};
#     881                 :      25978 : }
#     882                 :            : 
#     883                 :            : std::vector<TxMempoolInfo> CTxMemPool::infoAll() const
#     884                 :        718 : {
#     885                 :        718 :     LOCK(cs);
#     886                 :        718 :     auto iters = GetSortedDepthAndScore();
#     887                 :            : 
#     888                 :        718 :     std::vector<TxMempoolInfo> ret;
#     889                 :        718 :     ret.reserve(mapTx.size());
#     890         [ +  + ]:        718 :     for (auto it : iters) {
#     891                 :        704 :         ret.push_back(GetInfo(it));
#     892                 :        704 :     }
#     893                 :            : 
#     894                 :        718 :     return ret;
#     895                 :        718 : }
#     896                 :            : 
#     897                 :            : CTransactionRef CTxMemPool::get(const uint256& hash) const
#     898                 :     196450 : {
#     899                 :     196450 :     LOCK(cs);
#     900                 :     196450 :     indexed_transaction_set::const_iterator i = mapTx.find(hash);
#     901         [ +  + ]:     196450 :     if (i == mapTx.end())
#     902                 :     129352 :         return nullptr;
#     903                 :      67098 :     return i->GetSharedTx();
#     904                 :     196450 : }
#     905                 :            : 
#     906                 :            : TxMempoolInfo CTxMemPool::info(const GenTxid& gtxid) const
#     907                 :      27588 : {
#     908                 :      27588 :     LOCK(cs);
#     909         [ +  + ]:      27588 :     indexed_transaction_set::const_iterator i = (gtxid.IsWtxid() ? get_iter_from_wtxid(gtxid.GetHash()) : mapTx.find(gtxid.GetHash()));
#     910         [ +  + ]:      27588 :     if (i == mapTx.end())
#     911                 :       2314 :         return TxMempoolInfo();
#     912                 :      25274 :     return GetInfo(i);
#     913                 :      27588 : }
#     914                 :            : 
#     915                 :            : void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta)
#     916                 :        706 : {
#     917                 :        706 :     {
#     918                 :        706 :         LOCK(cs);
#     919                 :        706 :         CAmount &delta = mapDeltas[hash];
#     920                 :        706 :         delta += nFeeDelta;
#     921                 :        706 :         txiter it = mapTx.find(hash);
#     922         [ +  + ]:        706 :         if (it != mapTx.end()) {
#     923                 :        238 :             mapTx.modify(it, [&delta](CTxMemPoolEntry& e) { e.UpdateFeeDelta(delta); });
#     924                 :            :             // Now update all ancestors' modified fees with descendants
#     925                 :        238 :             setEntries setAncestors;
#     926                 :        238 :             uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#     927                 :        238 :             std::string dummy;
#     928                 :        238 :             CalculateMemPoolAncestors(*it, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false);
#     929         [ +  + ]:        238 :             for (txiter ancestorIt : setAncestors) {
#     930                 :         28 :                 mapTx.modify(ancestorIt, update_descendant_state(0, nFeeDelta, 0));
#     931                 :         28 :             }
#     932                 :            :             // Now update all descendants' modified fees with ancestors
#     933                 :        238 :             setEntries setDescendants;
#     934                 :        238 :             CalculateDescendants(it, setDescendants);
#     935                 :        238 :             setDescendants.erase(it);
#     936         [ +  + ]:        238 :             for (txiter descendantIt : setDescendants) {
#     937                 :         51 :                 mapTx.modify(descendantIt, update_ancestor_state(0, nFeeDelta, 0, 0));
#     938                 :         51 :             }
#     939                 :        238 :             ++nTransactionsUpdated;
#     940                 :        238 :         }
#     941                 :        706 :     }
#     942                 :        706 :     LogPrintf("PrioritiseTransaction: %s fee += %s\n", hash.ToString(), FormatMoney(nFeeDelta));
#     943                 :        706 : }
#     944                 :            : 
#     945                 :            : void CTxMemPool::ApplyDelta(const uint256& hash, CAmount &nFeeDelta) const
#     946                 :     105807 : {
#     947                 :     105807 :     AssertLockHeld(cs);
#     948                 :     105807 :     std::map<uint256, CAmount>::const_iterator pos = mapDeltas.find(hash);
#     949         [ +  + ]:     105807 :     if (pos == mapDeltas.end())
#     950                 :     105774 :         return;
#     951                 :         33 :     const CAmount &delta = pos->second;
#     952                 :         33 :     nFeeDelta += delta;
#     953                 :         33 : }
#     954                 :            : 
#     955                 :            : void CTxMemPool::ClearPrioritisation(const uint256& hash)
#     956                 :     154932 : {
#     957                 :     154932 :     AssertLockHeld(cs);
#     958                 :     154932 :     mapDeltas.erase(hash);
#     959                 :     154932 : }
#     960                 :            : 
#     961                 :            : const CTransaction* CTxMemPool::GetConflictTx(const COutPoint& prevout) const
#     962                 :      71172 : {
#     963                 :      71172 :     const auto it = mapNextTx.find(prevout);
#     964         [ +  + ]:      71172 :     return it == mapNextTx.end() ? nullptr : it->second;
#     965                 :      71172 : }
#     966                 :            : 
#     967                 :            : std::optional<CTxMemPool::txiter> CTxMemPool::GetIter(const uint256& txid) const
#     968                 :   14262891 : {
#     969                 :   14262891 :     auto it = mapTx.find(txid);
#     970         [ +  + ]:   14262891 :     if (it != mapTx.end()) return it;
#     971                 :   14075437 :     return std::nullopt;
#     972                 :   14262891 : }
#     973                 :            : 
#     974                 :            : CTxMemPool::setEntries CTxMemPool::GetIterSet(const std::set<uint256>& hashes) const
#     975                 :     101731 : {
#     976                 :     101731 :     CTxMemPool::setEntries ret;
#     977         [ +  + ]:     101731 :     for (const auto& h : hashes) {
#     978                 :      92415 :         const auto mi = GetIter(h);
#     979         [ +  + ]:      92415 :         if (mi) ret.insert(*mi);
#     980                 :      92415 :     }
#     981                 :     101731 :     return ret;
#     982                 :     101731 : }
#     983                 :            : 
#     984                 :            : bool CTxMemPool::HasNoInputsOf(const CTransaction &tx) const
#     985                 :      19518 : {
#     986         [ +  + ]:      50267 :     for (unsigned int i = 0; i < tx.vin.size(); i++)
#     987         [ +  + ]:      33159 :         if (exists(GenTxid::Txid(tx.vin[i].prevout.hash)))
#     988                 :       2410 :             return false;
#     989                 :      17108 :     return true;
#     990                 :      19518 : }
#     991                 :            : 
#     992                 :      45427 : CCoinsViewMemPool::CCoinsViewMemPool(CCoinsView* baseIn, const CTxMemPool& mempoolIn) : CCoinsViewBacked(baseIn), mempool(mempoolIn) { }
#     993                 :            : 
#     994                 :      82072 : bool CCoinsViewMemPool::GetCoin(const COutPoint &outpoint, Coin &coin) const {
#     995                 :            :     // Check to see if the inputs are made available by another tx in the package.
#     996                 :            :     // These Coins would not be available in the underlying CoinsView.
#     997         [ +  + ]:      82072 :     if (auto it = m_temp_added.find(outpoint); it != m_temp_added.end()) {
#     998                 :        492 :         coin = it->second;
#     999                 :        492 :         return true;
#    1000                 :        492 :     }
#    1001                 :            : 
#    1002                 :            :     // If an entry in the mempool exists, always return that one, as it's guaranteed to never
#    1003                 :            :     // conflict with the underlying cache, and it cannot have pruned entries (as it contains full)
#    1004                 :            :     // transactions. First checking the underlying cache risks returning a pruned entry instead.
#    1005                 :      81580 :     CTransactionRef ptx = mempool.get(outpoint.hash);
#    1006         [ +  + ]:      81580 :     if (ptx) {
#    1007         [ +  - ]:       9961 :         if (outpoint.n < ptx->vout.size()) {
#    1008                 :       9961 :             coin = Coin(ptx->vout[outpoint.n], MEMPOOL_HEIGHT, false);
#    1009                 :       9961 :             return true;
#    1010                 :       9961 :         } else {
#    1011                 :          0 :             return false;
#    1012                 :          0 :         }
#    1013                 :       9961 :     }
#    1014                 :      71619 :     return base->GetCoin(outpoint, coin);
#    1015                 :      81580 : }
#    1016                 :            : 
#    1017                 :            : void CCoinsViewMemPool::PackageAddTransaction(const CTransactionRef& tx)
#    1018                 :        577 : {
#    1019         [ +  + ]:       1544 :     for (unsigned int n = 0; n < tx->vout.size(); ++n) {
#    1020                 :        967 :         m_temp_added.emplace(COutPoint(tx->GetHash(), n), Coin(tx->vout[n], MEMPOOL_HEIGHT, false));
#    1021                 :        967 :     }
#    1022                 :        577 : }
#    1023                 :            : 
#    1024                 :     256530 : size_t CTxMemPool::DynamicMemoryUsage() const {
#    1025                 :     256530 :     LOCK(cs);
#    1026                 :            :     // Estimate the overhead of mapTx to be 15 pointers + an allocation, as no exact formula for boost::multi_index_contained is implemented.
#    1027                 :     256530 :     return memusage::MallocUsage(sizeof(CTxMemPoolEntry) + 15 * sizeof(void*)) * mapTx.size() + memusage::DynamicUsage(mapNextTx) + memusage::DynamicUsage(mapDeltas) + memusage::DynamicUsage(vTxHashes) + cachedInnerUsage;
#    1028                 :     256530 : }
#    1029                 :            : 
#    1030                 :      78937 : void CTxMemPool::RemoveUnbroadcastTx(const uint256& txid, const bool unchecked) {
#    1031                 :      78937 :     LOCK(cs);
#    1032                 :            : 
#    1033         [ +  + ]:      78937 :     if (m_unbroadcast_txids.erase(txid))
#    1034                 :       8977 :     {
#    1035 [ +  - ][ +  + ]:       8977 :         LogPrint(BCLog::MEMPOOL, "Removed %i from set of unbroadcast txns%s\n", txid.GetHex(), (unchecked ? " before confirmation that txn was sent out" : ""));
#    1036                 :       8977 :     }
#    1037                 :      78937 : }
#    1038                 :            : 
#    1039                 :     118473 : void CTxMemPool::RemoveStaged(setEntries &stage, bool updateDescendants, MemPoolRemovalReason reason) {
#    1040                 :     118473 :     AssertLockHeld(cs);
#    1041                 :     118473 :     UpdateForRemoveFromMempool(stage, updateDescendants);
#    1042         [ +  + ]:     118473 :     for (txiter it : stage) {
#    1043                 :      68531 :         removeUnchecked(it, reason);
#    1044                 :      68531 :     }
#    1045                 :     118473 : }
#    1046                 :            : 
#    1047                 :            : int CTxMemPool::Expire(std::chrono::seconds time)
#    1048                 :      20744 : {
#    1049                 :      20744 :     AssertLockHeld(cs);
#    1050                 :      20744 :     indexed_transaction_set::index<entry_time>::type::iterator it = mapTx.get<entry_time>().begin();
#    1051                 :      20744 :     setEntries toremove;
#    1052 [ +  + ][ +  + ]:      20746 :     while (it != mapTx.get<entry_time>().end() && it->GetTime() < time) {
#                 [ +  + ]
#    1053                 :          2 :         toremove.insert(mapTx.project<0>(it));
#    1054                 :          2 :         it++;
#    1055                 :          2 :     }
#    1056                 :      20744 :     setEntries stage;
#    1057         [ +  + ]:      20744 :     for (txiter removeit : toremove) {
#    1058                 :          2 :         CalculateDescendants(removeit, stage);
#    1059                 :          2 :     }
#    1060                 :      20744 :     RemoveStaged(stage, false, MemPoolRemovalReason::EXPIRY);
#    1061                 :      20744 :     return stage.size();
#    1062                 :      20744 : }
#    1063                 :            : 
#    1064                 :            : void CTxMemPool::addUnchecked(const CTxMemPoolEntry &entry, bool validFeeEstimate)
#    1065                 :      53616 : {
#    1066                 :      53616 :     setEntries setAncestors;
#    1067                 :      53616 :     uint64_t nNoLimit = std::numeric_limits<uint64_t>::max();
#    1068                 :      53616 :     std::string dummy;
#    1069                 :      53616 :     CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy);
#    1070                 :      53616 :     return addUnchecked(entry, setAncestors, validFeeEstimate);
#    1071                 :      53616 : }
#    1072                 :            : 
#    1073                 :            : void CTxMemPool::UpdateChild(txiter entry, txiter child, bool add)
#    1074                 :      13199 : {
#    1075                 :      13199 :     AssertLockHeld(cs);
#    1076                 :      13199 :     CTxMemPoolEntry::Children s;
#    1077 [ +  + ][ +  + ]:      13199 :     if (add && entry->GetMemPoolChildren().insert(*child).second) {
#                 [ +  - ]
#    1078                 :      12647 :         cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
#    1079 [ +  - ][ +  - ]:      12647 :     } else if (!add && entry->GetMemPoolChildren().erase(*child)) {
#                 [ +  - ]
#    1080                 :        552 :         cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
#    1081                 :        552 :     }
#    1082                 :      13199 : }
#    1083                 :            : 
#    1084                 :            : void CTxMemPool::UpdateParent(txiter entry, txiter parent, bool add)
#    1085                 :      15331 : {
#    1086                 :      15331 :     AssertLockHeld(cs);
#    1087                 :      15331 :     CTxMemPoolEntry::Parents s;
#    1088 [ +  + ][ +  + ]:      15331 :     if (add && entry->GetMemPoolParents().insert(*parent).second) {
#                 [ +  - ]
#    1089                 :      12647 :         cachedInnerUsage += memusage::IncrementalDynamicUsage(s);
#    1090 [ +  - ][ +  - ]:      12647 :     } else if (!add && entry->GetMemPoolParents().erase(*parent)) {
#                 [ +  - ]
#    1091                 :       2684 :         cachedInnerUsage -= memusage::IncrementalDynamicUsage(s);
#    1092                 :       2684 :     }
#    1093                 :      15331 : }
#    1094                 :            : 
#    1095                 :     353085 : CFeeRate CTxMemPool::GetMinFee(size_t sizelimit) const {
#    1096                 :     353085 :     LOCK(cs);
#    1097 [ +  + ][ +  + ]:     353085 :     if (!blockSinceLastRollingFeeBump || rollingMinimumFeeRate == 0)
#    1098                 :     353075 :         return CFeeRate(llround(rollingMinimumFeeRate));
#    1099                 :            : 
#    1100                 :         10 :     int64_t time = GetTime();
#    1101         [ +  - ]:         10 :     if (time > lastRollingFeeUpdate + 10) {
#    1102                 :         10 :         double halflife = ROLLING_FEE_HALFLIFE;
#    1103         [ +  + ]:         10 :         if (DynamicMemoryUsage() < sizelimit / 4)
#    1104                 :          2 :             halflife /= 4;
#    1105         [ +  + ]:          8 :         else if (DynamicMemoryUsage() < sizelimit / 2)
#    1106                 :          2 :             halflife /= 2;
#    1107                 :            : 
#    1108                 :         10 :         rollingMinimumFeeRate = rollingMinimumFeeRate / pow(2.0, (time - lastRollingFeeUpdate) / halflife);
#    1109                 :         10 :         lastRollingFeeUpdate = time;
#    1110                 :            : 
#    1111         [ +  + ]:         10 :         if (rollingMinimumFeeRate < (double)incrementalRelayFee.GetFeePerK() / 2) {
#    1112                 :          2 :             rollingMinimumFeeRate = 0;
#    1113                 :          2 :             return CFeeRate(0);
#    1114                 :          2 :         }
#    1115                 :         10 :     }
#    1116                 :          8 :     return std::max(CFeeRate(llround(rollingMinimumFeeRate)), incrementalRelayFee);
#    1117                 :         10 : }
#    1118                 :            : 
#    1119                 :         21 : void CTxMemPool::trackPackageRemoved(const CFeeRate& rate) {
#    1120                 :         21 :     AssertLockHeld(cs);
#    1121         [ +  + ]:         21 :     if (rate.GetFeePerK() > rollingMinimumFeeRate) {
#    1122                 :          8 :         rollingMinimumFeeRate = rate.GetFeePerK();
#    1123                 :          8 :         blockSinceLastRollingFeeBump = false;
#    1124                 :          8 :     }
#    1125                 :         21 : }
#    1126                 :            : 
#    1127                 :      20756 : void CTxMemPool::TrimToSize(size_t sizelimit, std::vector<COutPoint>* pvNoSpendsRemaining) {
#    1128                 :      20756 :     AssertLockHeld(cs);
#    1129                 :            : 
#    1130                 :      20756 :     unsigned nTxnRemoved = 0;
#    1131                 :      20756 :     CFeeRate maxFeeRateRemoved(0);
#    1132 [ +  + ][ +  + ]:      20777 :     while (!mapTx.empty() && DynamicMemoryUsage() > sizelimit) {
#    1133                 :         21 :         indexed_transaction_set::index<descendant_score>::type::iterator it = mapTx.get<descendant_score>().begin();
#    1134                 :            : 
#    1135                 :            :         // We set the new mempool min fee to the feerate of the removed set, plus the
#    1136                 :            :         // "minimum reasonable fee rate" (ie some value under which we consider txn
#    1137                 :            :         // to have 0 fee). This way, we don't allow txn to enter mempool with feerate
#    1138                 :            :         // equal to txn which were removed with no block in between.
#    1139                 :         21 :         CFeeRate removed(it->GetModFeesWithDescendants(), it->GetSizeWithDescendants());
#    1140                 :         21 :         removed += incrementalRelayFee;
#    1141                 :         21 :         trackPackageRemoved(removed);
#    1142                 :         21 :         maxFeeRateRemoved = std::max(maxFeeRateRemoved, removed);
#    1143                 :            : 
#    1144                 :         21 :         setEntries stage;
#    1145                 :         21 :         CalculateDescendants(mapTx.project<0>(it), stage);
#    1146                 :         21 :         nTxnRemoved += stage.size();
#    1147                 :            : 
#    1148                 :         21 :         std::vector<CTransaction> txn;
#    1149         [ +  + ]:         21 :         if (pvNoSpendsRemaining) {
#    1150                 :         11 :             txn.reserve(stage.size());
#    1151         [ +  + ]:         11 :             for (txiter iter : stage)
#    1152                 :         11 :                 txn.push_back(iter->GetTx());
#    1153                 :         11 :         }
#    1154                 :         21 :         RemoveStaged(stage, false, MemPoolRemovalReason::SIZELIMIT);
#    1155         [ +  + ]:         21 :         if (pvNoSpendsRemaining) {
#    1156         [ +  + ]:         11 :             for (const CTransaction& tx : txn) {
#    1157         [ +  + ]:         11 :                 for (const CTxIn& txin : tx.vin) {
#    1158         [ -  + ]:         11 :                     if (exists(GenTxid::Txid(txin.prevout.hash))) continue;
#    1159                 :         11 :                     pvNoSpendsRemaining->push_back(txin.prevout);
#    1160                 :         11 :                 }
#    1161                 :         11 :             }
#    1162                 :         11 :         }
#    1163                 :         21 :     }
#    1164                 :            : 
#    1165         [ +  + ]:      20756 :     if (maxFeeRateRemoved > CFeeRate(0)) {
#    1166         [ +  - ]:         20 :         LogPrint(BCLog::MEMPOOL, "Removed %u txn, rolling minimum fee bumped to %s\n", nTxnRemoved, maxFeeRateRemoved.ToString());
#    1167                 :         20 :     }
#    1168                 :      20756 : }
#    1169                 :            : 
#    1170                 :     407866 : uint64_t CTxMemPool::CalculateDescendantMaximum(txiter entry) const {
#    1171                 :            :     // find parent with highest descendant count
#    1172                 :     407866 :     std::vector<txiter> candidates;
#    1173                 :     407866 :     setEntries counted;
#    1174                 :     407866 :     candidates.push_back(entry);
#    1175                 :     407866 :     uint64_t maximum = 0;
#    1176         [ +  + ]:    1006566 :     while (candidates.size()) {
#    1177                 :     598700 :         txiter candidate = candidates.back();
#    1178                 :     598700 :         candidates.pop_back();
#    1179         [ +  + ]:     598700 :         if (!counted.insert(candidate).second) continue;
#    1180                 :     598570 :         const CTxMemPoolEntry::Parents& parents = candidate->GetMemPoolParentsConst();
#    1181         [ +  + ]:     598570 :         if (parents.size() == 0) {
#    1182                 :     407868 :             maximum = std::max(maximum, candidate->GetCountWithDescendants());
#    1183                 :     407868 :         } else {
#    1184         [ +  + ]:     190834 :             for (const CTxMemPoolEntry& i : parents) {
#    1185                 :     190834 :                 candidates.push_back(mapTx.iterator_to(i));
#    1186                 :     190834 :             }
#    1187                 :     190702 :         }
#    1188                 :     598570 :     }
#    1189                 :     407866 :     return maximum;
#    1190                 :     407866 : }
#    1191                 :            : 
#    1192                 :    1394255 : void CTxMemPool::GetTransactionAncestry(const uint256& txid, size_t& ancestors, size_t& descendants, size_t* const ancestorsize, CAmount* const ancestorfees) const {
#    1193                 :    1394255 :     LOCK(cs);
#    1194                 :    1394255 :     auto it = mapTx.find(txid);
#    1195                 :    1394255 :     ancestors = descendants = 0;
#    1196         [ +  + ]:    1394255 :     if (it != mapTx.end()) {
#    1197                 :     407866 :         ancestors = it->GetCountWithAncestors();
#    1198         [ +  + ]:     407866 :         if (ancestorsize) *ancestorsize = it->GetSizeWithAncestors();
#    1199         [ +  + ]:     407866 :         if (ancestorfees) *ancestorfees = it->GetModFeesWithAncestors();
#    1200                 :     407866 :         descendants = CalculateDescendantMaximum(it);
#    1201                 :     407866 :     }
#    1202                 :    1394255 : }
#    1203                 :            : 
#    1204                 :            : bool CTxMemPool::IsLoaded() const
#    1205                 :       1669 : {
#    1206                 :       1669 :     LOCK(cs);
#    1207                 :       1669 :     return m_is_loaded;
#    1208                 :       1669 : }
#    1209                 :            : 
#    1210                 :            : void CTxMemPool::SetIsLoaded(bool loaded)
#    1211                 :        725 : {
#    1212                 :        725 :     LOCK(cs);
#    1213                 :        725 :     m_is_loaded = loaded;
#    1214                 :        725 : }

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a