refactor: Add ChainstateManager::ActivateBestChains() method

Deduplicate code looping over chainstate objects and calling
ActivateBestChain() and avoid need for code outside ChainstateManager to use
the GetAll() method.
This commit is contained in:
Ryan Ofsky
2024-05-30 14:52:28 -04:00
parent 491d827d52
commit 6a572dbda9
4 changed files with 26 additions and 27 deletions

View File

@@ -5137,16 +5137,8 @@ void ChainstateManager::LoadExternalBlockFile(
// until after all of the block files are loaded. ActivateBestChain can be
// called by concurrent network message processing. but, that is not
// reliable for the purpose of pruning while importing.
bool activation_failure = false;
for (auto c : GetAll()) {
BlockValidationState state;
if (!c->ActivateBestChain(state, pblock)) {
LogDebug(BCLog::REINDEX, "failed to activate chain (%s)\n", state.ToString());
activation_failure = true;
break;
}
}
if (activation_failure) {
if (auto result{ActivateBestChains()}; !result) {
LogDebug(BCLog::REINDEX, "%s\n", util::ErrorString(result).original);
break;
}
}
@@ -6446,3 +6438,19 @@ std::optional<std::pair<const CBlockIndex*, const CBlockIndex*>> ChainstateManag
if (!chainstate) return {};
return std::make_pair(chainstate->m_chain.Tip(), chainstate->TargetBlock());
}
util::Result<void> ChainstateManager::ActivateBestChains()
{
// We can't hold cs_main during ActivateBestChain even though we're accessing
// the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
// the relevant pointers before the ABC call.
AssertLockNotHeld(cs_main);
for (Chainstate* chainstate : GetAll()) {
BlockValidationState state;
if (!chainstate->ActivateBestChain(state, nullptr)) {
LOCK(GetMutex());
return util::Error{Untranslated(strprintf("%s Failed to connect best block (%s)", chainstate->ToString(), state.ToString()))};
}
}
return {};
}