Prevent callback overruns in InvalidateBlock and RewindBlockIndex
This commit is contained in:
parent
9bb32eb571
commit
9ce9c37004
1 changed files with 21 additions and 9 deletions
|
@ -2642,6 +2642,14 @@ static void NotifyHeaderTip() LOCKS_EXCLUDED(cs_main) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void LimitValidationInterfaceQueue() {
|
||||||
|
AssertLockNotHeld(cs_main);
|
||||||
|
|
||||||
|
if (GetMainSignals().CallbacksPending() > 10) {
|
||||||
|
SyncWithValidationInterfaceQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the best chain active, in multiple steps. The result is either failure
|
* Make the best chain active, in multiple steps. The result is either failure
|
||||||
* or an activated best chain. pblock is either nullptr or a pointer to a block
|
* or an activated best chain. pblock is either nullptr or a pointer to a block
|
||||||
|
@ -2670,15 +2678,13 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
|
||||||
do {
|
do {
|
||||||
boost::this_thread::interruption_point();
|
boost::this_thread::interruption_point();
|
||||||
|
|
||||||
if (GetMainSignals().CallbacksPending() > 10) {
|
// Block until the validation queue drains. This should largely
|
||||||
// Block until the validation queue drains. This should largely
|
// never happen in normal operation, however may happen during
|
||||||
// never happen in normal operation, however may happen during
|
// reindex, causing memory blowup if we run too far ahead.
|
||||||
// reindex, causing memory blowup if we run too far ahead.
|
// Note that if a validationinterface callback ends up calling
|
||||||
// Note that if a validationinterface callback ends up calling
|
// ActivateBestChain this may lead to a deadlock! We should
|
||||||
// ActivateBestChain this may lead to a deadlock! We should
|
// probably have a DEBUG_LOCKORDER test for this in the future.
|
||||||
// probably have a DEBUG_LOCKORDER test for this in the future.
|
LimitValidationInterfaceQueue();
|
||||||
SyncWithValidationInterfaceQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
|
@ -2796,6 +2802,9 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
|
||||||
while (true) {
|
while (true) {
|
||||||
if (ShutdownRequested()) break;
|
if (ShutdownRequested()) break;
|
||||||
|
|
||||||
|
// Make sure the queue of validation callbacks doesn't grow unboundedly.
|
||||||
|
LimitValidationInterfaceQueue();
|
||||||
|
|
||||||
LOCK(cs_main);
|
LOCK(cs_main);
|
||||||
if (!chainActive.Contains(pindex)) break;
|
if (!chainActive.Contains(pindex)) break;
|
||||||
pindex_was_in_chain = true;
|
pindex_was_in_chain = true;
|
||||||
|
@ -4285,6 +4294,9 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
|
||||||
|
|
||||||
tip = tip->pprev;
|
tip = tip->pprev;
|
||||||
}
|
}
|
||||||
|
// Make sure the queue of validation callbacks doesn't grow unboundedly.
|
||||||
|
LimitValidationInterfaceQueue();
|
||||||
|
|
||||||
// Occasionally flush state to disk.
|
// Occasionally flush state to disk.
|
||||||
if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC)) {
|
if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC)) {
|
||||||
LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
|
LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
|
||||||
|
|
Loading…
Reference in a new issue