Skip to content

Commit 272fbc3

Browse files
committed
Update CheckBlockIndex invariants for chains based on an assumeutxo snapshot
1 parent 10c0571 commit 272fbc3

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

src/validation.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4723,12 +4723,12 @@ void Chainstate::CheckBlockIndex()
47234723
CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
47244724
CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
47254725
CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
4726+
CBlockIndex* pindexFirstAssumeValid = nullptr; // Oldest ancestor of pindex which has BLOCK_ASSUMED_VALID
47264727
while (pindex != nullptr) {
47274728
nNodes++;
4729+
if (pindexFirstAssumeValid == nullptr && pindex->nStatus & BLOCK_ASSUMED_VALID) pindexFirstAssumeValid = pindex;
47284730
if (pindexFirstInvalid == nullptr && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
4729-
// Assumed-valid index entries will not have data since we haven't downloaded the
4730-
// full block yet.
4731-
if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA) && !pindex->IsAssumedValid()) {
4731+
if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
47324732
pindexFirstMissing = pindex;
47334733
}
47344734
if (pindexFirstNeverProcessed == nullptr && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
@@ -4768,7 +4768,13 @@ void Chainstate::CheckBlockIndex()
47684768
if (!m_blockman.m_have_pruned && !pindex->IsAssumedValid()) {
47694769
// If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
47704770
assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
4771-
assert(pindexFirstMissing == pindexFirstNeverProcessed);
4771+
if (pindexFirstAssumeValid == nullptr) {
4772+
// If we've got some assume valid blocks, then we might have
4773+
// missing blocks (not HAVE_DATA) but still treat them as
4774+
// having been processed (with a fake nTx value). Otherwise, we
4775+
// can assert that these are the same.
4776+
assert(pindexFirstMissing == pindexFirstNeverProcessed);
4777+
}
47724778
} else {
47734779
// If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
47744780
if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
@@ -4839,7 +4845,7 @@ void Chainstate::CheckBlockIndex()
48394845
if (pindexFirstMissing == nullptr) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in m_blocks_unlinked.
48404846
if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == nullptr && pindexFirstMissing != nullptr) {
48414847
// We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
4842-
assert(m_blockman.m_have_pruned); // We must have pruned.
4848+
assert(m_blockman.m_have_pruned || pindexFirstAssumeValid != nullptr); // We must have pruned, or else we're using a snapshot (causing us to have faked the received data for some parent(s)).
48434849
// This block may have entered m_blocks_unlinked if:
48444850
// - it has a descendant that at some point had more work than the
48454851
// tip, and
@@ -4849,7 +4855,12 @@ void Chainstate::CheckBlockIndex()
48494855
// So if this block is itself better than m_chain.Tip() and it wasn't in
48504856
// setBlockIndexCandidates, then it must be in m_blocks_unlinked.
48514857
if (!CBlockIndexWorkComparator()(pindex, m_chain.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
4852-
if (pindexFirstInvalid == nullptr) {
4858+
if (pindexFirstInvalid == nullptr && pindexFirstAssumeValid == nullptr) {
4859+
// If this is a chain based on an assumeutxo snapshot, then
4860+
// this block could either be in mapBlocksUnlinked or in
4861+
// setBlockIndexCandidates; it may take a call to
4862+
// FindMostWorkChain() to figure out whether all the blocks
4863+
// between the tip and this block are actually available.
48534864
assert(foundInUnlinked);
48544865
}
48554866
}
@@ -4877,6 +4888,7 @@ void Chainstate::CheckBlockIndex()
48774888
if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = nullptr;
48784889
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr;
48794890
if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr;
4891+
if (pindex == pindexFirstAssumeValid) pindexFirstAssumeValid = nullptr;
48804892
// Find our parent.
48814893
CBlockIndex* pindexPar = pindex->pprev;
48824894
// Find which child we just visited.

0 commit comments

Comments
 (0)