MCPcopy Create free account
hub / github.com/ElementsProject/elements / MaybeUpdateMempoolForReorg

Method MaybeUpdateMempoolForReorg

src/validation.cpp:328–413  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

326}
327
328void CChainState::MaybeUpdateMempoolForReorg(
329 DisconnectedBlockTransactions& disconnectpool,
330 bool fAddToMempool)
331{
332 if (!m_mempool) return;
333
334 AssertLockHeld(cs_main);
335 AssertLockHeld(m_mempool->cs);
336 std::vector<uint256> vHashUpdate;
337 // disconnectpool's insertion_order index sorts the entries from
338 // oldest to newest, but the oldest entry will be the last tx from the
339 // latest mined block that was disconnected.
340 // Iterate disconnectpool in reverse, so that we add transactions
341 // back to the mempool starting with the earliest transaction that had
342 // been previously seen in a block.
343 auto it = disconnectpool.queuedTx.get<insertion_order>().rbegin();
344 while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
345 // ignore validation errors in resurrected transactions
346 if (!fAddToMempool || (*it)->IsCoinBase() ||
347 AcceptToMemoryPool(*this, *it, GetTime(),
348 /*bypass_limits=*/true, /*test_accept=*/false).m_result_type !=
349 MempoolAcceptResult::ResultType::VALID) {
350 // If the transaction doesn't make it in to the mempool, remove any
351 // transactions that depend on it (which would now be orphans).
352 m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
353 } else if (m_mempool->exists(GenTxid::Txid((*it)->GetHash()))) {
354 vHashUpdate.push_back((*it)->GetHash());
355 }
356 ++it;
357 }
358 disconnectpool.queuedTx.clear();
359 // AcceptToMemoryPool/addUnchecked all assume that new mempool entries have
360 // no in-mempool children, which is generally not true when adding
361 // previously-confirmed transactions back to the mempool.
362 // UpdateTransactionsFromBlock finds descendants of any transactions in
363 // the disconnectpool that were added back and cleans up the mempool state.
364 const uint64_t ancestor_count_limit = gArgs.GetIntArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT);
365 const uint64_t ancestor_size_limit = gArgs.GetIntArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT) * 1000;
366 m_mempool->UpdateTransactionsFromBlock(vHashUpdate, ancestor_size_limit, ancestor_count_limit);
367
368 // Predicate to use for filtering transactions in removeForReorg.
369 // Checks whether the transaction is still final and, if it spends a coinbase output, mature.
370 // Also updates valid entries' cached LockPoints if needed.
371 // If false, the tx is still valid and its lockpoints are updated.
372 // If true, the tx would be invalid in the next block; remove this entry and all of its descendants.
373 const auto filter_final_and_mature = [this, flags=STANDARD_LOCKTIME_VERIFY_FLAGS](CTxMemPool::txiter it)
374 EXCLUSIVE_LOCKS_REQUIRED(m_mempool->cs, ::cs_main) {
375 AssertLockHeld(m_mempool->cs);
376 AssertLockHeld(::cs_main);
377 const CTransaction& tx = it->GetTx();
378
379 // The transaction must be final.
380 if (!CheckFinalTx(m_chain.Tip(), tx, flags)) return true;
381 LockPoints lp = it->GetLockPoints();
382 const bool validLP{TestLockPointValidity(m_chain, lp)};
383 CCoinsViewMemPool view_mempool(&CoinsTip(), *m_mempool);
384 // CheckSequenceLocks checks if the transaction will be final in the next block to be
385 // created on top of the new chain. We use useExistingLockPoints=false so that, instead of

Callers

nothing calls this directly

Calls 15

GetTimeFunction · 0.85
CheckFinalTxFunction · 0.85
TestLockPointValidityFunction · 0.85
CheckSequenceLocksFunction · 0.85
rbeginMethod · 0.80
rendMethod · 0.80
removeRecursiveMethod · 0.80
GetIntArgMethod · 0.80
GetTxMethod · 0.80
UpdateLockPointsMethod · 0.80
GetSpendsCoinbaseMethod · 0.80

Tested by

no test coverage detected