mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 19:42:46 +01:00
merge bitcoin#21575: Create blockstorage module
This commit is contained in:
parent
94b706e402
commit
b1643e7c86
@ -247,6 +247,7 @@ BITCOIN_CORE_H = \
|
||||
netbase.h \
|
||||
netfulfilledman.h \
|
||||
netmessagemaker.h \
|
||||
node/blockstorage.h \
|
||||
node/coin.h \
|
||||
node/coinstats.h \
|
||||
node/context.h \
|
||||
@ -441,6 +442,7 @@ libbitcoin_server_a_SOURCES = \
|
||||
net.cpp \
|
||||
netfulfilledman.cpp \
|
||||
net_processing.cpp \
|
||||
node/blockstorage.cpp \
|
||||
node/coin.cpp \
|
||||
node/coinstats.cpp \
|
||||
node/context.cpp \
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <llmq/chainlocks.h>
|
||||
#include <llmq/commitment.h>
|
||||
#include <llmq/utils.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <evo/simplifiedmns.h>
|
||||
#include <evo/specialtx.h>
|
||||
#include <consensus/validation.h>
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <chain.h>
|
||||
#include <logging.h>
|
||||
#include <validation.h>
|
||||
#include <node/blockstorage.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <exception>
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <llmq/commitment.h>
|
||||
#include <llmq/quorums.h>
|
||||
#include <llmq/utils.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <evo/specialtx.h>
|
||||
|
||||
#include <pubkey.h>
|
||||
|
@ -4,11 +4,12 @@
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <index/base.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <shutdown.h>
|
||||
#include <tinyformat.h>
|
||||
#include <ui_interface.h>
|
||||
#include <util/translation.h>
|
||||
#include <validation.h>
|
||||
#include <validation.h> // For g_chainman
|
||||
#include <warnings.h>
|
||||
|
||||
constexpr char DB_BEST_BLOCK = 'B';
|
||||
|
@ -6,9 +6,8 @@
|
||||
|
||||
#include <dbwrapper.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <serialize.h>
|
||||
#include <util/system.h>
|
||||
#include <validation.h>
|
||||
|
||||
/* 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
|
||||
|
122
src/init.cpp
122
src/init.cpp
@ -20,7 +20,6 @@
|
||||
#include <context.h>
|
||||
#include <node/coinstats.h>
|
||||
#include <compat/sanity.h>
|
||||
#include <consensus/validation.h>
|
||||
#include <fs.h>
|
||||
#include <hash.h>
|
||||
#include <httpserver.h>
|
||||
@ -36,6 +35,7 @@
|
||||
#include <net_permissions.h>
|
||||
#include <net_processing.h>
|
||||
#include <netbase.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/context.h>
|
||||
#include <policy/feerate.h>
|
||||
#include <policy/fees.h>
|
||||
@ -123,7 +123,6 @@
|
||||
|
||||
static const bool DEFAULT_PROXYRANDOMIZE = true;
|
||||
static const bool DEFAULT_REST_ENABLE = false;
|
||||
static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
|
||||
|
||||
static CDSNotificationInterface* pdsNotificationInterface = nullptr;
|
||||
|
||||
@ -189,8 +188,6 @@ static fs::path GetPidFile(const ArgsManager& args)
|
||||
|
||||
static std::unique_ptr<ECCVerifyHandle> globalVerifyHandle;
|
||||
|
||||
static std::thread g_load_block;
|
||||
|
||||
void Interrupt(NodeContext& node)
|
||||
{
|
||||
InterruptHTTPServer();
|
||||
@ -266,7 +263,7 @@ void PrepareShutdown(NodeContext& node)
|
||||
// After everything has been shut down, but before things get flushed, stop the
|
||||
// CScheduler/checkqueue, threadGroup and load block thread.
|
||||
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();
|
||||
|
||||
// After there are no more peers/RPC left to give us new data which may generate
|
||||
@ -825,20 +822,6 @@ static void BlockNotifyGenesisWait(bool, 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
|
||||
// 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
|
||||
@ -880,103 +863,6 @@ static void CleanupBlockRevFiles()
|
||||
}
|
||||
}
|
||||
|
||||
static void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
|
||||
{
|
||||
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(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();
|
||||
}
|
||||
|
||||
// -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(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, 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
|
||||
|
||||
// force UpdatedBlockTip to initialize nCachedBlockHeight for DS, MN payments and budgets
|
||||
// but don't call it directly to prevent triggering of other listeners like zmq etc.
|
||||
// GetMainSignals().UpdatedBlockTip(::ChainActive().Tip());
|
||||
pdsNotificationInterface->InitializeCurrentBlockTip();
|
||||
|
||||
{
|
||||
// Get all UTXOs for each MN collateral in one go so that we can fill coin cache early
|
||||
// and reduce further locking overhead for cs_main in other parts of code including GUI
|
||||
LogPrintf("Filling coin cache with masternode UTXOs...\n");
|
||||
LOCK(cs_main);
|
||||
int64_t nStart = GetTimeMillis();
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
mnList.ForEachMN(false, [&](auto& dmn) {
|
||||
Coin coin;
|
||||
GetUTXOCoin(dmn.collateralOutpoint, coin);
|
||||
});
|
||||
LogPrintf("Filling coin cache with masternode UTXOs: done in %dms\n", GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
if (fMasternodeMode) {
|
||||
assert(activeMasternodeManager);
|
||||
activeMasternodeManager->Init(::ChainActive().Tip());
|
||||
}
|
||||
|
||||
g_wallet_init_interface.AutoLockMasternodeCollaterals();
|
||||
|
||||
chainman.ActiveChainstate().LoadMempool(args);
|
||||
}
|
||||
|
||||
static void PeriodicStats(ArgsManager& args, const CTxMemPool& mempool)
|
||||
{
|
||||
assert(args.GetBoolArg("-statsenabled", DEFAULT_STATSD_ENABLE));
|
||||
@ -2468,7 +2354,9 @@ bool AppInitMain(const CoreContext& context, NodeContext& node, interfaces::Bloc
|
||||
vImportFiles.push_back(strFile);
|
||||
}
|
||||
|
||||
g_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args]{ ThreadImport(chainman, vImportFiles, args); });
|
||||
chainman.m_load_block = std::thread(&TraceThread<std::function<void()>>, "loadblk", [=, &chainman, &args] {
|
||||
ThreadImport(chainman, *pdsNotificationInterface ,vImportFiles, args);
|
||||
});
|
||||
|
||||
// Wait for genesis block to be processed
|
||||
{
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <consensus/validation.h>
|
||||
#include <net.h>
|
||||
#include <net_processing.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
#include <saltedhasher.h>
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <consensus/validation.h>
|
||||
#include <masternode/sync.h>
|
||||
#include <net_processing.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <scheduler.h>
|
||||
#include <spork.h>
|
||||
#include <txmempool.h>
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <merkleblock.h>
|
||||
#include <netmessagemaker.h>
|
||||
#include <netbase.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <policy/policy.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.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
|
||||
through the more limited [`src/interfaces/`](../interfaces/) classes.
|
||||
|
||||
The [`src/node/`](./) directory is a new directory introduced in
|
||||
[#14978](https://github.com/bitcoin/bitcoin/pull/14978) and at the moment is
|
||||
This directory is at the moment
|
||||
sparsely populated. Eventually more substantial files like
|
||||
[`src/validation.cpp`](../validation.cpp) and
|
||||
[`src/txmempool.cpp`](../txmempool.cpp) might be moved there.
|
||||
|
223
src/node/blockstorage.cpp
Normal file
223
src/node/blockstorage.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
// 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 <consensus/validation.h>
|
||||
#include <dsnotificationinterface.h>
|
||||
#include <evo/deterministicmns.h>
|
||||
#include <flatfile.h>
|
||||
#include <fs.h>
|
||||
#include <masternode/node.h>
|
||||
#include <pow.h>
|
||||
#include <shutdown.h>
|
||||
#include <streams.h>
|
||||
#include <util/system.h>
|
||||
#include <validation.h>
|
||||
#include <walletinitinterface.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());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/** 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, CDSNotificationInterface& dsnfi, std::vector<fs::path> vImportFiles, const ArgsManager& args)
|
||||
{
|
||||
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(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();
|
||||
}
|
||||
|
||||
// -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(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, 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
|
||||
|
||||
// force UpdatedBlockTip to initialize nCachedBlockHeight for DS, MN payments and budgets
|
||||
// but don't call it directly to prevent triggering of other listeners like zmq etc.
|
||||
// GetMainSignals().UpdatedBlockTip(::ChainActive().Tip());
|
||||
dsnfi.InitializeCurrentBlockTip();
|
||||
|
||||
{
|
||||
// Get all UTXOs for each MN collateral in one go so that we can fill coin cache early
|
||||
// and reduce further locking overhead for cs_main in other parts of code including GUI
|
||||
LogPrintf("Filling coin cache with masternode UTXOs...\n");
|
||||
LOCK(cs_main);
|
||||
int64_t nStart = GetTimeMillis();
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
mnList.ForEachMN(false, [&](auto& dmn) {
|
||||
Coin coin;
|
||||
GetUTXOCoin(dmn.collateralOutpoint, coin);
|
||||
});
|
||||
LogPrintf("Filling coin cache with masternode UTXOs: done in %dms\n", GetTimeMillis() - nStart);
|
||||
}
|
||||
|
||||
if (fMasternodeMode) {
|
||||
assert(activeMasternodeManager);
|
||||
activeMasternodeManager->Init(::ChainActive().Tip());
|
||||
}
|
||||
|
||||
g_wallet_init_interface.AutoLockMasternodeCollaterals();
|
||||
|
||||
chainman.ActiveChainstate().LoadMempool(args);
|
||||
}
|
39
src/node/blockstorage.h
Normal file
39
src/node/blockstorage.h
Normal file
@ -0,0 +1,39 @@
|
||||
// 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 CDSNotificationInterface;
|
||||
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 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, CDSNotificationInterface& dsnfi, std::vector<fs::path> vImportFiles, const ArgsManager& args);
|
||||
|
||||
#endif // BITCOIN_NODE_BLOCKSTORAGE_H
|
@ -22,6 +22,7 @@
|
||||
#include <net_processing.h>
|
||||
#include <netaddress.h>
|
||||
#include <netbase.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/coin.h>
|
||||
#include <node/context.h>
|
||||
#include <node/transaction.h>
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <llmq/chainlocks.h>
|
||||
#include <llmq/context.h>
|
||||
#include <llmq/instantsend.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/context.h>
|
||||
#include <primitives/block.h>
|
||||
#include <primitives/transaction.h>
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <index/txindex.h>
|
||||
#include <llmq/context.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/coinstats.h>
|
||||
#include <node/context.h>
|
||||
#include <node/utxo_snapshot.h>
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <evo/deterministicmns.h>
|
||||
#include <governance/classes.h>
|
||||
#include <index/txindex.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/context.h>
|
||||
#include <governance/governance.h>
|
||||
#include <masternode/node.h>
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <init.h>
|
||||
#include <key_io.h>
|
||||
#include <merkleblock.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/coin.h>
|
||||
#include <node/context.h>
|
||||
#include <node/transaction.h>
|
||||
|
@ -5,6 +5,10 @@
|
||||
|
||||
#include <shutdown.h>
|
||||
|
||||
#include <logging.h>
|
||||
#include <ui_interface.h>
|
||||
#include <warnings.h>
|
||||
|
||||
#include <config/bitcoin-config.h>
|
||||
|
||||
#include <assert.h>
|
||||
@ -17,6 +21,18 @@
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
bool AbortNode(const std::string& strMessage, bilingual_str user_message)
|
||||
{
|
||||
SetMiscWarning(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> fRequestRestart(false);
|
||||
|
||||
|
@ -6,6 +6,11 @@
|
||||
#ifndef 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(),
|
||||
* AbortShutdown() or WaitForShutdown(). Calling ShutdownRequested() is always safe.
|
||||
*/
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include <test/util/blockfilter.h>
|
||||
|
||||
#include <chainparams.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <validation.h>
|
||||
|
||||
bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter)
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <index/txindex.h>
|
||||
#include <logging.h>
|
||||
#include <logging/timer.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <node/coinstats.h>
|
||||
#include <policy/policy.h>
|
||||
#include <policy/settings.h>
|
||||
@ -1087,72 +1088,6 @@ CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMe
|
||||
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());
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
double ConvertBitsToDouble(unsigned int nBits)
|
||||
{
|
||||
int nShift = (nBits >> 24) & 0xff;
|
||||
@ -1676,19 +1611,6 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Abort with a message */
|
||||
static bool AbortNode(const std::string& strMessage, bilingual_str user_message = bilingual_str())
|
||||
{
|
||||
SetMiscWarning(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())
|
||||
{
|
||||
AbortNode(strMessage, userMessage);
|
||||
@ -3759,7 +3681,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);
|
||||
|
||||
@ -4224,25 +4147,6 @@ bool ChainstateManager::ProcessNewBlockHeaders(const std::vector<CBlockHeader>&
|
||||
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 */
|
||||
bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, BlockValidationState& state, CBlockIndex** ppindex, bool fRequested, const FlatFilePos* dbp, bool* fNewBlock)
|
||||
{
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <set>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -312,13 +313,6 @@ bool GetAddressUnspent(uint160 addressHash, int type,
|
||||
/** Initializes the script-execution cache */
|
||||
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 UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
|
||||
|
||||
/** Functions for validating blocks and updating the block tree */
|
||||
|
||||
/** Context-independent validity checks */
|
||||
@ -921,6 +915,7 @@ private:
|
||||
friend CChain& ChainActive();
|
||||
|
||||
public:
|
||||
std::thread m_load_block;
|
||||
//! A single BlockManager instance is shared across each constructed
|
||||
//! chainstate to avoid duplicating block metadata.
|
||||
BlockManager m_blockman GUARDED_BY(::cs_main);
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <chain.h>
|
||||
#include <chainparams.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <streams.h>
|
||||
#include <validation.h>
|
||||
#include <zmq/zmqutil.h>
|
||||
|
@ -11,7 +11,9 @@ export LC_ALL=C
|
||||
EXPECTED_CIRCULAR_DEPENDENCIES=(
|
||||
"chainparamsbase -> util/system -> chainparamsbase"
|
||||
"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"
|
||||
"qt/addresstablemodel -> qt/walletmodel -> qt/addresstablemodel"
|
||||
"qt/bitcoingui -> qt/walletframe -> qt/bitcoingui"
|
||||
@ -23,6 +25,7 @@ EXPECTED_CIRCULAR_DEPENDENCIES=(
|
||||
"node/coinstats -> validation -> node/coinstats"
|
||||
# Dash
|
||||
"coinjoin/server -> net_processing -> coinjoin/server"
|
||||
"dsnotificationinterface -> llmq/chainlocks -> node/blockstorage -> dsnotificationinterface"
|
||||
"evo/cbtx -> evo/simplifiedmns -> evo/cbtx"
|
||||
"evo/deterministicmns -> llmq/commitment -> evo/deterministicmns"
|
||||
"evo/deterministicmns -> llmq/utils -> evo/deterministicmns"
|
||||
|
Loading…
Reference in New Issue
Block a user