mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-04-29 14:59:39 -04:00
Merge 12645d1dee
into 65714c162c
This commit is contained in:
commit
d77ba462f8
2 changed files with 34 additions and 21 deletions
|
@ -1970,7 +1970,7 @@ Chainstate::Chainstate(
|
||||||
m_chainman(chainman),
|
m_chainman(chainman),
|
||||||
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
|
m_from_snapshot_blockhash(from_snapshot_blockhash) {}
|
||||||
|
|
||||||
const CBlockIndex* Chainstate::SnapshotBase()
|
const CBlockIndex* Chainstate::SnapshotBase() const
|
||||||
{
|
{
|
||||||
if (!m_from_snapshot_blockhash) return nullptr;
|
if (!m_from_snapshot_blockhash) return nullptr;
|
||||||
if (!m_cached_snapshot_base) m_cached_snapshot_base = Assert(m_chainman.m_blockman.LookupBlockIndex(*m_from_snapshot_blockhash));
|
if (!m_cached_snapshot_base) m_cached_snapshot_base = Assert(m_chainman.m_blockman.LookupBlockIndex(*m_from_snapshot_blockhash));
|
||||||
|
@ -5257,7 +5257,7 @@ bool ChainstateManager::ShouldCheckBlockIndex() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChainstateManager::CheckBlockIndex()
|
void ChainstateManager::CheckBlockIndex() const
|
||||||
{
|
{
|
||||||
if (!ShouldCheckBlockIndex()) {
|
if (!ShouldCheckBlockIndex()) {
|
||||||
return;
|
return;
|
||||||
|
@ -5282,7 +5282,7 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
assert(m_best_header);
|
assert(m_best_header);
|
||||||
best_hdr_chain.SetTip(*m_best_header);
|
best_hdr_chain.SetTip(*m_best_header);
|
||||||
|
|
||||||
std::multimap<CBlockIndex*,CBlockIndex*> forward;
|
std::multimap<const CBlockIndex*, const CBlockIndex*> forward;
|
||||||
for (auto& [_, block_index] : m_blockman.m_block_index) {
|
for (auto& [_, block_index] : m_blockman.m_block_index) {
|
||||||
// Only save indexes in forward that are not part of the best header chain.
|
// Only save indexes in forward that are not part of the best header chain.
|
||||||
if (!best_hdr_chain.Contains(&block_index)) {
|
if (!best_hdr_chain.Contains(&block_index)) {
|
||||||
|
@ -5293,27 +5293,27 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
}
|
}
|
||||||
assert(forward.size() + best_hdr_chain.Height() + 1 == m_blockman.m_block_index.size());
|
assert(forward.size() + best_hdr_chain.Height() + 1 == m_blockman.m_block_index.size());
|
||||||
|
|
||||||
CBlockIndex* pindex = best_hdr_chain[0];
|
const CBlockIndex* pindex = best_hdr_chain[0];
|
||||||
assert(pindex);
|
assert(pindex);
|
||||||
// Iterate over the entire block tree, using depth-first search.
|
// Iterate over the entire block tree, using depth-first search.
|
||||||
// Along the way, remember whether there are blocks on the path from genesis
|
// Along the way, remember whether there are blocks on the path from genesis
|
||||||
// block being explored which are the first to have certain properties.
|
// block being explored which are the first to have certain properties.
|
||||||
size_t nNodes = 0;
|
size_t nNodes = 0;
|
||||||
int nHeight = 0;
|
int nHeight = 0;
|
||||||
CBlockIndex* pindexFirstInvalid = nullptr; // Oldest ancestor of pindex which is invalid.
|
const CBlockIndex* pindexFirstInvalid = nullptr; // Oldest ancestor of pindex which is invalid.
|
||||||
CBlockIndex* pindexFirstMissing = nullptr; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA, since assumeutxo snapshot if used.
|
const CBlockIndex* pindexFirstMissing = nullptr; // Oldest ancestor of pindex which does not have BLOCK_HAVE_DATA, since assumeutxo snapshot if used.
|
||||||
CBlockIndex* pindexFirstNeverProcessed = nullptr; // Oldest ancestor of pindex for which nTx == 0, since assumeutxo snapshot if used.
|
const CBlockIndex* pindexFirstNeverProcessed = nullptr; // Oldest ancestor of pindex for which nTx == 0, since assumeutxo snapshot if used.
|
||||||
CBlockIndex* pindexFirstNotTreeValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
|
const CBlockIndex* pindexFirstNotTreeValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TREE (regardless of being valid or not).
|
||||||
CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not), since assumeutxo snapshot if used.
|
const CBlockIndex* pindexFirstNotTransactionsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_TRANSACTIONS (regardless of being valid or not), since assumeutxo snapshot if used.
|
||||||
CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not), since assumeutxo snapshot if used.
|
const CBlockIndex* pindexFirstNotChainValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_CHAIN (regardless of being valid or not), since assumeutxo snapshot if used.
|
||||||
CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not), since assumeutxo snapshot if used.
|
const CBlockIndex* pindexFirstNotScriptsValid = nullptr; // Oldest ancestor of pindex which does not have BLOCK_VALID_SCRIPTS (regardless of being valid or not), since assumeutxo snapshot if used.
|
||||||
|
|
||||||
// After checking an assumeutxo snapshot block, reset pindexFirst pointers
|
// After checking an assumeutxo snapshot block, reset pindexFirst pointers
|
||||||
// to earlier blocks that have not been downloaded or validated yet, so
|
// to earlier blocks that have not been downloaded or validated yet, so
|
||||||
// checks for later blocks can assume the earlier blocks were validated and
|
// checks for later blocks can assume the earlier blocks were validated and
|
||||||
// be stricter, testing for more requirements.
|
// be stricter, testing for more requirements.
|
||||||
const CBlockIndex* snap_base{GetSnapshotBaseBlock()};
|
const CBlockIndex* snap_base{GetSnapshotBaseBlock()};
|
||||||
CBlockIndex *snap_first_missing{}, *snap_first_notx{}, *snap_first_notv{}, *snap_first_nocv{}, *snap_first_nosv{};
|
const CBlockIndex *snap_first_missing{}, *snap_first_notx{}, *snap_first_notv{}, *snap_first_nocv{}, *snap_first_nosv{};
|
||||||
auto snap_update_firsts = [&] {
|
auto snap_update_firsts = [&] {
|
||||||
if (pindex == snap_base) {
|
if (pindex == snap_base) {
|
||||||
std::swap(snap_first_missing, pindexFirstMissing);
|
std::swap(snap_first_missing, pindexFirstMissing);
|
||||||
|
@ -5453,7 +5453,7 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
// pindex only needs to be added if it is an ancestor of
|
// pindex only needs to be added if it is an ancestor of
|
||||||
// the snapshot that is being validated.
|
// the snapshot that is being validated.
|
||||||
if (c == &ActiveChainstate() || snap_base->GetAncestor(pindex->nHeight) == pindex) {
|
if (c == &ActiveChainstate() || snap_base->GetAncestor(pindex->nHeight) == pindex) {
|
||||||
assert(c->setBlockIndexCandidates.count(pindex));
|
assert(c->setBlockIndexCandidates.contains(const_cast<CBlockIndex*>(pindex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If some parent is missing, then it could be that this block was in
|
// If some parent is missing, then it could be that this block was in
|
||||||
|
@ -5461,11 +5461,11 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
// In this case it must be in m_blocks_unlinked -- see test below.
|
// In this case it must be in m_blocks_unlinked -- see test below.
|
||||||
}
|
}
|
||||||
} else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
|
} else { // If this block sorts worse than the current tip or some ancestor's block has never been seen, it cannot be in setBlockIndexCandidates.
|
||||||
assert(c->setBlockIndexCandidates.count(pindex) == 0);
|
assert(!c->setBlockIndexCandidates.contains(const_cast<CBlockIndex*>(pindex)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check whether this block is in m_blocks_unlinked.
|
// Check whether this block is in m_blocks_unlinked.
|
||||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangeUnlinked = m_blockman.m_blocks_unlinked.equal_range(pindex->pprev);
|
auto rangeUnlinked{m_blockman.m_blocks_unlinked.equal_range(pindex->pprev)};
|
||||||
bool foundInUnlinked = false;
|
bool foundInUnlinked = false;
|
||||||
while (rangeUnlinked.first != rangeUnlinked.second) {
|
while (rangeUnlinked.first != rangeUnlinked.second) {
|
||||||
assert(rangeUnlinked.first->first == pindex->pprev);
|
assert(rangeUnlinked.first->first == pindex->pprev);
|
||||||
|
@ -5494,7 +5494,7 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
// setBlockIndexCandidates, then it must be in m_blocks_unlinked.
|
// setBlockIndexCandidates, then it must be in m_blocks_unlinked.
|
||||||
for (auto c : GetAll()) {
|
for (auto c : GetAll()) {
|
||||||
const bool is_active = c == &ActiveChainstate();
|
const bool is_active = c == &ActiveChainstate();
|
||||||
if (!CBlockIndexWorkComparator()(pindex, c->m_chain.Tip()) && c->setBlockIndexCandidates.count(pindex) == 0) {
|
if (!CBlockIndexWorkComparator()(pindex, c->m_chain.Tip()) && !c->setBlockIndexCandidates.contains(const_cast<CBlockIndex*>(pindex))) {
|
||||||
if (pindexFirstInvalid == nullptr) {
|
if (pindexFirstInvalid == nullptr) {
|
||||||
if (is_active || snap_base->GetAncestor(pindex->nHeight) == pindex) {
|
if (is_active || snap_base->GetAncestor(pindex->nHeight) == pindex) {
|
||||||
assert(foundInUnlinked);
|
assert(foundInUnlinked);
|
||||||
|
@ -5509,7 +5509,7 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
|
|
||||||
// Try descending into the first subnode. Always process forks first and the best header chain after.
|
// Try descending into the first subnode. Always process forks first and the best header chain after.
|
||||||
snap_update_firsts();
|
snap_update_firsts();
|
||||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> range = forward.equal_range(pindex);
|
auto range{forward.equal_range(pindex)};
|
||||||
if (range.first != range.second) {
|
if (range.first != range.second) {
|
||||||
// A subnode not part of the best header chain was found.
|
// A subnode not part of the best header chain was found.
|
||||||
pindex = range.first->second;
|
pindex = range.first->second;
|
||||||
|
@ -5538,7 +5538,7 @@ void ChainstateManager::CheckBlockIndex()
|
||||||
// Find our parent.
|
// Find our parent.
|
||||||
CBlockIndex* pindexPar = pindex->pprev;
|
CBlockIndex* pindexPar = pindex->pprev;
|
||||||
// Find which child we just visited.
|
// Find which child we just visited.
|
||||||
std::pair<std::multimap<CBlockIndex*,CBlockIndex*>::iterator,std::multimap<CBlockIndex*,CBlockIndex*>::iterator> rangePar = forward.equal_range(pindexPar);
|
auto rangePar{forward.equal_range(pindexPar)};
|
||||||
while (rangePar.first->second != pindex) {
|
while (rangePar.first->second != pindex) {
|
||||||
assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
|
assert(rangePar.first != rangePar.second); // Our parent must have at least the node we're coming from as child.
|
||||||
rangePar.first++;
|
rangePar.first++;
|
||||||
|
@ -5657,6 +5657,18 @@ std::vector<Chainstate*> ChainstateManager::GetAll()
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<const Chainstate*> ChainstateManager::GetAll() const
|
||||||
|
{
|
||||||
|
LOCK(::cs_main);
|
||||||
|
std::vector<const Chainstate*> out;
|
||||||
|
|
||||||
|
for (const Chainstate* cs : {m_ibd_chainstate.get(), m_snapshot_chainstate.get()}) {
|
||||||
|
if (this->IsUsable(cs)) out.push_back(cs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
Chainstate& ChainstateManager::InitializeChainstate(CTxMemPool* mempool)
|
Chainstate& ChainstateManager::InitializeChainstate(CTxMemPool* mempool)
|
||||||
{
|
{
|
||||||
AssertLockHeld(::cs_main);
|
AssertLockHeld(::cs_main);
|
||||||
|
|
|
@ -532,7 +532,7 @@ protected:
|
||||||
bool m_disabled GUARDED_BY(::cs_main) {false};
|
bool m_disabled GUARDED_BY(::cs_main) {false};
|
||||||
|
|
||||||
//! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash)
|
//! Cached result of LookupBlockIndex(*m_from_snapshot_blockhash)
|
||||||
const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main) {nullptr};
|
mutable const CBlockIndex* m_cached_snapshot_base GUARDED_BY(::cs_main){nullptr};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//! Reference to a BlockManager instance which itself is shared across all
|
//! Reference to a BlockManager instance which itself is shared across all
|
||||||
|
@ -596,7 +596,7 @@ public:
|
||||||
*
|
*
|
||||||
* nullptr if this chainstate was not created from a snapshot.
|
* nullptr if this chainstate was not created from a snapshot.
|
||||||
*/
|
*/
|
||||||
const CBlockIndex* SnapshotBase() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
const CBlockIndex* SnapshotBase() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The set of all CBlockIndex entries that have as much work as our current
|
* The set of all CBlockIndex entries that have as much work as our current
|
||||||
|
@ -985,7 +985,7 @@ public:
|
||||||
*
|
*
|
||||||
* By default this only executes fully when using the Regtest chain; see: m_options.check_block_index.
|
* By default this only executes fully when using the Regtest chain; see: m_options.check_block_index.
|
||||||
*/
|
*/
|
||||||
void CheckBlockIndex();
|
void CheckBlockIndex() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias for ::cs_main.
|
* Alias for ::cs_main.
|
||||||
|
@ -1078,6 +1078,7 @@ public:
|
||||||
|
|
||||||
//! Get all chainstates currently being used.
|
//! Get all chainstates currently being used.
|
||||||
std::vector<Chainstate*> GetAll();
|
std::vector<Chainstate*> GetAll();
|
||||||
|
std::vector<const Chainstate*> GetAll() const;
|
||||||
|
|
||||||
//! Construct and activate a Chainstate on the basis of UTXO snapshot data.
|
//! Construct and activate a Chainstate on the basis of UTXO snapshot data.
|
||||||
//!
|
//!
|
||||||
|
|
Loading…
Add table
Reference in a new issue