mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-20 15:19:07 +01:00
rewrite DisconnectedBlockTransactions as a list + map
And encapsulate underlying data structures to avoid misuse. It's better to use stdlib instead of boost when we can achieve the same thing. Behavior change: the number returned by DynamicMemoryUsage for the same transactions is higher (due to change in usage or more accurate accounting), which effectively decreases the maximum amount of transactions kept for resubmission in a reorg. Co-authored-by: Cory Fields <cory-nospam-@coryfields.com>
This commit is contained in:
@@ -295,28 +295,30 @@ void Chainstate::MaybeUpdateMempoolForReorg(
|
||||
AssertLockHeld(cs_main);
|
||||
AssertLockHeld(m_mempool->cs);
|
||||
std::vector<uint256> vHashUpdate;
|
||||
// disconnectpool's insertion_order index sorts the entries from
|
||||
// oldest to newest, but the oldest entry will be the last tx from the
|
||||
// latest mined block that was disconnected.
|
||||
// Iterate disconnectpool in reverse, so that we add transactions
|
||||
// back to the mempool starting with the earliest transaction that had
|
||||
// been previously seen in a block.
|
||||
auto it = disconnectpool.queuedTx.get<insertion_order>().rbegin();
|
||||
while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
|
||||
// ignore validation errors in resurrected transactions
|
||||
if (!fAddToMempool || (*it)->IsCoinBase() ||
|
||||
AcceptToMemoryPool(*this, *it, GetTime(),
|
||||
/*bypass_limits=*/true, /*test_accept=*/false).m_result_type !=
|
||||
MempoolAcceptResult::ResultType::VALID) {
|
||||
// If the transaction doesn't make it in to the mempool, remove any
|
||||
// transactions that depend on it (which would now be orphans).
|
||||
m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
|
||||
} else if (m_mempool->exists(GenTxid::Txid((*it)->GetHash()))) {
|
||||
vHashUpdate.push_back((*it)->GetHash());
|
||||
{
|
||||
// disconnectpool is ordered so that the front is the most recently-confirmed
|
||||
// transaction (the last tx of the block at the tip) in the disconnected chain.
|
||||
// Iterate disconnectpool in reverse, so that we add transactions
|
||||
// back to the mempool starting with the earliest transaction that had
|
||||
// been previously seen in a block.
|
||||
const auto queuedTx = disconnectpool.take();
|
||||
auto it = queuedTx.rbegin();
|
||||
while (it != queuedTx.rend()) {
|
||||
// ignore validation errors in resurrected transactions
|
||||
if (!fAddToMempool || (*it)->IsCoinBase() ||
|
||||
AcceptToMemoryPool(*this, *it, GetTime(),
|
||||
/*bypass_limits=*/true, /*test_accept=*/false).m_result_type !=
|
||||
MempoolAcceptResult::ResultType::VALID) {
|
||||
// If the transaction doesn't make it in to the mempool, remove any
|
||||
// transactions that depend on it (which would now be orphans).
|
||||
m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
|
||||
} else if (m_mempool->exists(GenTxid::Txid((*it)->GetHash()))) {
|
||||
vHashUpdate.push_back((*it)->GetHash());
|
||||
}
|
||||
++it;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
disconnectpool.queuedTx.clear();
|
||||
|
||||
// AcceptToMemoryPool/addUnchecked all assume that new mempool entries have
|
||||
// no in-mempool children, which is generally not true when adding
|
||||
// previously-confirmed transactions back to the mempool.
|
||||
@@ -2724,9 +2726,8 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra
|
||||
disconnectpool->AddTransactionsFromBlock(block.vtx);
|
||||
while (disconnectpool->DynamicMemoryUsage() > MAX_DISCONNECTED_TX_POOL_SIZE * 1000) {
|
||||
// Drop the earliest entry, and remove its children from the mempool.
|
||||
auto it = disconnectpool->queuedTx.get<insertion_order>().begin();
|
||||
m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
|
||||
disconnectpool->removeEntry(it);
|
||||
auto ptx = disconnectpool->take_first();
|
||||
m_mempool->removeRecursive(*ptx, MemPoolRemovalReason::REORG);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user