index: Ensure block locator is not stale after chain reorg.
This commit is contained in:
parent
4368384f1d
commit
62b7a4f094
2 changed files with 30 additions and 0 deletions
|
@ -113,6 +113,11 @@ void BaseIndex::ThreadSync()
|
||||||
Commit();
|
Commit();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (pindex_next->pprev != pindex && !Rewind(pindex, pindex_next->pprev)) {
|
||||||
|
FatalError("%s: Failed to rewind index %s to a previous chain tip",
|
||||||
|
__func__, GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
pindex = pindex_next;
|
pindex = pindex_next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,6 +172,22 @@ bool BaseIndex::CommitInternal(CDBBatch& batch)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseIndex::Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip)
|
||||||
|
{
|
||||||
|
assert(current_tip == m_best_block_index);
|
||||||
|
assert(current_tip->GetAncestor(new_tip->nHeight) == new_tip);
|
||||||
|
|
||||||
|
// In the case of a reorg, ensure persisted block locator is not stale.
|
||||||
|
m_best_block_index = new_tip;
|
||||||
|
if (!Commit()) {
|
||||||
|
// If commit fails, revert the best block index to avoid corruption.
|
||||||
|
m_best_block_index = current_tip;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
|
void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const CBlockIndex* pindex,
|
||||||
const std::vector<CTransactionRef>& txn_conflicted)
|
const std::vector<CTransactionRef>& txn_conflicted)
|
||||||
{
|
{
|
||||||
|
@ -194,6 +215,11 @@ void BaseIndex::BlockConnected(const std::shared_ptr<const CBlock>& block, const
|
||||||
best_block_index->GetBlockHash().ToString());
|
best_block_index->GetBlockHash().ToString());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (best_block_index != pindex->pprev && !Rewind(best_block_index, pindex->pprev)) {
|
||||||
|
FatalError("%s: Failed to rewind index %s to a previous chain tip",
|
||||||
|
__func__, GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WriteBlock(*block, pindex)) {
|
if (WriteBlock(*block, pindex)) {
|
||||||
|
|
|
@ -80,6 +80,10 @@ protected:
|
||||||
/// commit more index state.
|
/// commit more index state.
|
||||||
virtual bool CommitInternal(CDBBatch& batch);
|
virtual bool CommitInternal(CDBBatch& batch);
|
||||||
|
|
||||||
|
/// Rewind index to an earlier chain tip during a chain reorg. The tip must
|
||||||
|
/// be an ancestor of the current best block.
|
||||||
|
virtual bool Rewind(const CBlockIndex* current_tip, const CBlockIndex* new_tip);
|
||||||
|
|
||||||
virtual DB& GetDB() const = 0;
|
virtual DB& GetDB() const = 0;
|
||||||
|
|
||||||
/// Get the name of the index for display in logs.
|
/// Get the name of the index for display in logs.
|
||||||
|
|
Loading…
Reference in a new issue