Release cs_main during RewindBlockIndex operation

This commit is contained in:
Pieter Wuille 2019-02-13 15:32:34 -08:00
parent 1d342875c2
commit 436f7d735f

View file

@ -4208,20 +4208,25 @@ void CChainState::EraseBlockData(CBlockIndex* index)
bool CChainState::RewindBlockIndex(const CChainParams& params) bool CChainState::RewindBlockIndex(const CChainParams& params)
{ {
LOCK(cs_main);
// Note that during -reindex-chainstate we are called with an empty chainActive! // Note that during -reindex-chainstate we are called with an empty chainActive!
// First erase all post-segwit blocks without witness not in the main chain, // First erase all post-segwit blocks without witness not in the main chain,
// as this can we done without costly DisconnectTip calls. Active // as this can we done without costly DisconnectTip calls. Active
// blocks will be dealt with below. // blocks will be dealt with below (releasing cs_main in between).
{
LOCK(cs_main);
for (const auto& entry : mapBlockIndex) { for (const auto& entry : mapBlockIndex) {
if (IsWitnessEnabled(entry.second->pprev, params.GetConsensus()) && !(entry.second->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(entry.second)) { if (IsWitnessEnabled(entry.second->pprev, params.GetConsensus()) && !(entry.second->nStatus & BLOCK_OPT_WITNESS) && !chainActive.Contains(entry.second)) {
EraseBlockData(entry.second); EraseBlockData(entry.second);
} }
} }
}
// Find what height we need to reorganize to. // Find what height we need to reorganize to.
CBlockIndex *tip;
int nHeight = 1; int nHeight = 1;
{
LOCK(cs_main);
while (nHeight <= chainActive.Height()) { while (nHeight <= chainActive.Height()) {
// Although SCRIPT_VERIFY_WITNESS is now generally enforced on all // Although SCRIPT_VERIFY_WITNESS is now generally enforced on all
// blocks in ConnectBlock, we don't need to go back and // blocks in ConnectBlock, we don't need to go back and
@ -4232,11 +4237,15 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
nHeight++; nHeight++;
} }
tip = chainActive.Tip();
}
// nHeight is now the height of the first insufficiently-validated block, or tipheight + 1 // nHeight is now the height of the first insufficiently-validated block, or tipheight + 1
CValidationState state; CValidationState state;
CBlockIndex* tip = chainActive.Tip();
// Loop until the tip is below nHeight, or we reach a pruned block. // Loop until the tip is below nHeight, or we reach a pruned block.
while (true) { while (true) {
{
LOCK(cs_main);
// Make sure nothing changed from under us (this won't happen because RewindBlockIndex runs before importing/network are active) // Make sure nothing changed from under us (this won't happen because RewindBlockIndex runs before importing/network are active)
assert(tip == chainActive.Tip()); assert(tip == chainActive.Tip());
if (tip == nullptr || tip->nHeight < nHeight) break; if (tip == nullptr || tip->nHeight < nHeight) break;
@ -4265,7 +4274,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
EraseBlockData(tip); EraseBlockData(tip);
tip = tip->pprev; tip = tip->pprev;
}
// 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));
@ -4273,6 +4282,8 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
} }
} }
{
LOCK(cs_main);
if (chainActive.Tip() != nullptr) { if (chainActive.Tip() != nullptr) {
// We can't prune block index candidates based on our tip if we have // We can't prune block index candidates based on our tip if we have
// no tip due to chainActive being empty! // no tip due to chainActive being empty!
@ -4280,6 +4291,7 @@ bool CChainState::RewindBlockIndex(const CChainParams& params)
CheckBlockIndex(params.GetConsensus()); CheckBlockIndex(params.GetConsensus());
} }
}
return true; return true;
} }