mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-07-28 12:43:59 +02:00
refactor: move UpdateMempoolForReorg into CChainState
Allows fewer arguments and simplification of call sites. Co-authored-by: John Newbery <john@johnnewbery.com>
This commit is contained in:
@@ -329,24 +329,14 @@ static bool IsCurrentForFeeEstimation(CChainState& active_chainstate) EXCLUSIVE_
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void CChainState::MaybeUpdateMempoolForReorg(
|
||||||
* Make mempool consistent after a reorg, by re-adding or recursively erasing
|
DisconnectedBlockTransactions& disconnectpool,
|
||||||
* disconnected block transactions from the mempool, and also removing any
|
bool fAddToMempool)
|
||||||
* other transactions from the mempool that are no longer valid given the new
|
|
||||||
* tip/height.
|
|
||||||
*
|
|
||||||
* Note: we assume that disconnectpool only contains transactions that are NOT
|
|
||||||
* confirmed in the current chain nor already in the mempool (otherwise,
|
|
||||||
* in-mempool descendants of such transactions would be removed).
|
|
||||||
*
|
|
||||||
* Passing fAddToMempool=false will skip trying to add the transactions back,
|
|
||||||
* and instead just erase from the mempool as needed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void UpdateMempoolForReorg(CChainState& active_chainstate, CTxMemPool& mempool, DisconnectedBlockTransactions& disconnectpool, bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, mempool.cs)
|
|
||||||
{
|
{
|
||||||
|
if (!m_mempool) return;
|
||||||
|
|
||||||
AssertLockHeld(cs_main);
|
AssertLockHeld(cs_main);
|
||||||
AssertLockHeld(mempool.cs);
|
AssertLockHeld(m_mempool->cs);
|
||||||
std::vector<uint256> vHashUpdate;
|
std::vector<uint256> vHashUpdate;
|
||||||
// disconnectpool's insertion_order index sorts the entries from
|
// disconnectpool's insertion_order index sorts the entries from
|
||||||
// oldest to newest, but the oldest entry will be the last tx from the
|
// oldest to newest, but the oldest entry will be the last tx from the
|
||||||
@@ -358,11 +348,13 @@ static void UpdateMempoolForReorg(CChainState& active_chainstate, CTxMemPool& me
|
|||||||
while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
|
while (it != disconnectpool.queuedTx.get<insertion_order>().rend()) {
|
||||||
// ignore validation errors in resurrected transactions
|
// ignore validation errors in resurrected transactions
|
||||||
if (!fAddToMempool || (*it)->IsCoinBase() ||
|
if (!fAddToMempool || (*it)->IsCoinBase() ||
|
||||||
AcceptToMemoryPool(active_chainstate, mempool, *it, true /* bypass_limits */).m_result_type != MempoolAcceptResult::ResultType::VALID) {
|
AcceptToMemoryPool(
|
||||||
|
*this, *m_mempool, *it, true /* bypass_limits */).m_result_type !=
|
||||||
|
MempoolAcceptResult::ResultType::VALID) {
|
||||||
// If the transaction doesn't make it in to the mempool, remove any
|
// If the transaction doesn't make it in to the mempool, remove any
|
||||||
// transactions that depend on it (which would now be orphans).
|
// transactions that depend on it (which would now be orphans).
|
||||||
mempool.removeRecursive(**it, MemPoolRemovalReason::REORG);
|
m_mempool->removeRecursive(**it, MemPoolRemovalReason::REORG);
|
||||||
} else if (mempool.exists((*it)->GetHash())) {
|
} else if (m_mempool->exists((*it)->GetHash())) {
|
||||||
vHashUpdate.push_back((*it)->GetHash());
|
vHashUpdate.push_back((*it)->GetHash());
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
@@ -373,12 +365,16 @@ static void UpdateMempoolForReorg(CChainState& active_chainstate, CTxMemPool& me
|
|||||||
// previously-confirmed transactions back to the mempool.
|
// previously-confirmed transactions back to the mempool.
|
||||||
// UpdateTransactionsFromBlock finds descendants of any transactions in
|
// UpdateTransactionsFromBlock finds descendants of any transactions in
|
||||||
// the disconnectpool that were added back and cleans up the mempool state.
|
// the disconnectpool that were added back and cleans up the mempool state.
|
||||||
mempool.UpdateTransactionsFromBlock(vHashUpdate);
|
m_mempool->UpdateTransactionsFromBlock(vHashUpdate);
|
||||||
|
|
||||||
// We also need to remove any now-immature transactions
|
// We also need to remove any now-immature transactions
|
||||||
mempool.removeForReorg(active_chainstate, STANDARD_LOCKTIME_VERIFY_FLAGS);
|
m_mempool->removeForReorg(*this, STANDARD_LOCKTIME_VERIFY_FLAGS);
|
||||||
// Re-limit mempool size, in case we added any transactions
|
// Re-limit mempool size, in case we added any transactions
|
||||||
LimitMempoolSize(mempool, active_chainstate.CoinsTip(), gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000, std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
|
LimitMempoolSize(
|
||||||
|
*m_mempool,
|
||||||
|
this->CoinsTip(),
|
||||||
|
gArgs.GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000,
|
||||||
|
std::chrono::hours{gArgs.GetArg("-mempoolexpiry", DEFAULT_MEMPOOL_EXPIRY)});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -2247,7 +2243,7 @@ static void UpdateTip(CTxMemPool* mempool, const CBlockIndex* pindexNew, const C
|
|||||||
/** Disconnect m_chain's tip.
|
/** Disconnect m_chain's tip.
|
||||||
* After calling, the mempool will be in an inconsistent state, with
|
* After calling, the mempool will be in an inconsistent state, with
|
||||||
* transactions from disconnected blocks being added to disconnectpool. You
|
* transactions from disconnected blocks being added to disconnectpool. You
|
||||||
* should make the mempool consistent again by calling UpdateMempoolForReorg.
|
* should make the mempool consistent again by calling MaybeUpdateMempoolForReorg.
|
||||||
* with cs_main held.
|
* with cs_main held.
|
||||||
*
|
*
|
||||||
* If disconnectpool is nullptr, then no disconnected transactions are added to
|
* If disconnectpool is nullptr, then no disconnected transactions are added to
|
||||||
@@ -2512,7 +2508,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex
|
|||||||
if (!DisconnectTip(state, &disconnectpool)) {
|
if (!DisconnectTip(state, &disconnectpool)) {
|
||||||
// This is likely a fatal error, but keep the mempool consistent,
|
// This is likely a fatal error, but keep the mempool consistent,
|
||||||
// just in case. Only remove from the mempool in this case.
|
// just in case. Only remove from the mempool in this case.
|
||||||
if (m_mempool) UpdateMempoolForReorg(*this, *m_mempool, disconnectpool, false);
|
MaybeUpdateMempoolForReorg(disconnectpool, false);
|
||||||
|
|
||||||
// If we're unable to disconnect a block during normal operation,
|
// If we're unable to disconnect a block during normal operation,
|
||||||
// then that is a failure of our local system -- we should abort
|
// then that is a failure of our local system -- we should abort
|
||||||
@@ -2556,7 +2552,7 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex
|
|||||||
// A system error occurred (disk space, database error, ...).
|
// A system error occurred (disk space, database error, ...).
|
||||||
// Make the mempool consistent with the current tip, just in case
|
// Make the mempool consistent with the current tip, just in case
|
||||||
// any observers try to use it before shutdown.
|
// any observers try to use it before shutdown.
|
||||||
if (m_mempool) UpdateMempoolForReorg(*this, *m_mempool, disconnectpool, false);
|
MaybeUpdateMempoolForReorg(disconnectpool, false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -2570,10 +2566,10 @@ bool CChainState::ActivateBestChainStep(BlockValidationState& state, CBlockIndex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fBlocksDisconnected && m_mempool) {
|
if (fBlocksDisconnected) {
|
||||||
// If any blocks were disconnected, disconnectpool may be non empty. Add
|
// If any blocks were disconnected, disconnectpool may be non empty. Add
|
||||||
// any disconnected transactions back to the mempool.
|
// any disconnected transactions back to the mempool.
|
||||||
UpdateMempoolForReorg(*this, *m_mempool, disconnectpool, true);
|
MaybeUpdateMempoolForReorg(disconnectpool, true);
|
||||||
}
|
}
|
||||||
if (m_mempool) m_mempool->check(*this);
|
if (m_mempool) m_mempool->check(*this);
|
||||||
|
|
||||||
@@ -2798,7 +2794,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
|
|||||||
LimitValidationInterfaceQueue();
|
LimitValidationInterfaceQueue();
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
// Lock for as long as disconnectpool is in scope to make sure UpdateMempoolForReorg is
|
// Lock for as long as disconnectpool is in scope to make sure MaybeUpdateMempoolForReorg is
|
||||||
// called after DisconnectTip without unlocking in between
|
// called after DisconnectTip without unlocking in between
|
||||||
LOCK(MempoolMutex());
|
LOCK(MempoolMutex());
|
||||||
if (!m_chain.Contains(pindex)) break;
|
if (!m_chain.Contains(pindex)) break;
|
||||||
@@ -2814,9 +2810,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
|
|||||||
// transactions back to the mempool if disconnecting was successful,
|
// transactions back to the mempool if disconnecting was successful,
|
||||||
// and we're not doing a very deep invalidation (in which case
|
// and we're not doing a very deep invalidation (in which case
|
||||||
// keeping the mempool up to date is probably futile anyway).
|
// keeping the mempool up to date is probably futile anyway).
|
||||||
if (m_mempool) {
|
MaybeUpdateMempoolForReorg(disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
|
||||||
UpdateMempoolForReorg(*this, *m_mempool, disconnectpool, /* fAddToMempool = */ (++disconnected <= 10) && ret);
|
|
||||||
}
|
|
||||||
if (!ret) return false;
|
if (!ret) return false;
|
||||||
assert(invalid_walk_tip->pprev == m_chain.Tip());
|
assert(invalid_walk_tip->pprev == m_chain.Tip());
|
||||||
|
|
||||||
|
@@ -808,6 +808,23 @@ private:
|
|||||||
return m_mempool ? &m_mempool->cs : nullptr;
|
return m_mempool ? &m_mempool->cs : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make mempool consistent after a reorg, by re-adding or recursively erasing
|
||||||
|
* disconnected block transactions from the mempool, and also removing any
|
||||||
|
* other transactions from the mempool that are no longer valid given the new
|
||||||
|
* tip/height.
|
||||||
|
*
|
||||||
|
* Note: we assume that disconnectpool only contains transactions that are NOT
|
||||||
|
* confirmed in the current chain nor already in the mempool (otherwise,
|
||||||
|
* in-mempool descendants of such transactions would be removed).
|
||||||
|
*
|
||||||
|
* Passing fAddToMempool=false will skip trying to add the transactions back,
|
||||||
|
* and instead just erase from the mempool as needed.
|
||||||
|
*/
|
||||||
|
void MaybeUpdateMempoolForReorg(
|
||||||
|
DisconnectedBlockTransactions& disconnectpool,
|
||||||
|
bool fAddToMempool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, m_mempool->cs);
|
||||||
|
|
||||||
friend ChainstateManager;
|
friend ChainstateManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user