Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.18: Granular invalidateblock and RewindBlockIndex #15552

Merged
merged 11 commits into from Mar 7, 2019

Prevent callback overruns in InvalidateBlock and RewindBlockIndex

  • Loading branch information...
sipa committed Feb 14, 2019
commit 9ce9c37004440d6a329874dbf66b51666d497dcb
@@ -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
* 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 {
boost::this_thread::interruption_point();

if (GetMainSignals().CallbacksPending() > 10) {
// Block until the validation queue drains. This should largely
// never happen in normal operation, however may happen during
// reindex, causing memory blowup if we run too far ahead.
// Note that if a validationinterface callback ends up calling
// ActivateBestChain this may lead to a deadlock! We should
// probably have a DEBUG_LOCKORDER test for this in the future.
SyncWithValidationInterfaceQueue();
}
// Block until the validation queue drains. This should largely
// never happen in normal operation, however may happen during
// reindex, causing memory blowup if we run too far ahead.
// Note that if a validationinterface callback ends up calling
// ActivateBestChain this may lead to a deadlock! We should
// probably have a DEBUG_LOCKORDER test for this in the future.
LimitValidationInterfaceQueue();

{
LOCK(cs_main);
@@ -2796,6 +2802,9 @@ bool CChainState::InvalidateBlock(CValidationState& state, const CChainParams& c
while (true) {
if (ShutdownRequested()) break;

// Make sure the queue of validation callbacks doesn't grow unboundedly.
LimitValidationInterfaceQueue();

LOCK(cs_main);
if (!chainActive.Contains(pindex)) break;
pindex_was_in_chain = true;
@@ -4285,6 +4294,9 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)

tip = tip->pprev;
}
// Make sure the queue of validation callbacks doesn't grow unboundedly.
LimitValidationInterfaceQueue();

// Occasionally flush state to disk.
if (!FlushStateToDisk(params, state, FlushStateMode::PERIODIC)) {
LogPrintf("RewindBlockIndex: unable to flush state to disk (%s)\n", FormatStateMessage(state));
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.