txdb: More complete fix for the Heartwood chain consistency check issue.

#4499 was an insufficient fix, because it did not consider the case where
a post-Heartwood node wrote a block index object for a header from a
non-upgraded peer. In that case the version in the block index entry is
`>= CHAIN_HISTORY_ROOT_VERSION`, and so the fix in #4499 has no effect.
In addition, we should skip the consistency check when the index object
validity is not BLOCK_VALID_CONSENSUS.

Signed-off-by: Daira Hopwood <daira@jacaranda.org>
This commit is contained in:
Jack Grigg 2020-05-05 14:59:22 +12:00 committed by Sean Bowe
parent f7d2142eb0
commit daabcd6d22
No known key found for this signature in database
GPG Key ID: 95684257D8F8B031
1 changed files with 30 additions and 15 deletions

View File

@ -566,21 +566,36 @@ bool CBlockTreeDB::LoadBlockIndexGuts(
return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString()); return error("LoadBlockIndex(): CheckProofOfWork failed: %s", pindexNew->ToString());
// ZIP 221 consistency checks // ZIP 221 consistency checks
// We assume block index objects on disk that are not at least // These checks should only be performed for block index entries marked
// CHAIN_HISTORY_ROOT_VERSION were created by nodes that were // as consensus-valid (at the time they were written).
// not Heartwood aware. //
if (diskindex.nClientVersion >= CHAIN_HISTORY_ROOT_VERSION && if (pindexNew->IsValid(BLOCK_VALID_CONSENSUS)) {
chainParams.GetConsensus().NetworkUpgradeActive(pindexNew->nHeight, Consensus::UPGRADE_HEARTWOOD)) { // We assume block index entries on disk that are not at least
if (pindexNew->hashLightClientRoot != pindexNew->hashChainHistoryRoot) { // CHAIN_HISTORY_ROOT_VERSION were created by nodes that were
return error( // not Heartwood aware. Such a node would not see Heartwood block
"LoadBlockIndex(): block index inconsistency detected (hashLightClientRoot %s != hashChainHistoryRoot %s): %s", // headers as valid, and so this must *either* be an index entry
pindexNew->hashLightClientRoot.ToString(), pindexNew->hashChainHistoryRoot.ToString(), pindexNew->ToString()); // for a block header on a non-Heartwood chain, or be marked as
} // consensus-invalid.
} else { //
if (pindexNew->hashLightClientRoot != pindexNew->hashFinalSaplingRoot) { // It can also happen that the block index entry was written
return error( // by this node when it was Heartwood-aware (so its version
"LoadBlockIndex(): block index inconsistency detected (hashLightClientRoot != hashFinalSaplingRoot): %s", // will be >= CHAIN_HISTORY_ROOT_VERSION), but received from
pindexNew->ToString()); // a non-upgraded peer. However that case the entry will be
// marked as consensus-invalid.
//
if (diskindex.nClientVersion >= CHAIN_HISTORY_ROOT_VERSION &&
chainParams.GetConsensus().NetworkUpgradeActive(pindexNew->nHeight, Consensus::UPGRADE_HEARTWOOD)) {
if (pindexNew->hashLightClientRoot != pindexNew->hashChainHistoryRoot) {
return error(
"LoadBlockIndex(): block index inconsistency detected (hashLightClientRoot %s != hashChainHistoryRoot %s): %s",
pindexNew->hashLightClientRoot.ToString(), pindexNew->hashChainHistoryRoot.ToString(), pindexNew->ToString());
}
} else {
if (pindexNew->hashLightClientRoot != pindexNew->hashFinalSaplingRoot) {
return error(
"LoadBlockIndex(): block index inconsistency detected (hashLightClientRoot != hashFinalSaplingRoot): %s",
pindexNew->ToString());
}
} }
} }