merge bitcoin#25571: Make mapBlocksUnknownParent local, and rename it

This commit is contained in:
Kittywhiskers Van Gogh 2020-07-26 23:43:01 +03:00
parent 70a91e1d3f
commit 2c758f4ba2
No known key found for this signature in database
GPG Key ID: 30CD0C065E5C4AAD
4 changed files with 61 additions and 12 deletions

View File

@ -23,6 +23,8 @@
#include <validation.h>
#include <walletinitinterface.h>
#include <map>
std::atomic_bool fImporting(false);
std::atomic_bool fReindex(false);
bool fPruneMode = false;
@ -818,6 +820,9 @@ void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman,
// -reindex
if (fReindex) {
int nFile = 0;
// Map of disk positions for blocks with unknown parent (only used for reindex);
// parent hash -> child disk position, multiple children can have the same parent.
std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
while (true) {
FlatFilePos pos(nFile, 0);
if (!fs::exists(GetBlockPosFilename(pos))) {
@ -828,7 +833,7 @@ void ThreadImport(ChainstateManager& chainman, CDeterministicMNManager& dmnman,
break; // This error is logged in OpenBlockFile
}
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos);
chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos, &blocks_with_unknown_parent);
if (ShutdownRequested()) {
LogPrintf("Shutdown requested. Exit %s\n", __func__);
return;

View File

@ -31,6 +31,13 @@ FUZZ_TARGET_INIT(load_external_block_file, initialize_load_external_block_file)
if (fuzzed_block_file == nullptr) {
return;
}
FlatFilePos flat_file_pos;
g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(fuzzed_block_file, fuzzed_data_provider.ConsumeBool() ? &flat_file_pos : nullptr);
if (fuzzed_data_provider.ConsumeBool()) {
// Corresponds to the -reindex case (track orphan blocks across files).
FlatFilePos flat_file_pos;
std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(fuzzed_block_file, &flat_file_pos, &blocks_with_unknown_parent);
} else {
// Corresponds to the -loadblock= case (orphan blocks aren't tracked across files).
g_setup->m_node.chainman->ActiveChainstate().LoadExternalBlockFile(fuzzed_block_file);
}
}

View File

@ -68,6 +68,7 @@
#include <statsd_client.h>
#include <algorithm>
#include <cassert>
#include <deque>
#include <numeric>
#include <optional>
@ -4516,11 +4517,16 @@ bool CChainState::LoadGenesisBlock()
return true;
}
void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
void CChainState::LoadExternalBlockFile(
FILE* fileIn,
FlatFilePos* dbp,
std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent)
{
AssertLockNotHeld(m_chainstate_mutex);
// Map of disk positions for blocks with unknown parent (only used for reindex)
static std::multimap<uint256, FlatFilePos> mapBlocksUnknownParent;
// Either both should be specified (-reindex), or neither (-loadblock).
assert(!dbp == !blocks_with_unknown_parent);
int64_t nStart = GetTimeMillis();
int nLoaded = 0;
@ -4571,8 +4577,9 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
if (hash != m_params.GetConsensus().hashGenesisBlock && !m_blockman.LookupBlockIndex(block.hashPrevBlock)) {
LogPrint(BCLog::REINDEX, "%s: Out of order block %s, parent %s not known\n", __func__, hash.ToString(),
block.hashPrevBlock.ToString());
if (dbp)
mapBlocksUnknownParent.insert(std::make_pair(block.hashPrevBlock, *dbp));
if (dbp && blocks_with_unknown_parent) {
blocks_with_unknown_parent->emplace(block.hashPrevBlock, *dbp);
}
continue;
}
@ -4601,13 +4608,15 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
NotifyHeaderTip(*this);
if (!blocks_with_unknown_parent) continue;
// Recursively process earlier encountered successors of this block
std::deque<uint256> queue;
queue.push_back(hash);
while (!queue.empty()) {
uint256 head = queue.front();
queue.pop_front();
std::pair<std::multimap<uint256, FlatFilePos>::iterator, std::multimap<uint256, FlatFilePos>::iterator> range = mapBlocksUnknownParent.equal_range(head);
auto range = blocks_with_unknown_parent->equal_range(head);
while (range.first != range.second) {
std::multimap<uint256, FlatFilePos>::iterator it = range.first;
std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
@ -4622,7 +4631,7 @@ void CChainState::LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp)
}
}
range.first++;
mapBlocksUnknownParent.erase(it);
blocks_with_unknown_parent->erase(it);
NotifyHeaderTip(*this);
}
}

View File

@ -604,8 +604,36 @@ public:
bool ResizeCoinsCaches(size_t coinstip_size, size_t coinsdb_size)
EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** Import blocks from an external file */
void LoadExternalBlockFile(FILE* fileIn, FlatFilePos* dbp = nullptr)
/**
* Import blocks from an external file
*
* During reindexing, this function is called for each block file (datadir/blocks/blk?????.dat).
* It reads all blocks contained in the given file and attempts to process them (add them to the
* block index). The blocks may be out of order within each file and across files. Often this
* function reads a block but finds that its parent hasn't been read yet, so the block can't be
* processed yet. The function will add an entry to the blocks_with_unknown_parent map (which is
* passed as an argument), so that when the block's parent is later read and processed, this
* function can re-read the child block from disk and process it.
*
* Because a block's parent may be in a later file, not just later in the same file, the
* blocks_with_unknown_parent map must be passed in and out with each call. It's a multimap,
* rather than just a map, because multiple blocks may have the same parent (when chain splits
* or stale blocks exist). It maps from parent-hash to child-disk-position.
*
* This function can also be used to read blocks from user-specified block files using the
* -loadblock= option. There's no unknown-parent tracking, so the last two arguments are omitted.
*
*
* @param[in] fileIn FILE handle to file containing blocks to read
* @param[in] dbp (optional) Disk block position (only for reindex)
* @param[in,out] blocks_with_unknown_parent (optional) Map of disk positions for blocks with
* unknown parent, key is parent block hash
* (only used for reindex)
* */
void LoadExternalBlockFile(
FILE* fileIn,
FlatFilePos* dbp = nullptr,
std::multimap<uint256, FlatFilePos>* blocks_with_unknown_parent = nullptr)
EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex);
/**