mirror of
https://github.com/ElementsProject/elements.git
synced 2026-08-15 12:51:00 +02:00
Merge 601bfc417d into merged_master (Bitcoin PR bitcoin/bitcoin#24515)
This commit is contained in:
commit
fa21dc5b5d
10 changed files with 155 additions and 130 deletions
|
|
@ -32,10 +32,45 @@ bool fTrimHeaders = false;
|
|||
uint64_t nMustKeepFullHeaders = std::numeric_limits<uint64_t>::max();
|
||||
int64_t nHeaderDownloadBuffer = std::numeric_limits<int64_t>::max();
|
||||
|
||||
bool CBlockIndexWorkComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
|
||||
{
|
||||
// First sort by most total work, ...
|
||||
if (pa->nChainWork > pb->nChainWork) return false;
|
||||
if (pa->nChainWork < pb->nChainWork) return true;
|
||||
|
||||
// ... then by earliest time received, ...
|
||||
if (pa->nSequenceId < pb->nSequenceId) return false;
|
||||
if (pa->nSequenceId > pb->nSequenceId) return true;
|
||||
|
||||
// Use pointer address as tie breaker (should only happen with blocks
|
||||
// loaded from disk, as those all have id 0).
|
||||
if (pa < pb) return false;
|
||||
if (pa > pb) return true;
|
||||
|
||||
// Identical blocks.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CBlockIndexHeightOnlyComparator::operator()(const CBlockIndex* pa, const CBlockIndex* pb) const
|
||||
{
|
||||
return pa->nHeight < pb->nHeight;
|
||||
}
|
||||
|
||||
static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false);
|
||||
static FlatFileSeq BlockFileSeq();
|
||||
static FlatFileSeq UndoFileSeq();
|
||||
|
||||
std::vector<CBlockIndex*> BlockManager::GetAllBlockIndices()
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
std::vector<CBlockIndex*> rv;
|
||||
rv.reserve(m_block_index.size());
|
||||
for (auto& [_, block_index] : m_block_index) {
|
||||
rv.push_back(&block_index);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
CBlockIndex* BlockManager::LookupBlockIndex(const uint256& hash)
|
||||
{
|
||||
AssertLockHeld(cs_main);
|
||||
|
|
@ -207,8 +242,7 @@ CBlockIndex* BlockManager::InsertBlockIndex(const uint256& hash)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Return existing or create new
|
||||
auto [mi, inserted] = m_block_index.try_emplace(hash);
|
||||
const auto [mi, inserted]{m_block_index.try_emplace(hash)};
|
||||
CBlockIndex* pindex = &(*mi).second;
|
||||
if (inserted) {
|
||||
pindex->phashBlock = &((*mi).first);
|
||||
|
|
@ -216,9 +250,7 @@ CBlockIndex* BlockManager::InsertBlockIndex(const uint256& hash)
|
|||
return pindex;
|
||||
}
|
||||
|
||||
bool BlockManager::LoadBlockIndex(
|
||||
const Consensus::Params& consensus_params,
|
||||
ChainstateManager& chainman)
|
||||
bool BlockManager::LoadBlockIndex(const Consensus::Params& consensus_params)
|
||||
{
|
||||
int trim_below_height = 0;
|
||||
if (fTrimHeaders) {
|
||||
|
|
@ -237,37 +269,12 @@ bool BlockManager::LoadBlockIndex(
|
|||
}
|
||||
|
||||
// Calculate nChainWork
|
||||
std::vector<std::pair<int, CBlockIndex*>> vSortedByHeight;
|
||||
vSortedByHeight.reserve(m_block_index.size());
|
||||
for (auto& [_, block_index] : m_block_index) {
|
||||
CBlockIndex* pindex = &block_index;
|
||||
vSortedByHeight.push_back(std::make_pair(pindex->nHeight, pindex));
|
||||
}
|
||||
sort(vSortedByHeight.begin(), vSortedByHeight.end());
|
||||
std::vector<CBlockIndex*> vSortedByHeight{GetAllBlockIndices()};
|
||||
std::sort(vSortedByHeight.begin(), vSortedByHeight.end(),
|
||||
CBlockIndexHeightOnlyComparator());
|
||||
|
||||
// Find start of assumed-valid region.
|
||||
int first_assumed_valid_height = std::numeric_limits<int>::max();
|
||||
|
||||
for (const auto& [height, block] : vSortedByHeight) {
|
||||
if (block->IsAssumedValid()) {
|
||||
auto chainstates = chainman.GetAll();
|
||||
|
||||
// If we encounter an assumed-valid block index entry, ensure that we have
|
||||
// one chainstate that tolerates assumed-valid entries and another that does
|
||||
// not (i.e. the background validation chainstate), since assumed-valid
|
||||
// entries should always be pending validation by a fully-validated chainstate.
|
||||
auto any_chain = [&](auto fnc) { return std::any_of(chainstates.cbegin(), chainstates.cend(), fnc); };
|
||||
assert(any_chain([](auto chainstate) { return chainstate->reliesOnAssumedValid(); }));
|
||||
assert(any_chain([](auto chainstate) { return !chainstate->reliesOnAssumedValid(); }));
|
||||
|
||||
first_assumed_valid_height = height;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const std::pair<int, CBlockIndex*>& item : vSortedByHeight) {
|
||||
for (CBlockIndex* pindex : vSortedByHeight) {
|
||||
if (ShutdownRequested()) return false;
|
||||
CBlockIndex* pindex = item.second;
|
||||
pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex);
|
||||
pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime);
|
||||
|
||||
|
|
@ -291,43 +298,6 @@ bool BlockManager::LoadBlockIndex(
|
|||
pindex->nStatus |= BLOCK_FAILED_CHILD;
|
||||
m_dirty_blockindex.insert(pindex);
|
||||
}
|
||||
if (pindex->IsAssumedValid() ||
|
||||
(pindex->IsValid(BLOCK_VALID_TRANSACTIONS) &&
|
||||
(pindex->HaveTxsDownloaded() || pindex->pprev == nullptr))) {
|
||||
|
||||
// Fill each chainstate's block candidate set. Only add assumed-valid
|
||||
// blocks to the tip candidate set if the chainstate is allowed to rely on
|
||||
// assumed-valid blocks.
|
||||
//
|
||||
// If all setBlockIndexCandidates contained the assumed-valid blocks, the
|
||||
// background chainstate's ActivateBestChain() call would add assumed-valid
|
||||
// blocks to the chain (based on how FindMostWorkChain() works). Obviously
|
||||
// we don't want this since the purpose of the background validation chain
|
||||
// is to validate assued-valid blocks.
|
||||
//
|
||||
// Note: This is considering all blocks whose height is greater or equal to
|
||||
// the first assumed-valid block to be assumed-valid blocks, and excluding
|
||||
// them from the background chainstate's setBlockIndexCandidates set. This
|
||||
// does mean that some blocks which are not technically assumed-valid
|
||||
// (later blocks on a fork beginning before the first assumed-valid block)
|
||||
// might not get added to the background chainstate, but this is ok,
|
||||
// because they will still be attached to the active chainstate if they
|
||||
// actually contain more work.
|
||||
//
|
||||
// Instead of this height-based approach, an earlier attempt was made at
|
||||
// detecting "holistically" whether the block index under consideration
|
||||
// relied on an assumed-valid ancestor, but this proved to be too slow to
|
||||
// be practical.
|
||||
for (CChainState* chainstate : chainman.GetAll()) {
|
||||
if (chainstate->reliesOnAssumedValid() ||
|
||||
pindex->nHeight < first_assumed_valid_height) {
|
||||
chainstate->setBlockIndexCandidates.insert(pindex);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pindex->nStatus & BLOCK_FAILED_MASK && (!chainman.m_best_invalid || pindex->nChainWork > chainman.m_best_invalid->nChainWork)) {
|
||||
chainman.m_best_invalid = pindex;
|
||||
}
|
||||
if (pindex->pprev) {
|
||||
pindex->BuildSkip();
|
||||
}
|
||||
|
|
@ -372,9 +342,9 @@ bool BlockManager::WriteBlockIndexDB()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman)
|
||||
bool BlockManager::LoadBlockIndexDB()
|
||||
{
|
||||
if (!LoadBlockIndex(::Params().GetConsensus(), chainman)) {
|
||||
if (!LoadBlockIndex(::Params().GetConsensus())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -399,9 +369,8 @@ bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman)
|
|||
LogPrintf("Checking all blk files are present...\n");
|
||||
std::set<int> setBlkDataFiles;
|
||||
for (const auto& [_, block_index] : m_block_index) {
|
||||
const CBlockIndex* pindex = &block_index;
|
||||
if (pindex->nStatus & BLOCK_HAVE_DATA) {
|
||||
setBlkDataFiles.insert(pindex->nFile);
|
||||
if (block_index.nStatus & BLOCK_HAVE_DATA) {
|
||||
setBlkDataFiles.insert(block_index.nFile);
|
||||
}
|
||||
}
|
||||
for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) {
|
||||
|
|
@ -425,13 +394,13 @@ bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman)
|
|||
return true;
|
||||
}
|
||||
|
||||
CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
|
||||
const CBlockIndex* BlockManager::GetLastCheckpoint(const CCheckpointData& data)
|
||||
{
|
||||
const MapCheckpoints& checkpoints = data.mapCheckpoints;
|
||||
|
||||
for (const MapCheckpoints::value_type& i : reverse_iterate(checkpoints)) {
|
||||
const uint256& hash = i.second;
|
||||
CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
const CBlockIndex* pindex = LookupBlockIndex(hash);
|
||||
if (pindex) {
|
||||
return pindex;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue