vHashesToUpdate is the set of transaction hashes from a disconnected block which has been re-added to the mempool. for each entry, look for descendants that are outside hashesToUpdate, and add fee/size information for such descendants to the parent. for each such descendant, also update the ancestor state to include the parent.
| 116 | // add fee/size information for such descendants to the parent. |
| 117 | // for each such descendant, also update the ancestor state to include the parent. |
| 118 | void CTxMemPool::UpdateTransactionsFromBlock(const std::vector<uint256> &vHashesToUpdate) |
| 119 | { |
| 120 | LOCK(cs); |
| 121 | // For each entry in vHashesToUpdate, store the set of in-mempool, but not |
| 122 | // in-vHashesToUpdate transactions, so that we don't have to recalculate |
| 123 | // descendants when we come across a previously seen entry. |
| 124 | cacheMap mapMemPoolDescendantsToUpdate; |
| 125 | |
| 126 | // Use a set for lookups into vHashesToUpdate (these entries are already |
| 127 | // accounted for in the state of their ancestors) |
| 128 | std::set<uint256> setAlreadyIncluded(vHashesToUpdate.begin(), vHashesToUpdate.end()); |
| 129 | |
| 130 | // Iterate in reverse, so that whenever we are looking at at a transaction |
| 131 | // we are sure that all in-mempool descendants have already been processed. |
| 132 | // This maximizes the benefit of the descendant cache and guarantees that |
| 133 | // setMemPoolChildren will be updated, an assumption made in |
| 134 | // UpdateForDescendants. |
| 135 | BOOST_REVERSE_FOREACH(const uint256 &hash, vHashesToUpdate) { |
| 136 | // we cache the in-mempool children to avoid duplicate updates |
| 137 | setEntries setChildren; |
| 138 | // calculate children from mapNextTx |
| 139 | txiter it = mapTx.find(hash); |
| 140 | if (it == mapTx.end()) { |
| 141 | continue; |
| 142 | } |
| 143 | std::map<COutPoint, CInPoint>::iterator iter = mapNextTx.lower_bound(COutPoint(hash, 0)); |
| 144 | // First calculate the children, and update setMemPoolChildren to |
| 145 | // include them, and update their setMemPoolParents to include this tx. |
| 146 | for (; iter != mapNextTx.end() && iter->first.hash == hash; ++iter) { |
| 147 | const uint256 &childHash = iter->second.ptx->GetHash(); |
| 148 | txiter childIter = mapTx.find(childHash); |
| 149 | assert(childIter != mapTx.end()); |
| 150 | // We can skip updating entries we've encountered before or that |
| 151 | // are in the block (which are already accounted for). |
| 152 | if (setChildren.insert(childIter).second && !setAlreadyIncluded.count(childHash)) { |
| 153 | UpdateChild(it, childIter, true); |
| 154 | UpdateParent(childIter, it, true); |
| 155 | } |
| 156 | } |
| 157 | UpdateForDescendants(it, mapMemPoolDescendantsToUpdate, setAlreadyIncluded); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | bool CTxMemPool::CalculateMemPoolAncestors(const CTxMemPoolEntry &entry, setEntries &setAncestors, uint64_t limitAncestorCount, uint64_t limitAncestorSize, uint64_t limitDescendantCount, uint64_t limitDescendantSize, std::string &errString, bool fSearchForParents /* = true */) |
| 162 | { |
no test coverage detected