mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
Merge #21575: refactor: Create blockstorage module
fadcd3f78e
doc: Remove irrelevant link to GitHub (MarcoFalke)fa121b628d
blockstorage: [refactor] Use chainman reference where possible (MarcoFalke)fa0c7d9ad2
move-only: Move *Disk functions to blockstorage (MarcoFalke)fa91b2b2b3
move-only: Move AbortNode to shutdown (MarcoFalke)fa413f07a1
move-only: Move ThreadImport to blockstorage (MarcoFalke)faf843c07f
refactor: Move load block thread into ChainstateManager (MarcoFalke) Pull request description: This picks up the closed pull request #21030 and is the first step toward fixing #21220. The basic idea is to move all disk access into a separate module with benefits: * Breaking down the massive files init.cpp and validation.cpp into logical units * Creating a standalone-module to reduce the mental complexity * Pave the way to fix validation related circular dependencies * Pave the way to mock disk access for testing, especially where it is performance critical (like fuzzing) ACKs for top commit: promag: Code review ACKfadcd3f78e
, checked (almost) moved only changes. This is a nice tidy up change and doesn't change behavior. Easily reviewed commit by commit. jamesob: ACKfadcd3f78e
([`jamesob/ackr/21575.1.MarcoFalke.refactor_create_blocksto`](https://github.com/jamesob/bitcoin/tree/ackr/21575.1.MarcoFalke.refactor_create_blocksto)) ryanofsky: Code review ACKfadcd3f78e
. New organization makes sense, moves extraneous things outside of validation.cpp. PR is also easy to review with helpfully split up moveonly commits. Tree-SHA512: 917996592b6d8f9998289d8cb2b1b78b23d1fdb3b07216c9caec1380df33baa09dc2c1e706da669d440b497e79c9c62a01ca20dc202df5ad974a75f3ef7a143b
This commit is contained in:
commit
1f14130cb0
19 changed files with 330 additions and 258 deletions
|
@ -175,6 +175,7 @@ BITCOIN_CORE_H = \
|
||||||
netaddress.h \
|
netaddress.h \
|
||||||
netbase.h \
|
netbase.h \
|
||||||
netmessagemaker.h \
|
netmessagemaker.h \
|
||||||
|
node/blockstorage.h \
|
||||||
node/coin.h \
|
node/coin.h \
|
||||||
node/coinstats.h \
|
node/coinstats.h \
|
||||||
node/context.h \
|
node/context.h \
|
||||||
|
@ -323,6 +324,7 @@ libbitcoin_server_a_SOURCES = \
|
||||||
miner.cpp \
|
miner.cpp \
|
||||||
net.cpp \
|
net.cpp \
|
||||||
net_processing.cpp \
|
net_processing.cpp \
|
||||||
|
node/blockstorage.cpp \
|
||||||
node/coin.cpp \
|
node/coin.cpp \
|
||||||
node/coinstats.cpp \
|
node/coinstats.cpp \
|
||||||
node/context.cpp \
|
node/context.cpp \
|
||||||
|
|
|
@ -4,12 +4,13 @@
|
||||||
|
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <index/base.h>
|
#include <index/base.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/ui_interface.h>
|
#include <node/ui_interface.h>
|
||||||
#include <shutdown.h>
|
#include <shutdown.h>
|
||||||
#include <tinyformat.h>
|
#include <tinyformat.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <util/translation.h>
|
#include <util/translation.h>
|
||||||
#include <validation.h>
|
#include <validation.h> // For g_chainman
|
||||||
#include <warnings.h>
|
#include <warnings.h>
|
||||||
|
|
||||||
constexpr char DB_BEST_BLOCK = 'B';
|
constexpr char DB_BEST_BLOCK = 'B';
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
#include <dbwrapper.h>
|
#include <dbwrapper.h>
|
||||||
#include <index/blockfilterindex.h>
|
#include <index/blockfilterindex.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <validation.h>
|
|
||||||
|
|
||||||
/* The index database stores three items for each block: the disk location of the encoded filter,
|
/* The index database stores three items for each block: the disk location of the encoded filter,
|
||||||
* its dSHA256 hash, and the header. Those belonging to blocks on the active chain are indexed by
|
* its dSHA256 hash, and the header. Those belonging to blocks on the active chain are indexed by
|
||||||
|
|
95
src/init.cpp
95
src/init.cpp
|
@ -16,7 +16,6 @@
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <compat/sanity.h>
|
#include <compat/sanity.h>
|
||||||
#include <consensus/validation.h>
|
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <httprpc.h>
|
#include <httprpc.h>
|
||||||
|
@ -32,6 +31,7 @@
|
||||||
#include <net_permissions.h>
|
#include <net_permissions.h>
|
||||||
#include <net_processing.h>
|
#include <net_processing.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <node/ui_interface.h>
|
#include <node/ui_interface.h>
|
||||||
#include <policy/feerate.h>
|
#include <policy/feerate.h>
|
||||||
|
@ -61,7 +61,6 @@
|
||||||
#include <util/threadnames.h>
|
#include <util/threadnames.h>
|
||||||
#include <util/translation.h>
|
#include <util/translation.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
#include <walletinitinterface.h>
|
#include <walletinitinterface.h>
|
||||||
|
|
||||||
|
@ -90,7 +89,6 @@
|
||||||
|
|
||||||
static const bool DEFAULT_PROXYRANDOMIZE = true;
|
static const bool DEFAULT_PROXYRANDOMIZE = true;
|
||||||
static const bool DEFAULT_REST_ENABLE = false;
|
static const bool DEFAULT_REST_ENABLE = false;
|
||||||
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
|
// Win32 LevelDB doesn't use filedescriptors, and the ones used for
|
||||||
|
@ -155,8 +153,6 @@ static fs::path GetPidFile(const ArgsManager& args)
|
||||||
|
|
||||||
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
||||||
|
|
||||||
static std::thread g_load_block;
|
|
||||||
|
|
||||||
void Interrupt(NodeContext& node)
|
void Interrupt(NodeContext& node)
|
||||||
{
|
{
|
||||||
InterruptHTTPServer();
|
InterruptHTTPServer();
|
||||||
|
@ -220,7 +216,7 @@ void Shutdown(NodeContext& node)
|
||||||
// After everything has been shut down, but before things get flushed, stop the
|
// After everything has been shut down, but before things get flushed, stop the
|
||||||
// CScheduler/checkqueue, scheduler and load block thread.
|
// CScheduler/checkqueue, scheduler and load block thread.
|
||||||
if (node.scheduler) node.scheduler->stop();
|
if (node.scheduler) node.scheduler->stop();
|
||||||
if (g_load_block.joinable()) g_load_block.join();
|
if (node.chainman && node.chainman->m_load_block.joinable()) node.chainman->m_load_block.join();
|
||||||
StopScriptCheckWorkerThreads();
|
StopScriptCheckWorkerThreads();
|
||||||
|
|
||||||
// After the threads that potentially access these pointers have been stopped,
|
// After the threads that potentially access these pointers have been stopped,
|
||||||
|
@ -627,20 +623,6 @@ static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
// 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
|
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
|
||||||
// is missing, do the same here to delete any later block files after a gap. Also delete all
|
// is missing, do the same here to delete any later block files after a gap. Also delete all
|
||||||
|
@ -693,77 +675,6 @@ static void StartupNotify(const ArgsManager& args)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
|
|
||||||
{
|
|
||||||
const CChainParams& chainparams = Params();
|
|
||||||
ScheduleBatchPriority();
|
|
||||||
|
|
||||||
{
|
|
||||||
CImportingNow imp;
|
|
||||||
|
|
||||||
// -reindex
|
|
||||||
if (fReindex) {
|
|
||||||
int nFile = 0;
|
|
||||||
while (true) {
|
|
||||||
FlatFilePos pos(nFile, 0);
|
|
||||||
if (!fs::exists(GetBlockPosFilename(pos)))
|
|
||||||
break; // No block files left to reindex
|
|
||||||
FILE *file = OpenBlockFile(pos, true);
|
|
||||||
if (!file)
|
|
||||||
break; // This error is logged in OpenBlockFile
|
|
||||||
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
|
|
||||||
::ChainstateActive().LoadExternalBlockFile(chainparams, 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", path.string());
|
|
||||||
::ChainstateActive().LoadExternalBlockFile(chainparams, file);
|
|
||||||
if (ShutdownRequested()) {
|
|
||||||
LogPrintf("Shutdown requested. Exit %s\n", __func__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
LogPrintf("Warning: Could not open blocks file %s\n", path.string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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(state, chainparams, 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(args);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Sanity checks
|
/** Sanity checks
|
||||||
* Ensure that Bitcoin is running in a usable environment with all
|
* Ensure that Bitcoin is running in a usable environment with all
|
||||||
* necessary library support.
|
* necessary library support.
|
||||||
|
@ -1880,7 +1791,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
|
||||||
vImportFiles.push_back(strFile);
|
vImportFiles.push_back(strFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
|
chainman.m_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
|
||||||
ThreadImport(chainman, vImportFiles, args);
|
ThreadImport(chainman, vImportFiles, args);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <merkleblock.h>
|
#include <merkleblock.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
#include <netmessagemaker.h>
|
#include <netmessagemaker.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <policy/fees.h>
|
#include <policy/fees.h>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
|
|
|
@ -15,8 +15,7 @@ As a rule of thumb, code in one of the [`src/node/`](./),
|
||||||
calling code in the other directories directly, and only invoke it indirectly
|
calling code in the other directories directly, and only invoke it indirectly
|
||||||
through the more limited [`src/interfaces/`](../interfaces/) classes.
|
through the more limited [`src/interfaces/`](../interfaces/) classes.
|
||||||
|
|
||||||
The [`src/node/`](./) directory is a new directory introduced in
|
This directory is at the moment
|
||||||
[#14978](https://github.com/bitcoin/bitcoin/pull/14978) and at the moment is
|
|
||||||
sparsely populated. Eventually more substantial files like
|
sparsely populated. Eventually more substantial files like
|
||||||
[`src/validation.cpp`](../validation.cpp) and
|
[`src/validation.cpp`](../validation.cpp) and
|
||||||
[`src/txmempool.cpp`](../txmempool.cpp) might be moved there.
|
[`src/txmempool.cpp`](../txmempool.cpp) might be moved there.
|
||||||
|
|
244
src/node/blockstorage.cpp
Normal file
244
src/node/blockstorage.cpp
Normal file
|
@ -0,0 +1,244 @@
|
||||||
|
// Copyright (c) 2011-2021 The Bitcoin Core developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#include <node/blockstorage.h>
|
||||||
|
|
||||||
|
#include <chain.h>
|
||||||
|
#include <chainparams.h>
|
||||||
|
#include <flatfile.h>
|
||||||
|
#include <fs.h>
|
||||||
|
#include <pow.h>
|
||||||
|
#include <shutdown.h>
|
||||||
|
#include <signet.h>
|
||||||
|
#include <streams.h>
|
||||||
|
#include <util/system.h>
|
||||||
|
#include <validation.h>
|
||||||
|
|
||||||
|
// From validation. TODO move here
|
||||||
|
bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false);
|
||||||
|
|
||||||
|
static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
|
||||||
|
{
|
||||||
|
// Open history file to append
|
||||||
|
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
|
||||||
|
if (fileout.IsNull()) {
|
||||||
|
return error("WriteBlockToDisk: OpenBlockFile failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write index header
|
||||||
|
unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
|
||||||
|
fileout << messageStart << nSize;
|
||||||
|
|
||||||
|
// Write block
|
||||||
|
long fileOutPos = ftell(fileout.Get());
|
||||||
|
if (fileOutPos < 0) {
|
||||||
|
return error("WriteBlockToDisk: ftell failed");
|
||||||
|
}
|
||||||
|
pos.nPos = (unsigned int)fileOutPos;
|
||||||
|
fileout << block;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
|
||||||
|
{
|
||||||
|
block.SetNull();
|
||||||
|
|
||||||
|
// Open history file to read
|
||||||
|
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
|
||||||
|
if (filein.IsNull()) {
|
||||||
|
return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read block
|
||||||
|
try {
|
||||||
|
filein >> block;
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the header
|
||||||
|
if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) {
|
||||||
|
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Signet only: check block solution
|
||||||
|
if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) {
|
||||||
|
return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
||||||
|
{
|
||||||
|
FlatFilePos blockPos;
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
blockPos = pindex->GetBlockPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ReadBlockFromDisk(block, blockPos, consensusParams)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (block.GetHash() != pindex->GetBlockHash()) {
|
||||||
|
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
|
||||||
|
pindex->ToString(), pindex->GetBlockPos().ToString());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
|
||||||
|
{
|
||||||
|
FlatFilePos hpos = pos;
|
||||||
|
hpos.nPos -= 8; // Seek back 8 bytes for meta header
|
||||||
|
CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION);
|
||||||
|
if (filein.IsNull()) {
|
||||||
|
return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
CMessageHeader::MessageStartChars blk_start;
|
||||||
|
unsigned int blk_size;
|
||||||
|
|
||||||
|
filein >> blk_start >> blk_size;
|
||||||
|
|
||||||
|
if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) {
|
||||||
|
return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(),
|
||||||
|
HexStr(blk_start),
|
||||||
|
HexStr(message_start));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blk_size > MAX_SIZE) {
|
||||||
|
return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(),
|
||||||
|
blk_size, MAX_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
block.resize(blk_size); // Zeroing of memory is intentional here
|
||||||
|
filein.read((char*)block.data(), blk_size);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start)
|
||||||
|
{
|
||||||
|
FlatFilePos block_pos;
|
||||||
|
{
|
||||||
|
LOCK(cs_main);
|
||||||
|
block_pos = pindex->GetBlockPos();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ReadRawBlockFromDisk(block, block_pos, message_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
|
||||||
|
FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp)
|
||||||
|
{
|
||||||
|
unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
|
||||||
|
FlatFilePos blockPos;
|
||||||
|
if (dbp != nullptr) {
|
||||||
|
blockPos = *dbp;
|
||||||
|
}
|
||||||
|
if (!FindBlockPos(blockPos, nBlockSize + 8, nHeight, active_chain, block.GetBlockTime(), dbp != nullptr)) {
|
||||||
|
error("%s: FindBlockPos failed", __func__);
|
||||||
|
return FlatFilePos();
|
||||||
|
}
|
||||||
|
if (dbp == nullptr) {
|
||||||
|
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
|
||||||
|
AbortNode("Failed to write block");
|
||||||
|
return FlatFilePos();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return blockPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CImportingNow {
|
||||||
|
CImportingNow()
|
||||||
|
{
|
||||||
|
assert(fImporting == false);
|
||||||
|
fImporting = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CImportingNow()
|
||||||
|
{
|
||||||
|
assert(fImporting == true);
|
||||||
|
fImporting = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
|
||||||
|
{
|
||||||
|
const CChainParams& chainparams = Params();
|
||||||
|
ScheduleBatchPriority();
|
||||||
|
|
||||||
|
{
|
||||||
|
CImportingNow imp;
|
||||||
|
|
||||||
|
// -reindex
|
||||||
|
if (fReindex) {
|
||||||
|
int nFile = 0;
|
||||||
|
while (true) {
|
||||||
|
FlatFilePos pos(nFile, 0);
|
||||||
|
if (!fs::exists(GetBlockPosFilename(pos))) {
|
||||||
|
break; // No block files left to reindex
|
||||||
|
}
|
||||||
|
FILE* file = OpenBlockFile(pos, true);
|
||||||
|
if (!file) {
|
||||||
|
break; // This error is logged in OpenBlockFile
|
||||||
|
}
|
||||||
|
LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
|
||||||
|
chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, 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):
|
||||||
|
chainman.ActiveChainstate().LoadGenesisBlock(chainparams);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -loadblock=
|
||||||
|
for (const fs::path& path : vImportFiles) {
|
||||||
|
FILE* file = fsbridge::fopen(path, "rb");
|
||||||
|
if (file) {
|
||||||
|
LogPrintf("Importing blocks file %s...\n", path.string());
|
||||||
|
chainman.ActiveChainstate().LoadExternalBlockFile(chainparams, file);
|
||||||
|
if (ShutdownRequested()) {
|
||||||
|
LogPrintf("Shutdown requested. Exit %s\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LogPrintf("Warning: Could not open blocks file %s\n", path.string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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(state, chainparams, 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(args);
|
||||||
|
}
|
40
src/node/blockstorage.h
Normal file
40
src/node/blockstorage.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
// Copyright (c) 2011-2021 The Bitcoin Core 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 <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <fs.h>
|
||||||
|
#include <protocol.h> // For CMessageHeader::MessageStartChars
|
||||||
|
|
||||||
|
class ArgsManager;
|
||||||
|
class CBlock;
|
||||||
|
class CBlockIndex;
|
||||||
|
class CBlockUndo;
|
||||||
|
class CChain;
|
||||||
|
class CChainParams;
|
||||||
|
class ChainstateManager;
|
||||||
|
struct FlatFilePos;
|
||||||
|
namespace Consensus {
|
||||||
|
struct Params;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
|
||||||
|
|
||||||
|
/** Functions for disk access for blocks */
|
||||||
|
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
|
||||||
|
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
|
||||||
|
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
|
||||||
|
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
|
||||||
|
|
||||||
|
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
|
||||||
|
|
||||||
|
FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
|
||||||
|
|
||||||
|
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args);
|
||||||
|
|
||||||
|
#endif // BITCOIN_NODE_BLOCKSTORAGE_H
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include <addrdb.h>
|
#include <addrdb.h>
|
||||||
#include <banman.h>
|
#include <banman.h>
|
||||||
#include <boost/signals2/signal.hpp>
|
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
#include <init.h>
|
#include <init.h>
|
||||||
|
@ -17,6 +16,7 @@
|
||||||
#include <net_processing.h>
|
#include <net_processing.h>
|
||||||
#include <netaddress.h>
|
#include <netaddress.h>
|
||||||
#include <netbase.h>
|
#include <netbase.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/coin.h>
|
#include <node/coin.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <node/transaction.h>
|
#include <node/transaction.h>
|
||||||
|
@ -53,6 +53,8 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <boost/signals2/signal.hpp>
|
||||||
|
|
||||||
using interfaces::BlockTip;
|
using interfaces::BlockTip;
|
||||||
using interfaces::Chain;
|
using interfaces::Chain;
|
||||||
using interfaces::FoundBlock;
|
using interfaces::FoundBlock;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <httpserver.h>
|
#include <httpserver.h>
|
||||||
#include <index/txindex.h>
|
#include <index/txindex.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <primitives/block.h>
|
#include <primitives/block.h>
|
||||||
#include <primitives/transaction.h>
|
#include <primitives/transaction.h>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <core_io.h>
|
#include <core_io.h>
|
||||||
#include <hash.h>
|
#include <hash.h>
|
||||||
#include <index/blockfilterindex.h>
|
#include <index/blockfilterindex.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/coinstats.h>
|
#include <node/coinstats.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <node/utxo_snapshot.h>
|
#include <node/utxo_snapshot.h>
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <index/txindex.h>
|
#include <index/txindex.h>
|
||||||
#include <key_io.h>
|
#include <key_io.h>
|
||||||
#include <merkleblock.h>
|
#include <merkleblock.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/coin.h>
|
#include <node/coin.h>
|
||||||
#include <node/context.h>
|
#include <node/context.h>
|
||||||
#include <node/psbt.h>
|
#include <node/psbt.h>
|
||||||
|
|
|
@ -6,7 +6,9 @@
|
||||||
#include <shutdown.h>
|
#include <shutdown.h>
|
||||||
|
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
|
#include <node/ui_interface.h>
|
||||||
#include <util/tokenpipe.h>
|
#include <util/tokenpipe.h>
|
||||||
|
#include <warnings.h>
|
||||||
|
|
||||||
#include <config/bitcoin-config.h>
|
#include <config/bitcoin-config.h>
|
||||||
|
|
||||||
|
@ -16,6 +18,18 @@
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool AbortNode(const std::string& strMessage, bilingual_str user_message)
|
||||||
|
{
|
||||||
|
SetMiscWarning(Untranslated(strMessage));
|
||||||
|
LogPrintf("*** %s\n", strMessage);
|
||||||
|
if (user_message.empty()) {
|
||||||
|
user_message = _("A fatal internal error occurred, see debug.log for details");
|
||||||
|
}
|
||||||
|
AbortError(user_message);
|
||||||
|
StartShutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static std::atomic<bool> fRequestShutdown(false);
|
static std::atomic<bool> fRequestShutdown(false);
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/** On windows it is possible to simply use a condition variable. */
|
/** On windows it is possible to simply use a condition variable. */
|
||||||
|
|
|
@ -6,6 +6,11 @@
|
||||||
#ifndef BITCOIN_SHUTDOWN_H
|
#ifndef BITCOIN_SHUTDOWN_H
|
||||||
#define BITCOIN_SHUTDOWN_H
|
#define BITCOIN_SHUTDOWN_H
|
||||||
|
|
||||||
|
#include <util/translation.h> // For bilingual_str
|
||||||
|
|
||||||
|
/** Abort with a message */
|
||||||
|
bool AbortNode(const std::string& strMessage, bilingual_str user_message = bilingual_str{});
|
||||||
|
|
||||||
/** Initialize shutdown state. This must be called before using either StartShutdown(),
|
/** Initialize shutdown state. This must be called before using either StartShutdown(),
|
||||||
* AbortShutdown() or WaitForShutdown(). Calling ShutdownRequested() is always safe.
|
* AbortShutdown() or WaitForShutdown(). Calling ShutdownRequested() is always safe.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include <test/util/blockfilter.h>
|
#include <test/util/blockfilter.h>
|
||||||
|
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <validation.h>
|
#include <validation.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <index/txindex.h>
|
#include <index/txindex.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <logging/timer.h>
|
#include <logging/timer.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <node/coinstats.h>
|
#include <node/coinstats.h>
|
||||||
#include <node/ui_interface.h>
|
#include <node/ui_interface.h>
|
||||||
#include <policy/policy.h>
|
#include <policy/policy.h>
|
||||||
|
@ -1148,123 +1149,6 @@ CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMe
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// CBlock and CBlockIndex
|
|
||||||
//
|
|
||||||
|
|
||||||
static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
|
|
||||||
{
|
|
||||||
// Open history file to append
|
|
||||||
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
|
|
||||||
if (fileout.IsNull())
|
|
||||||
return error("WriteBlockToDisk: OpenBlockFile failed");
|
|
||||||
|
|
||||||
// Write index header
|
|
||||||
unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
|
|
||||||
fileout << messageStart << nSize;
|
|
||||||
|
|
||||||
// Write block
|
|
||||||
long fileOutPos = ftell(fileout.Get());
|
|
||||||
if (fileOutPos < 0)
|
|
||||||
return error("WriteBlockToDisk: ftell failed");
|
|
||||||
pos.nPos = (unsigned int)fileOutPos;
|
|
||||||
fileout << block;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
|
|
||||||
{
|
|
||||||
block.SetNull();
|
|
||||||
|
|
||||||
// Open history file to read
|
|
||||||
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
|
|
||||||
if (filein.IsNull())
|
|
||||||
return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
|
|
||||||
|
|
||||||
// Read block
|
|
||||||
try {
|
|
||||||
filein >> block;
|
|
||||||
}
|
|
||||||
catch (const std::exception& e) {
|
|
||||||
return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the header
|
|
||||||
if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams))
|
|
||||||
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
|
|
||||||
|
|
||||||
// Signet only: check block solution
|
|
||||||
if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) {
|
|
||||||
return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
|
||||||
{
|
|
||||||
FlatFilePos blockPos;
|
|
||||||
{
|
|
||||||
LOCK(cs_main);
|
|
||||||
blockPos = pindex->GetBlockPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ReadBlockFromDisk(block, blockPos, consensusParams))
|
|
||||||
return false;
|
|
||||||
if (block.GetHash() != pindex->GetBlockHash())
|
|
||||||
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
|
|
||||||
pindex->ToString(), pindex->GetBlockPos().ToString());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
|
|
||||||
{
|
|
||||||
FlatFilePos hpos = pos;
|
|
||||||
hpos.nPos -= 8; // Seek back 8 bytes for meta header
|
|
||||||
CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION);
|
|
||||||
if (filein.IsNull()) {
|
|
||||||
return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
CMessageHeader::MessageStartChars blk_start;
|
|
||||||
unsigned int blk_size;
|
|
||||||
|
|
||||||
filein >> blk_start >> blk_size;
|
|
||||||
|
|
||||||
if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) {
|
|
||||||
return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(),
|
|
||||||
HexStr(blk_start),
|
|
||||||
HexStr(message_start));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blk_size > MAX_SIZE) {
|
|
||||||
return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(),
|
|
||||||
blk_size, MAX_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
block.resize(blk_size); // Zeroing of memory is intentional here
|
|
||||||
filein.read((char*)block.data(), blk_size);
|
|
||||||
} catch(const std::exception& e) {
|
|
||||||
return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start)
|
|
||||||
{
|
|
||||||
FlatFilePos block_pos;
|
|
||||||
{
|
|
||||||
LOCK(cs_main);
|
|
||||||
block_pos = pindex->GetBlockPos();
|
|
||||||
}
|
|
||||||
|
|
||||||
return ReadRawBlockFromDisk(block, block_pos, message_start);
|
|
||||||
}
|
|
||||||
|
|
||||||
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
|
CAmount GetBlockSubsidy(int nHeight, const Consensus::Params& consensusParams)
|
||||||
{
|
{
|
||||||
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
|
int halvings = nHeight / consensusParams.nSubsidyHalvingInterval;
|
||||||
|
@ -1636,19 +1520,6 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Abort with a message */
|
|
||||||
static bool AbortNode(const std::string& strMessage, bilingual_str user_message = bilingual_str())
|
|
||||||
{
|
|
||||||
SetMiscWarning(Untranslated(strMessage));
|
|
||||||
LogPrintf("*** %s\n", strMessage);
|
|
||||||
if (user_message.empty()) {
|
|
||||||
user_message = _("A fatal internal error occurred, see debug.log for details");
|
|
||||||
}
|
|
||||||
AbortError(user_message);
|
|
||||||
StartShutdown();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = bilingual_str())
|
static bool AbortNode(BlockValidationState& state, const std::string& strMessage, const bilingual_str& userMessage = bilingual_str())
|
||||||
{
|
{
|
||||||
AbortNode(strMessage, userMessage);
|
AbortNode(strMessage, userMessage);
|
||||||
|
@ -3231,7 +3102,8 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
|
// TODO move to blockstorage
|
||||||
|
bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
|
||||||
{
|
{
|
||||||
LOCK(cs_LastBlockFile);
|
LOCK(cs_LastBlockFile);
|
||||||
|
|
||||||
|
@ -3708,25 +3580,6 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
|
|
||||||
static FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp) {
|
|
||||||
unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
|
|
||||||
FlatFilePos blockPos;
|
|
||||||
if (dbp != nullptr)
|
|
||||||
blockPos = *dbp;
|
|
||||||
if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, active_chain, block.GetBlockTime(), dbp != nullptr)) {
|
|
||||||
error("%s: FindBlockPos failed", __func__);
|
|
||||||
return FlatFilePos();
|
|
||||||
}
|
|
||||||
if (dbp == nullptr) {
|
|
||||||
if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
|
|
||||||
AbortNode("Failed to write block");
|
|
||||||
return FlatFilePos();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return blockPos;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
|
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
|
||||||
bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
|
bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, const CChainParams& chainparams, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -299,15 +300,6 @@ public:
|
||||||
/** Initializes the script-execution cache */
|
/** Initializes the script-execution cache */
|
||||||
void InitScriptExecutionCache();
|
void InitScriptExecutionCache();
|
||||||
|
|
||||||
|
|
||||||
/** Functions for disk access for blocks */
|
|
||||||
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
|
|
||||||
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
|
|
||||||
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
|
|
||||||
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
|
|
||||||
|
|
||||||
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
|
|
||||||
|
|
||||||
/** Functions for validating blocks and updating the block tree */
|
/** Functions for validating blocks and updating the block tree */
|
||||||
|
|
||||||
/** Context-independent validity checks */
|
/** Context-independent validity checks */
|
||||||
|
@ -869,6 +861,7 @@ private:
|
||||||
friend CChain& ChainActive();
|
friend CChain& ChainActive();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
std::thread m_load_block;
|
||||||
//! A single BlockManager instance is shared across each constructed
|
//! A single BlockManager instance is shared across each constructed
|
||||||
//! chainstate to avoid duplicating block metadata.
|
//! chainstate to avoid duplicating block metadata.
|
||||||
BlockManager m_blockman GUARDED_BY(::cs_main);
|
BlockManager m_blockman GUARDED_BY(::cs_main);
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
|
|
||||||
#include <chain.h>
|
#include <chain.h>
|
||||||
#include <chainparams.h>
|
#include <chainparams.h>
|
||||||
|
#include <node/blockstorage.h>
|
||||||
#include <rpc/server.h>
|
#include <rpc/server.h>
|
||||||
#include <streams.h>
|
#include <streams.h>
|
||||||
#include <util/system.h>
|
#include <util/system.h>
|
||||||
#include <validation.h>
|
#include <validation.h> // For cs_main
|
||||||
#include <zmq/zmqutil.h>
|
#include <zmq/zmqutil.h>
|
||||||
|
|
||||||
#include <zmq.h>
|
#include <zmq.h>
|
||||||
|
|
|
@ -11,7 +11,9 @@ export LC_ALL=C
|
||||||
EXPECTED_CIRCULAR_DEPENDENCIES=(
|
EXPECTED_CIRCULAR_DEPENDENCIES=(
|
||||||
"chainparamsbase -> util/system -> chainparamsbase"
|
"chainparamsbase -> util/system -> chainparamsbase"
|
||||||
"index/txindex -> validation -> index/txindex"
|
"index/txindex -> validation -> index/txindex"
|
||||||
"index/blockfilterindex -> validation -> index/blockfilterindex"
|
"node/blockstorage -> validation -> node/blockstorage"
|
||||||
|
"index/blockfilterindex -> node/blockstorage -> validation -> index/blockfilterindex"
|
||||||
|
"index/base -> validation -> index/blockfilterindex -> index/base"
|
||||||
"policy/fees -> txmempool -> policy/fees"
|
"policy/fees -> txmempool -> policy/fees"
|
||||||
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel"
|
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel"
|
||||||
"qt/bitcoingui -> qt/walletframe -> qt/bitcoingui"
|
"qt/bitcoingui -> qt/walletframe -> qt/bitcoingui"
|
||||||
|
|
Loading…
Add table
Reference in a new issue