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