| 272 | } |
| 273 | |
| 274 | void CTxMemPool::UpdateForRemoveFromMempool(const setEntries &entriesToRemove, bool updateDescendants) |
| 275 | { |
| 276 | // For each entry, walk back all ancestors and decrement size associated with this |
| 277 | // transaction |
| 278 | const uint64_t nNoLimit = std::numeric_limits<uint64_t>::max(); |
| 279 | if (updateDescendants) { |
| 280 | // updateDescendants should be true whenever we're not recursively |
| 281 | // removing a tx and all its descendants, eg when a transaction is |
| 282 | // confirmed in a block. |
| 283 | // Here we only update statistics and not data in mapLinks (which |
| 284 | // we need to preserve until we're finished with all operations that |
| 285 | // need to traverse the mempool). |
| 286 | for (txiter removeIt : entriesToRemove) { |
| 287 | setEntries setDescendants; |
| 288 | CalculateDescendants(removeIt, setDescendants); |
| 289 | setDescendants.erase(removeIt); // don't update state for self |
| 290 | int64_t modifySize = -((int64_t)removeIt->GetTxSize()); |
| 291 | CAmount modifyFee = -removeIt->GetModifiedFee(); |
| 292 | int modifySigOps = -removeIt->GetSigOpCost(); |
| 293 | for (txiter dit : setDescendants) { |
| 294 | mapTx.modify(dit, update_ancestor_state(modifySize, modifyFee, -1, modifySigOps)); |
| 295 | } |
| 296 | } |
| 297 | } |
| 298 | for (txiter removeIt : entriesToRemove) { |
| 299 | setEntries setAncestors; |
| 300 | const CTxMemPoolEntry &entry = *removeIt; |
| 301 | std::string dummy; |
| 302 | // Since this is a tx that is already in the mempool, we can call CMPA |
| 303 | // with fSearchForParents = false. If the mempool is in a consistent |
| 304 | // state, then using true or false should both be correct, though false |
| 305 | // should be a bit faster. |
| 306 | // However, if we happen to be in the middle of processing a reorg, then |
| 307 | // the mempool can be in an inconsistent state. In this case, the set |
| 308 | // of ancestors reachable via mapLinks will be the same as the set of |
| 309 | // ancestors whose packages include this transaction, because when we |
| 310 | // add a new transaction to the mempool in addUnchecked(), we assume it |
| 311 | // has no children, and in the case of a reorg where that assumption is |
| 312 | // false, the in-mempool children aren't linked to the in-block tx's |
| 313 | // until UpdateTransactionsFromBlock() is called. |
| 314 | // So if we're being called during a reorg, ie before |
| 315 | // UpdateTransactionsFromBlock() has been called, then mapLinks[] will |
| 316 | // differ from the set of mempool parents we'd calculate by searching, |
| 317 | // and it's important that we use the mapLinks[] notion of ancestor |
| 318 | // transactions as the set of things to update for removal. |
| 319 | CalculateMemPoolAncestors(entry, setAncestors, nNoLimit, nNoLimit, nNoLimit, nNoLimit, dummy, false); |
| 320 | // Note that UpdateAncestorsOf severs the child links that point to |
| 321 | // removeIt in the entries for the parents of removeIt. |
| 322 | UpdateAncestorsOf(false, removeIt, setAncestors); |
| 323 | } |
| 324 | // After updating all the ancestor sizes, we can now sever the link between each |
| 325 | // transaction being removed and any mempool children (ie, update setMemPoolParents |
| 326 | // for each direct child of a transaction being removed). |
| 327 | for (txiter removeIt : entriesToRemove) { |
| 328 | UpdateChildrenForRemoval(removeIt); |
| 329 | } |
| 330 | } |
| 331 |
nothing calls this directly
no test coverage detected