diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -579,6 +579,7 @@ minerfund.cpp net.cpp net_processing.cpp + node/blockstorage.cpp node/coin.cpp node/coinstats.cpp node/context.cpp diff --git a/src/init.cpp b/src/init.cpp --- a/src/init.cpp +++ b/src/init.cpp @@ -16,13 +16,11 @@ #include // For AVALANCHE_LEGACY_PROOF_DEFAULT #include #include -#include #include #include #include #include #include -#include #include #include #include @@ -40,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -93,7 +92,6 @@ static const bool DEFAULT_PROXYRANDOMIZE = true; static const bool DEFAULT_REST_ENABLE = false; -static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false; #ifdef WIN32 // Win32 LevelDB doesn't use filedescriptors, and the ones used for accessing @@ -1420,18 +1418,6 @@ } } -struct CImportingNow { - CImportingNow() { - assert(fImporting == false); - fImporting = true; - } - - ~CImportingNow() { - assert(fImporting == true); - fImporting = false; - } -}; - // If we're using -prune with -reindex, then delete block files that will be // ignored by the reindex. Since reindexing works by starting at block file 0 // and looping until a blockfile is missing, do the same here to delete any @@ -1484,110 +1470,6 @@ } #endif -static void ThreadImport(const Config &config, ChainstateManager &chainman, - std::vector vImportFiles, - const ArgsManager &args) { - ScheduleBatchPriority(); - - { - const CChainParams &chainParams = config.GetChainParams(); - - CImportingNow imp; - - // -reindex - if (fReindex) { - int nFile = 0; - while (true) { - FlatFilePos pos(nFile, 0); - if (!fs::exists(GetBlockPosFilename(pos))) { - // No block files left to reindex - break; - } - FILE *file = OpenBlockFile(pos, true); - if (!file) { - // This error is logged in OpenBlockFile - break; - } - LogPrintf("Reindexing block file blk%05u.dat...\n", - (unsigned int)nFile); - ::ChainstateActive().LoadExternalBlockFile(config, file, &pos); - if (ShutdownRequested()) { - LogPrintf("Shutdown requested. Exit %s\n", __func__); - return; - } - nFile++; - } - pblocktree->WriteReindexing(false); - fReindex = false; - LogPrintf("Reindexing finished\n"); - // To avoid ending up in a situation without genesis block, re-try - // initializing (no-op if reindexing worked): - ::ChainstateActive().LoadGenesisBlock(chainParams); - } - - // -loadblock= - for (const fs::path &path : vImportFiles) { - FILE *file = fsbridge::fopen(path, "rb"); - if (file) { - LogPrintf("Importing blocks file %s...\n", - fs::PathToString(path)); - ::ChainstateActive().LoadExternalBlockFile(config, file); - if (ShutdownRequested()) { - LogPrintf("Shutdown requested. Exit %s\n", __func__); - return; - } - } else { - LogPrintf("Warning: Could not open blocks file %s\n", - fs::PathToString(path)); - } - } - - // Reconsider blocks we know are valid. They may have been marked - // invalid by, for instance, running an outdated version of the node - // software. - const MapCheckpoints &checkpoints = - chainParams.Checkpoints().mapCheckpoints; - for (const MapCheckpoints::value_type &i : checkpoints) { - const BlockHash &hash = i.second; - - LOCK(cs_main); - CBlockIndex *pblockindex = - g_chainman.m_blockman.LookupBlockIndex(hash); - if (pblockindex && !pblockindex->nStatus.isValid()) { - LogPrintf("Reconsidering checkpointed block %s ...\n", - hash.GetHex()); - ::ChainstateActive().ResetBlockFailureFlags(pblockindex); - } - } - - // scan for better chains in the block chain database, that are not yet - // connected in the active best chain - - // We can't hold cs_main during ActivateBestChain even though we're - // accessing the chainman unique_ptrs since ABC requires us not to be - // holding cs_main, so retrieve the relevant pointers before the ABC - // call. - for (CChainState *chainstate : - WITH_LOCK(::cs_main, return chainman.GetAll())) { - BlockValidationState state; - if (!chainstate->ActivateBestChain(config, state, nullptr)) { - LogPrintf("Failed to connect best block (%s)\n", - state.ToString()); - StartShutdown(); - return; - } - } - - if (args.GetBoolArg("-stopafterblockimport", - DEFAULT_STOPAFTERBLOCKIMPORT)) { - LogPrintf("Stopping after block import\n"); - StartShutdown(); - return; - } - } // End scope of CImportingNow - chainman.ActiveChainstate().LoadMempool(config, args); -} - /** Sanity checks * Ensure that Bitcoin is running in a usable environment with all * necessary library support. diff --git a/src/node/blockstorage.h b/src/node/blockstorage.h new file mode 100644 --- /dev/null +++ b/src/node/blockstorage.h @@ -0,0 +1,21 @@ +// Copyright (c) 2011-2021 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_NODE_BLOCKSTORAGE_H +#define BITCOIN_NODE_BLOCKSTORAGE_H + +#include + +#include + +class ArgsManager; +class ChainstateManager; +class Config; + +static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false}; + +void ThreadImport(const Config &config, ChainstateManager &chainman, + std::vector vImportFiles, const ArgsManager &args); + +#endif // BITCOIN_NODE_BLOCKSTORAGE_H diff --git a/src/node/blockstorage.cpp b/src/node/blockstorage.cpp new file mode 100644 --- /dev/null +++ b/src/node/blockstorage.cpp @@ -0,0 +1,129 @@ +// Copyright (c) 2011-2022 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +struct CImportingNow { + CImportingNow() { + assert(fImporting == false); + fImporting = true; + } + + ~CImportingNow() { + assert(fImporting == true); + fImporting = false; + } +}; + +void ThreadImport(const Config &config, ChainstateManager &chainman, + std::vector vImportFiles, const ArgsManager &args) { + ScheduleBatchPriority(); + + { + const CChainParams &chainParams = config.GetChainParams(); + + CImportingNow imp; + + // -reindex + if (fReindex) { + int nFile = 0; + while (true) { + FlatFilePos pos(nFile, 0); + if (!fs::exists(GetBlockPosFilename(pos))) { + // No block files left to reindex + break; + } + FILE *file = OpenBlockFile(pos, true); + if (!file) { + // This error is logged in OpenBlockFile + break; + } + LogPrintf("Reindexing block file blk%05u.dat...\n", + (unsigned int)nFile); + ::ChainstateActive().LoadExternalBlockFile(config, file, &pos); + if (ShutdownRequested()) { + LogPrintf("Shutdown requested. Exit %s\n", __func__); + return; + } + nFile++; + } + pblocktree->WriteReindexing(false); + fReindex = false; + LogPrintf("Reindexing finished\n"); + // To avoid ending up in a situation without genesis block, re-try + // initializing (no-op if reindexing worked): + ::ChainstateActive().LoadGenesisBlock(chainParams); + } + + // -loadblock= + for (const fs::path &path : vImportFiles) { + FILE *file = fsbridge::fopen(path, "rb"); + if (file) { + LogPrintf("Importing blocks file %s...\n", + fs::PathToString(path)); + ::ChainstateActive().LoadExternalBlockFile(config, file); + if (ShutdownRequested()) { + LogPrintf("Shutdown requested. Exit %s\n", __func__); + return; + } + } else { + LogPrintf("Warning: Could not open blocks file %s\n", + fs::PathToString(path)); + } + } + + // Reconsider blocks we know are valid. They may have been marked + // invalid by, for instance, running an outdated version of the node + // software. + const MapCheckpoints &checkpoints = + chainParams.Checkpoints().mapCheckpoints; + for (const MapCheckpoints::value_type &i : checkpoints) { + const BlockHash &hash = i.second; + + LOCK(cs_main); + CBlockIndex *pblockindex = + g_chainman.m_blockman.LookupBlockIndex(hash); + if (pblockindex && !pblockindex->nStatus.isValid()) { + LogPrintf("Reconsidering checkpointed block %s ...\n", + hash.GetHex()); + ::ChainstateActive().ResetBlockFailureFlags(pblockindex); + } + } + + // scan for better chains in the block chain database, that are not yet + // connected in the active best chain + + // We can't hold cs_main during ActivateBestChain even though we're + // accessing the chainman unique_ptrs since ABC requires us not to be + // holding cs_main, so retrieve the relevant pointers before the ABC + // call. + for (CChainState *chainstate : + WITH_LOCK(::cs_main, return chainman.GetAll())) { + BlockValidationState state; + if (!chainstate->ActivateBestChain(config, state, nullptr)) { + LogPrintf("Failed to connect best block (%s)\n", + state.ToString()); + StartShutdown(); + return; + } + } + + if (args.GetBoolArg("-stopafterblockimport", + DEFAULT_STOPAFTERBLOCKIMPORT)) { + LogPrintf("Stopping after block import\n"); + StartShutdown(); + return; + } + } // End scope of CImportingNow + chainman.ActiveChainstate().LoadMempool(config, args); +}