Changeset View
Changeset View
Standalone View
Standalone View
src/index/base.cpp
Show First 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | bool BaseIndex::Init() { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (locator.IsNull()) { | if (locator.IsNull()) { | ||||
m_best_block_index = nullptr; | m_best_block_index = nullptr; | ||||
} else { | } else { | ||||
m_best_block_index = g_chainman.m_blockman.FindForkInGlobalIndex( | m_best_block_index = g_chainman.m_blockman.FindForkInGlobalIndex( | ||||
::ChainActive(), locator); | ::ChainActive(), locator); | ||||
} | } | ||||
m_synced = m_best_block_index.load() == ::ChainActive().Tip(); | m_synced = m_best_block_index.load() == ::ChainActive().Tip(); | ||||
if (!m_synced) { | |||||
bool prune_violation = false; | |||||
if (!m_best_block_index) { | |||||
// index is not built yet | |||||
// make sure we have all block data back to the genesis | |||||
const CBlockIndex *block = ::ChainActive().Tip(); | |||||
while (block->pprev && block->pprev->nStatus.hasData()) { | |||||
block = block->pprev; | |||||
} | |||||
prune_violation = block != ::ChainActive().Genesis(); | |||||
} | |||||
// in case the index has a best block set and is not fully synced | |||||
// check if we have the required blocks to continue building the index | |||||
else { | |||||
const CBlockIndex *block_to_test = m_best_block_index.load(); | |||||
if (!ChainActive().Contains(block_to_test)) { | |||||
// if the bestblock is not part of the mainchain, find the fork | |||||
// and make sure we have all data down to the fork | |||||
block_to_test = ::ChainActive().FindFork(block_to_test); | |||||
} | |||||
const CBlockIndex *block = ::ChainActive().Tip(); | |||||
prune_violation = true; | |||||
// check backwards from the tip if we have all block data until we | |||||
// reach the indexes bestblock | |||||
while (block_to_test && block && block->nStatus.hasData()) { | |||||
if (block_to_test == block) { | |||||
prune_violation = false; | |||||
break; | |||||
} | |||||
assert(block->pprev); | |||||
block = block->pprev; | |||||
} | |||||
} | |||||
if (prune_violation) { | |||||
// throw error and graceful shutdown if we can't build the index | |||||
FatalError("%s: %s best block of the index goes beyond pruned " | |||||
"data. Please disable the index or reindex (which will " | |||||
"download the whole blockchain again)", | |||||
__func__, GetName()); | |||||
return false; | |||||
} | |||||
} | |||||
return true; | return true; | ||||
} | } | ||||
static const CBlockIndex *NextSyncBlock(const CBlockIndex *pindex_prev) | static const CBlockIndex *NextSyncBlock(const CBlockIndex *pindex_prev) | ||||
EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | EXCLUSIVE_LOCKS_REQUIRED(cs_main) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
if (!pindex_prev) { | if (!pindex_prev) { | ||||
▲ Show 20 Lines • Show All 99 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool BaseIndex::Rewind(const CBlockIndex *current_tip, | bool BaseIndex::Rewind(const CBlockIndex *current_tip, | ||||
const CBlockIndex *new_tip) { | const CBlockIndex *new_tip) { | ||||
assert(current_tip == m_best_block_index); | assert(current_tip == m_best_block_index); | ||||
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip); | assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip); | ||||
// In the case of a reorg, ensure persisted block locator is not stale. | // In the case of a reorg, ensure persisted block locator is not stale. | ||||
// Pruning has a minimum of 288 blocks-to-keep and getting the index | |||||
// out of sync may be possible but a users fault. | |||||
// In case we reorg beyond the pruned depth, ReadBlockFromDisk would | |||||
// throw and lead to a graceful shutdown | |||||
m_best_block_index = new_tip; | m_best_block_index = new_tip; | ||||
if (!Commit()) { | if (!Commit()) { | ||||
// If commit fails, revert the best block index to avoid corruption. | // If commit fails, revert the best block index to avoid corruption. | ||||
m_best_block_index = current_tip; | m_best_block_index = current_tip; | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | if (m_thread_sync.joinable()) { | ||||
m_thread_sync.join(); | m_thread_sync.join(); | ||||
} | } | ||||
} | } | ||||
IndexSummary BaseIndex::GetSummary() const { | IndexSummary BaseIndex::GetSummary() const { | ||||
IndexSummary summary{}; | IndexSummary summary{}; | ||||
summary.name = GetName(); | summary.name = GetName(); | ||||
summary.synced = m_synced; | summary.synced = m_synced; | ||||
summary.best_block_height = m_best_block_index.load()->nHeight; | summary.best_block_height = | ||||
m_best_block_index ? m_best_block_index.load()->nHeight : 0; | |||||
return summary; | return summary; | ||||
} | } |