mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-02 09:46:52 -05:00
Update CheckBlockIndex invariants for chains based on an assumeutxo snapshot
This commit is contained in:
parent
10c05710ce
commit
272fbc370c
1 changed files with 18 additions and 6 deletions
|
@ -4723,12 +4723,12 @@ void Chainstate::CheckBlockIndex()
|
|||
CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not).
|
||||
CBlockIndex* pindexFirstAssumeValid = nullptr; // Oldest ancestor of pindex which has BLOCK_ASSUMED_VALID
|
||||
while (pindex != nullptr) {
|
||||
nNodes++;
|
||||
if (pindexFirstAssumeValid == nullptr && pindex->nStatus & BLOCK_ASSUMED_VALID) pindexFirstAssumeValid = pindex;
|
||||
if (pindexFirstInvalid == nullptr && pindex->nStatus & BLOCK_FAILED_VALID) pindexFirstInvalid = pindex;
|
||||
// Assumed-valid index entries will not have data since we haven't downloaded the
|
||||
// full block yet.
|
||||
if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA) && !pindex->IsAssumedValid()) {
|
||||
if (pindexFirstMissing == nullptr && !(pindex->nStatus & BLOCK_HAVE_DATA)) {
|
||||
pindexFirstMissing = pindex;
|
||||
}
|
||||
if (pindexFirstNeverProcessed == nullptr && pindex->nTx == 0) pindexFirstNeverProcessed = pindex;
|
||||
|
@ -4768,7 +4768,13 @@ void Chainstate::CheckBlockIndex()
|
|||
if (!m_blockman.m_have_pruned && !pindex->IsAssumedValid()) {
|
||||
// If we've never pruned, then HAVE_DATA should be equivalent to nTx > 0
|
||||
assert(!(pindex->nStatus & BLOCK_HAVE_DATA) == (pindex->nTx == 0));
|
||||
assert(pindexFirstMissing == pindexFirstNeverProcessed);
|
||||
if (pindexFirstAssumeValid == nullptr) {
|
||||
// If we've got some assume valid blocks, then we might have
|
||||
// missing blocks (not HAVE_DATA) but still treat them as
|
||||
// having been processed (with a fake nTx value). Otherwise, we
|
||||
// can assert that these are the same.
|
||||
assert(pindexFirstMissing == pindexFirstNeverProcessed);
|
||||
}
|
||||
} else {
|
||||
// If we have pruned, then we can only say that HAVE_DATA implies nTx > 0
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) assert(pindex->nTx > 0);
|
||||
|
@ -4839,7 +4845,7 @@ void Chainstate::CheckBlockIndex()
|
|||
if (pindexFirstMissing == nullptr) assert(!foundInUnlinked); // We aren't missing data for any parent -- cannot be in m_blocks_unlinked.
|
||||
if (pindex->pprev && (pindex->nStatus & BLOCK_HAVE_DATA) && pindexFirstNeverProcessed == nullptr && pindexFirstMissing != nullptr) {
|
||||
// We HAVE_DATA for this block, have received data for all parents at some point, but we're currently missing data for some parent.
|
||||
assert(m_blockman.m_have_pruned); // We must have pruned.
|
||||
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)).
|
||||
// This block may have entered m_blocks_unlinked if:
|
||||
// - it has a descendant that at some point had more work than the
|
||||
// tip, and
|
||||
|
@ -4849,7 +4855,12 @@ void Chainstate::CheckBlockIndex()
|
|||
// So if this block is itself better than m_chain.Tip() and it wasn't in
|
||||
// setBlockIndexCandidates, then it must be in m_blocks_unlinked.
|
||||
if (!CBlockIndexWorkComparator()(pindex, m_chain.Tip()) && setBlockIndexCandidates.count(pindex) == 0) {
|
||||
if (pindexFirstInvalid == nullptr) {
|
||||
if (pindexFirstInvalid == nullptr && pindexFirstAssumeValid == nullptr) {
|
||||
// If this is a chain based on an assumeutxo snapshot, then
|
||||
// this block could either be in mapBlocksUnlinked or in
|
||||
// setBlockIndexCandidates; it may take a call to
|
||||
// FindMostWorkChain() to figure out whether all the blocks
|
||||
// between the tip and this block are actually available.
|
||||
assert(foundInUnlinked);
|
||||
}
|
||||
}
|
||||
|
@ -4877,6 +4888,7 @@ void Chainstate::CheckBlockIndex()
|
|||
if (pindex == pindexFirstNotTransactionsValid) pindexFirstNotTransactionsValid = nullptr;
|
||||
if (pindex == pindexFirstNotChainValid) pindexFirstNotChainValid = nullptr;
|
||||
if (pindex == pindexFirstNotScriptsValid) pindexFirstNotScriptsValid = nullptr;
|
||||
if (pindex == pindexFirstAssumeValid) pindexFirstAssumeValid = nullptr;
|
||||
// Find our parent.
|
||||
CBlockIndex* pindexPar = pindex->pprev;
|
||||
// Find which child we just visited.
|
||||
|
|
Loading…
Add table
Reference in a new issue