0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-10 10:52:31 -05:00

Merge bitcoin/bitcoin#27125: refactor, kernel: Decouple ArgsManager from blockstorage

5ff63a09a9 refactor, blockstorage: Replace stopafterblockimport arg (TheCharlatan)
18e5ba7c80 refactor, blockstorage: Replace blocksdir arg (TheCharlatan)
02a0899527 refactor, BlockManager: Replace fastprune from arg with options (TheCharlatan)
a498d699e3 refactor/iwyu: Complete includes for blockmanager_args (TheCharlatan)
f0bb1021f0 refactor: Move functions to BlockManager methods (TheCharlatan)
cfbb212493 zmq: Pass lambda to zmq's ZMQPublishRawBlockNotifier (TheCharlatan)
8ed4ff8e05 refactor: Declare g_zmq_notification_interface as unique_ptr (TheCharlatan)

Pull request description:

  The libbitcoin_kernel library should not rely on the `ArgsManager`, but rather use option structs that can be passed to the various classes it uses. This PR removes reliance on the `ArgsManager` from the `blockstorage.*` files. Like similar prior work, it uses the options struct in the `BlockManager` that can be populated with `ArgsManager` values.

  Some related prior work: https://github.com/bitcoin/bitcoin/pull/26889 https://github.com/bitcoin/bitcoin/pull/25862 https://github.com/bitcoin/bitcoin/pull/25527 https://github.com/bitcoin/bitcoin/pull/25487

  Related PR removing blockstorage globals: https://github.com/bitcoin/bitcoin/pull/25781

ACKs for top commit:
  ryanofsky:
    Code review ACK 5ff63a09a9. Since last ACK just added std::move and fixed commit title. Sorry for the noise!
  mzumsande:
    Code Review ACK 5ff63a09a9

Tree-SHA512: 4bde8fd140a40b97eca923e9016d85dcea6fad6fd199731f158376294af59c3e8b163a0725aa47b4be3519b61828044e0a042deea005e0c28de21d8b6c3e1ea7
This commit is contained in:
fanquake 2023-05-11 10:14:30 +01:00
commit c2f2abd0a4
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
33 changed files with 194 additions and 174 deletions

View file

@ -52,6 +52,7 @@ if [ "${RUN_TIDY}" = "true" ]; then
src/dbwrapper.cpp \ src/dbwrapper.cpp \
src/init \ src/init \
src/kernel \ src/kernel \
src/node/blockmanager_args.cpp \
src/node/chainstate.cpp \ src/node/chainstate.cpp \
src/node/chainstatemanager_args.cpp \ src/node/chainstatemanager_args.cpp \
src/node/mempool_args.cpp \ src/node/mempool_args.cpp \

View file

@ -89,6 +89,7 @@ int main(int argc, char* argv[])
}; };
const node::BlockManager::Options blockman_opts{ const node::BlockManager::Options blockman_opts{
.chainparams = chainman_opts.chainparams, .chainparams = chainman_opts.chainparams,
.blocks_dir = gArgs.GetBlocksDirPath(),
}; };
ChainstateManager chainman{chainman_opts, blockman_opts}; ChainstateManager chainman{chainman_opts, blockman_opts};

View file

@ -23,8 +23,6 @@
#include <string> #include <string>
#include <utility> #include <utility>
using node::ReadBlockFromDisk;
constexpr uint8_t DB_BEST_BLOCK{'B'}; constexpr uint8_t DB_BEST_BLOCK{'B'};
constexpr auto SYNC_LOG_INTERVAL{30s}; constexpr auto SYNC_LOG_INTERVAL{30s};
@ -159,8 +157,6 @@ void BaseIndex::ThreadSync()
SetSyscallSandboxPolicy(SyscallSandboxPolicy::TX_INDEX); SetSyscallSandboxPolicy(SyscallSandboxPolicy::TX_INDEX);
const CBlockIndex* pindex = m_best_block_index.load(); const CBlockIndex* pindex = m_best_block_index.load();
if (!m_synced) { if (!m_synced) {
auto& consensus_params = Params().GetConsensus();
std::chrono::steady_clock::time_point last_log_time{0s}; std::chrono::steady_clock::time_point last_log_time{0s};
std::chrono::steady_clock::time_point last_locator_write_time{0s}; std::chrono::steady_clock::time_point last_locator_write_time{0s};
while (true) { while (true) {
@ -207,7 +203,7 @@ void BaseIndex::ThreadSync()
CBlock block; CBlock block;
interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex); interfaces::BlockInfo block_info = kernel::MakeBlockInfo(pindex);
if (!ReadBlockFromDisk(block, pindex, consensus_params)) { if (!m_chainstate->m_blockman.ReadBlockFromDisk(block, *pindex)) {
FatalError("%s: Failed to read block %s from disk", FatalError("%s: Failed to read block %s from disk",
__func__, pindex->GetBlockHash().ToString()); __func__, pindex->GetBlockHash().ToString());
return; return;

View file

@ -12,8 +12,6 @@
#include <util/fs_helpers.h> #include <util/fs_helpers.h>
#include <validation.h> #include <validation.h>
using node::UndoReadFromDisk;
/* 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
* height, and those belonging to blocks that have been reorganized out of the active chain are * height, and those belonging to blocks that have been reorganized out of the active chain are
@ -223,7 +221,7 @@ bool BlockFilterIndex::CustomAppend(const interfaces::BlockInfo& block)
// pindex variable gives indexing code access to node internals. It // pindex variable gives indexing code access to node internals. It
// will be removed in upcoming commit // will be removed in upcoming commit
const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash)); const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash));
if (!UndoReadFromDisk(block_undo, pindex)) { if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
return false; return false;
} }

View file

@ -19,9 +19,6 @@ using kernel::CCoinsStats;
using kernel::GetBogoSize; using kernel::GetBogoSize;
using kernel::TxOutSer; using kernel::TxOutSer;
using node::ReadBlockFromDisk;
using node::UndoReadFromDisk;
static constexpr uint8_t DB_BLOCK_HASH{'s'}; static constexpr uint8_t DB_BLOCK_HASH{'s'};
static constexpr uint8_t DB_BLOCK_HEIGHT{'t'}; static constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
static constexpr uint8_t DB_MUHASH{'M'}; static constexpr uint8_t DB_MUHASH{'M'};
@ -125,7 +122,7 @@ bool CoinStatsIndex::CustomAppend(const interfaces::BlockInfo& block)
// pindex variable gives indexing code access to node internals. It // pindex variable gives indexing code access to node internals. It
// will be removed in upcoming commit // will be removed in upcoming commit
const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash)); const CBlockIndex* pindex = WITH_LOCK(cs_main, return m_chainstate->m_blockman.LookupBlockIndex(block.hash));
if (!UndoReadFromDisk(block_undo, pindex)) { if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
return false; return false;
} }
@ -282,12 +279,11 @@ bool CoinStatsIndex::CustomRewind(const interfaces::BlockKey& current_tip, const
LOCK(cs_main); LOCK(cs_main);
const CBlockIndex* iter_tip{m_chainstate->m_blockman.LookupBlockIndex(current_tip.hash)}; const CBlockIndex* iter_tip{m_chainstate->m_blockman.LookupBlockIndex(current_tip.hash)};
const CBlockIndex* new_tip_index{m_chainstate->m_blockman.LookupBlockIndex(new_tip.hash)}; const CBlockIndex* new_tip_index{m_chainstate->m_blockman.LookupBlockIndex(new_tip.hash)};
const auto& consensus_params{Params().GetConsensus()};
do { do {
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, iter_tip, consensus_params)) { if (!m_chainstate->m_blockman.ReadBlockFromDisk(block, *iter_tip)) {
return error("%s: Failed to read block %s from disk", return error("%s: Failed to read block %s from disk",
__func__, iter_tip->GetBlockHash().ToString()); __func__, iter_tip->GetBlockHash().ToString());
} }
@ -409,7 +405,7 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
// Ignore genesis block // Ignore genesis block
if (pindex->nHeight > 0) { if (pindex->nHeight > 0) {
if (!UndoReadFromDisk(block_undo, pindex)) { if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
return false; return false;
} }

View file

@ -10,8 +10,6 @@
#include <node/blockstorage.h> #include <node/blockstorage.h>
#include <validation.h> #include <validation.h>
using node::OpenBlockFile;
constexpr uint8_t DB_TXINDEX{'t'}; constexpr uint8_t DB_TXINDEX{'t'};
std::unique_ptr<TxIndex> g_txindex; std::unique_ptr<TxIndex> g_txindex;
@ -80,7 +78,7 @@ bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRe
return false; return false;
} }
CAutoFile file(OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION); CAutoFile file(m_chainstate->m_blockman.OpenBlockFile(postx, true), SER_DISK, CLIENT_VERSION);
if (file.IsNull()) { if (file.IsNull()) {
return error("%s: OpenBlockFile failed", __func__); return error("%s: OpenBlockFile failed", __func__);
} }

View file

@ -112,22 +112,23 @@
#include <zmq/zmqrpc.h> #include <zmq/zmqrpc.h>
#endif #endif
using kernel::DEFAULT_STOPAFTERBLOCKIMPORT;
using kernel::DumpMempool; using kernel::DumpMempool;
using kernel::ValidationCacheSizes; using kernel::ValidationCacheSizes;
using node::ApplyArgsManOptions; using node::ApplyArgsManOptions;
using node::BlockManager;
using node::CacheSizes; using node::CacheSizes;
using node::CalculateCacheSizes; using node::CalculateCacheSizes;
using node::DEFAULT_PERSIST_MEMPOOL; using node::DEFAULT_PERSIST_MEMPOOL;
using node::DEFAULT_PRINTPRIORITY; using node::DEFAULT_PRINTPRIORITY;
using node::DEFAULT_STOPAFTERBLOCKIMPORT; using node::fReindex;
using node::LoadChainstate; using node::LoadChainstate;
using node::MempoolPath; using node::MempoolPath;
using node::ShouldPersistMempool;
using node::NodeContext; using node::NodeContext;
using node::ShouldPersistMempool;
using node::ThreadImport; using node::ThreadImport;
using node::VerifyLoadedChainstate; using node::VerifyLoadedChainstate;
using node::fReindex;
static constexpr bool DEFAULT_PROXYRANDOMIZE{true}; static constexpr bool DEFAULT_PROXYRANDOMIZE{true};
static constexpr bool DEFAULT_REST_ENABLE{false}; static constexpr bool DEFAULT_REST_ENABLE{false};
@ -328,9 +329,8 @@ void Shutdown(NodeContext& node)
#if ENABLE_ZMQ #if ENABLE_ZMQ
if (g_zmq_notification_interface) { if (g_zmq_notification_interface) {
UnregisterValidationInterface(g_zmq_notification_interface); UnregisterValidationInterface(g_zmq_notification_interface.get());
delete g_zmq_notification_interface; g_zmq_notification_interface.reset();
g_zmq_notification_interface = nullptr;
} }
#endif #endif
@ -1038,8 +1038,9 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb
if (const auto error{ApplyArgsManOptions(args, chainman_opts_dummy)}) { if (const auto error{ApplyArgsManOptions(args, chainman_opts_dummy)}) {
return InitError(*error); return InitError(*error);
} }
node::BlockManager::Options blockman_opts_dummy{ BlockManager::Options blockman_opts_dummy{
.chainparams = chainman_opts_dummy.chainparams, .chainparams = chainman_opts_dummy.chainparams,
.blocks_dir = args.GetBlocksDirPath(),
}; };
if (const auto error{ApplyArgsManOptions(args, blockman_opts_dummy)}) { if (const auto error{ApplyArgsManOptions(args, blockman_opts_dummy)}) {
return InitError(*error); return InitError(*error);
@ -1425,10 +1426,14 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} }
#if ENABLE_ZMQ #if ENABLE_ZMQ
g_zmq_notification_interface = CZMQNotificationInterface::Create(); g_zmq_notification_interface = CZMQNotificationInterface::Create(
[&chainman = node.chainman](CBlock& block, const CBlockIndex& index) {
assert(chainman);
return chainman->m_blockman.ReadBlockFromDisk(block, index);
});
if (g_zmq_notification_interface) { if (g_zmq_notification_interface) {
RegisterValidationInterface(g_zmq_notification_interface); RegisterValidationInterface(g_zmq_notification_interface.get());
} }
#endif #endif
@ -1443,8 +1448,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
}; };
Assert(!ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction Assert(!ApplyArgsManOptions(args, chainman_opts)); // no error can happen, already checked in AppInitParameterInteraction
node::BlockManager::Options blockman_opts{ BlockManager::Options blockman_opts{
.chainparams = chainman_opts.chainparams, .chainparams = chainman_opts.chainparams,
.blocks_dir = args.GetBlocksDirPath(),
}; };
Assert(!ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction Assert(!ApplyArgsManOptions(args, blockman_opts)); // no error can happen, already checked in AppInitParameterInteraction
@ -1674,7 +1680,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
} }
chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &chainman, &args] { chainman.m_load_block = std::thread(&util::TraceThread, "loadblk", [=, &chainman, &args] {
ThreadImport(chainman, vImportFiles, args, ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{}); ThreadImport(chainman, vImportFiles, ShouldPersistMempool(args) ? MempoolPath(args) : fs::path{});
}); });
// Wait for genesis block to be processed // Wait for genesis block to be processed

View file

@ -5,10 +5,16 @@
#ifndef BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H #ifndef BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H
#define BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H #define BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H
#include <util/fs.h>
#include <cstdint>
class CChainParams; class CChainParams;
namespace kernel { namespace kernel {
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
/** /**
* An options struct for `BlockManager`, more ergonomically referred to as * An options struct for `BlockManager`, more ergonomically referred to as
* `BlockManager::Options` due to the using-declaration in `BlockManager`. * `BlockManager::Options` due to the using-declaration in `BlockManager`.
@ -16,6 +22,9 @@ namespace kernel {
struct BlockManagerOpts { struct BlockManagerOpts {
const CChainParams& chainparams; const CChainParams& chainparams;
uint64_t prune_target{0}; uint64_t prune_target{0};
bool fast_prune{false};
bool stop_after_block_import{DEFAULT_STOPAFTERBLOCKIMPORT};
const fs::path blocks_dir;
}; };
} // namespace kernel } // namespace kernel

View file

@ -51,9 +51,6 @@
#include <optional> #include <optional>
#include <typeinfo> #include <typeinfo>
using node::ReadBlockFromDisk;
using node::ReadRawBlockFromDisk;
/** How long to cache transactions in mapRelay for normal relay */ /** How long to cache transactions in mapRelay for normal relay */
static constexpr auto RELAY_TX_CACHE_TIME = 15min; static constexpr auto RELAY_TX_CACHE_TIME = 15min;
/** How long a transaction has to be in the mempool before it can unconditionally be relayed (even when not in mapRelay). */ /** How long a transaction has to be in the mempool before it can unconditionally be relayed (even when not in mapRelay). */
@ -2189,7 +2186,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
// Fast-path: in this case it is possible to serve the block directly from disk, // Fast-path: in this case it is possible to serve the block directly from disk,
// as the network format matches the format on disk // as the network format matches the format on disk
std::vector<uint8_t> block_data; std::vector<uint8_t> block_data;
if (!ReadRawBlockFromDisk(block_data, pindex->GetBlockPos(), m_chainparams.MessageStart())) { if (!m_chainman.m_blockman.ReadRawBlockFromDisk(block_data, pindex->GetBlockPos(), m_chainparams.MessageStart())) {
assert(!"cannot load block from disk"); assert(!"cannot load block from disk");
} }
m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCK, Span{block_data})); m_connman.PushMessage(&pfrom, msgMaker.Make(NetMsgType::BLOCK, Span{block_data}));
@ -2197,7 +2194,7 @@ void PeerManagerImpl::ProcessGetBlockData(CNode& pfrom, Peer& peer, const CInv&
} else { } else {
// Send block from disk // Send block from disk
std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblockRead = std::make_shared<CBlock>();
if (!ReadBlockFromDisk(*pblockRead, pindex, m_chainparams.GetConsensus())) { if (!m_chainman.m_blockman.ReadBlockFromDisk(*pblockRead, *pindex)) {
assert(!"cannot load block from disk"); assert(!"cannot load block from disk");
} }
pblock = pblockRead; pblock = pblockRead;
@ -3889,7 +3886,7 @@ void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
if (pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_BLOCKTXN_DEPTH) { if (pindex->nHeight >= m_chainman.ActiveChain().Height() - MAX_BLOCKTXN_DEPTH) {
CBlock block; CBlock block;
bool ret = ReadBlockFromDisk(block, pindex, m_chainparams.GetConsensus()); const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pindex)};
assert(ret); assert(ret);
SendBlockTransactions(pfrom, *peer, block, req); SendBlockTransactions(pfrom, *peer, block, req);
@ -5546,7 +5543,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
m_connman.PushMessage(pto, std::move(cached_cmpctblock_msg.value())); m_connman.PushMessage(pto, std::move(cached_cmpctblock_msg.value()));
} else { } else {
CBlock block; CBlock block;
bool ret = ReadBlockFromDisk(block, pBestIndex, consensusParams); const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pBestIndex)};
assert(ret); assert(ret);
CBlockHeaderAndShortTxIDs cmpctblock{block}; CBlockHeaderAndShortTxIDs cmpctblock{block};
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock)); m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::CMPCTBLOCK, cmpctblock));

View file

@ -5,8 +5,14 @@
#include <node/blockmanager_args.h> #include <node/blockmanager_args.h>
#include <common/args.h> #include <common/args.h>
#include <node/blockstorage.h>
#include <tinyformat.h>
#include <util/translation.h>
#include <validation.h> #include <validation.h>
#include <cstdint>
#include <optional>
namespace node { namespace node {
std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Options& opts) std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, BlockManager::Options& opts)
{ {
@ -25,6 +31,9 @@ std::optional<bilingual_str> ApplyArgsManOptions(const ArgsManager& args, BlockM
} }
opts.prune_target = nPruneTarget; opts.prune_target = nPruneTarget;
if (auto value{args.GetBoolArg("-fastprune")}) opts.fast_prune = *value;
if (auto value{args.GetBoolArg("-stopafterblockimport")}) opts.stop_after_block_import = *value;
return std::nullopt; return std::nullopt;
} }
} // namespace node } // namespace node

View file

@ -6,7 +6,6 @@
#include <chain.h> #include <chain.h>
#include <clientversion.h> #include <clientversion.h>
#include <common/args.h>
#include <consensus/validation.h> #include <consensus/validation.h>
#include <flatfile.h> #include <flatfile.h>
#include <hash.h> #include <hash.h>
@ -53,10 +52,6 @@ bool CBlockIndexHeightOnlyComparator::operator()(const CBlockIndex* pa, const CB
return pa->nHeight < pb->nHeight; 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() std::vector<CBlockIndex*> BlockManager::GetAllBlockIndices()
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
@ -423,7 +418,7 @@ const CBlockIndex* BlockManager::GetFirstStoredBlock(const CBlockIndex& start_bl
// rev files since they'll be rewritten by the reindex anyway. This ensures that m_blockfile_info // rev files since they'll be rewritten by the reindex anyway. This ensures that m_blockfile_info
// is in sync with what's actually on disk by the time we start downloading, so that pruning // is in sync with what's actually on disk by the time we start downloading, so that pruning
// works correctly. // works correctly.
void CleanupBlockRevFiles() void BlockManager::CleanupBlockRevFiles() const
{ {
std::map<std::string, fs::path> mapBlockFiles; std::map<std::string, fs::path> mapBlockFiles;
@ -431,8 +426,7 @@ void CleanupBlockRevFiles()
// Remove the rev files immediately and insert the blk file paths into an // Remove the rev files immediately and insert the blk file paths into an
// ordered map keyed by block file index. // ordered map keyed by block file index.
LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n"); LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
const fs::path& blocksdir = gArgs.GetBlocksDirPath(); for (fs::directory_iterator it(m_opts.blocks_dir); it != fs::directory_iterator(); it++) {
for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
const std::string path = fs::PathToString(it->path().filename()); const std::string path = fs::PathToString(it->path().filename());
if (fs::is_regular_file(*it) && if (fs::is_regular_file(*it) &&
path.length() == 12 && path.length() == 12 &&
@ -467,7 +461,7 @@ CBlockFileInfo* BlockManager::GetBlockFileInfo(size_t n)
return &m_blockfile_info.at(n); return &m_blockfile_info.at(n);
} }
static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) bool BlockManager::UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) const
{ {
// Open history file to append // Open history file to append
AutoFile fileout{OpenUndoFile(pos)}; AutoFile fileout{OpenUndoFile(pos)};
@ -496,9 +490,9 @@ static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const
return true; return true;
} }
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex) bool BlockManager::UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex& index) const
{ {
const FlatFilePos pos{WITH_LOCK(::cs_main, return pindex->GetUndoPos())}; const FlatFilePos pos{WITH_LOCK(::cs_main, return index.GetUndoPos())};
if (pos.IsNull()) { if (pos.IsNull()) {
return error("%s: no undo data available", __func__); return error("%s: no undo data available", __func__);
@ -514,7 +508,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
uint256 hashChecksum; uint256 hashChecksum;
HashVerifier verifier{filein}; // Use HashVerifier as reserializing may lose data, c.f. commit d342424301013ec47dc146a4beb49d5c9319d80a HashVerifier verifier{filein}; // Use HashVerifier as reserializing may lose data, c.f. commit d342424301013ec47dc146a4beb49d5c9319d80a
try { try {
verifier << pindex->pprev->GetBlockHash(); verifier << index.pprev->GetBlockHash();
verifier >> blockundo; verifier >> blockundo;
filein >> hashChecksum; filein >> hashChecksum;
} catch (const std::exception& e) { } catch (const std::exception& e) {
@ -570,7 +564,7 @@ uint64_t BlockManager::CalculateCurrentUsage()
return retval; return retval;
} }
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) void BlockManager::UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const
{ {
std::error_code ec; std::error_code ec;
for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) { for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
@ -583,28 +577,28 @@ void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune)
} }
} }
static FlatFileSeq BlockFileSeq() FlatFileSeq BlockManager::BlockFileSeq() const
{ {
return FlatFileSeq(gArgs.GetBlocksDirPath(), "blk", gArgs.GetBoolArg("-fastprune", false) ? 0x4000 /* 16kb */ : BLOCKFILE_CHUNK_SIZE); return FlatFileSeq(m_opts.blocks_dir, "blk", m_opts.fast_prune ? 0x4000 /* 16kb */ : BLOCKFILE_CHUNK_SIZE);
} }
static FlatFileSeq UndoFileSeq() FlatFileSeq BlockManager::UndoFileSeq() const
{ {
return FlatFileSeq(gArgs.GetBlocksDirPath(), "rev", UNDOFILE_CHUNK_SIZE); return FlatFileSeq(m_opts.blocks_dir, "rev", UNDOFILE_CHUNK_SIZE);
} }
FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly) FILE* BlockManager::OpenBlockFile(const FlatFilePos& pos, bool fReadOnly) const
{ {
return BlockFileSeq().Open(pos, fReadOnly); return BlockFileSeq().Open(pos, fReadOnly);
} }
/** Open an undo file (rev?????.dat) */ /** Open an undo file (rev?????.dat) */
static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly) FILE* BlockManager::OpenUndoFile(const FlatFilePos& pos, bool fReadOnly) const
{ {
return UndoFileSeq().Open(pos, fReadOnly); return UndoFileSeq().Open(pos, fReadOnly);
} }
fs::path GetBlockPosFilename(const FlatFilePos& pos) fs::path BlockManager::GetBlockPosFilename(const FlatFilePos& pos) const
{ {
return BlockFileSeq().FileName(pos); return BlockFileSeq().FileName(pos);
} }
@ -623,7 +617,7 @@ bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigne
unsigned int max_blockfile_size{MAX_BLOCKFILE_SIZE}; unsigned int max_blockfile_size{MAX_BLOCKFILE_SIZE};
// Use smaller blockfiles in test-only -fastprune mode - but avoid // Use smaller blockfiles in test-only -fastprune mode - but avoid
// the possibility of having a block not fit into the block file. // the possibility of having a block not fit into the block file.
if (gArgs.GetBoolArg("-fastprune", false)) { if (m_opts.fast_prune) {
max_blockfile_size = 0x10000; // 64kiB max_blockfile_size = 0x10000; // 64kiB
if (nAddSize >= max_blockfile_size) { if (nAddSize >= max_blockfile_size) {
// dynamically adjust the blockfile size to be larger than the added size // dynamically adjust the blockfile size to be larger than the added size
@ -697,7 +691,7 @@ bool BlockManager::FindUndoPos(BlockValidationState& state, int nFile, FlatFileP
return true; return true;
} }
static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart) bool BlockManager::WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart) const
{ {
// Open history file to append // Open history file to append
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION); CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
@ -750,7 +744,7 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid
return true; return true;
} }
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams) bool BlockManager::ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const
{ {
block.SetNull(); block.SetNull();
@ -768,33 +762,33 @@ bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::P
} }
// Check the header // Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) { if (!CheckProofOfWork(block.GetHash(), block.nBits, GetConsensus())) {
return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString()); return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
} }
// Signet only: check block solution // Signet only: check block solution
if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) { if (GetConsensus().signet_blocks && !CheckSignetBlockSolution(block, GetConsensus())) {
return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString()); return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
} }
return true; return true;
} }
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams) bool BlockManager::ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const
{ {
const FlatFilePos block_pos{WITH_LOCK(cs_main, return pindex->GetBlockPos())}; const FlatFilePos block_pos{WITH_LOCK(cs_main, return index.GetBlockPos())};
if (!ReadBlockFromDisk(block, block_pos, consensusParams)) { if (!ReadBlockFromDisk(block, block_pos)) {
return false; return false;
} }
if (block.GetHash() != pindex->GetBlockHash()) { if (block.GetHash() != index.GetBlockHash()) {
return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s", return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
pindex->ToString(), block_pos.ToString()); index.ToString(), block_pos.ToString());
} }
return true; return true;
} }
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start) bool BlockManager::ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start) const
{ {
FlatFilePos hpos = pos; FlatFilePos hpos = pos;
hpos.nPos -= 8; // Seek back 8 bytes for meta header hpos.nPos -= 8; // Seek back 8 bytes for meta header
@ -872,7 +866,7 @@ public:
} }
}; };
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args, const fs::path& mempool_path) void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const fs::path& mempool_path)
{ {
SetSyscallSandboxPolicy(SyscallSandboxPolicy::INITIALIZATION_LOAD_BLOCKS); SetSyscallSandboxPolicy(SyscallSandboxPolicy::INITIALIZATION_LOAD_BLOCKS);
ScheduleBatchPriority(); ScheduleBatchPriority();
@ -888,10 +882,10 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent; std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
while (true) { while (true) {
FlatFilePos pos(nFile, 0); FlatFilePos pos(nFile, 0);
if (!fs::exists(GetBlockPosFilename(pos))) { if (!fs::exists(chainman.m_blockman.GetBlockPosFilename(pos))) {
break; // No block files left to reindex break; // No block files left to reindex
} }
FILE* file = OpenBlockFile(pos, true); FILE* file = chainman.m_blockman.OpenBlockFile(pos, true);
if (!file) { if (!file) {
break; // This error is logged in OpenBlockFile break; // This error is logged in OpenBlockFile
} }
@ -939,7 +933,7 @@ void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFile
} }
} }
if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) { if (chainman.m_blockman.StopAfterBlockImport()) {
LogPrintf("Stopping after block import\n"); LogPrintf("Stopping after block import\n");
StartShutdown(); StartShutdown();
return; return;

View file

@ -20,7 +20,6 @@
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
class ArgsManager;
class BlockValidationState; class BlockValidationState;
class CBlock; class CBlock;
class CBlockFileInfo; class CBlockFileInfo;
@ -36,7 +35,6 @@ struct Params;
} }
namespace node { namespace node {
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
/** The pre-allocation chunk size for blk?????.dat files (since 0.8) */ /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
@ -96,6 +94,14 @@ private:
bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown); bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown);
bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize); bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize);
FlatFileSeq BlockFileSeq() const;
FlatFileSeq UndoFileSeq() const;
FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false) const;
bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart) const;
bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) const;
/* Calculate the block/rev files to delete based on height specified by user with RPC command pruneblockchain */ /* Calculate the block/rev files to delete based on height specified by user with RPC command pruneblockchain */
void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height); void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height);
@ -202,6 +208,8 @@ public:
[[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; } [[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; }
[[nodiscard]] bool StopAfterBlockImport() const { return m_opts.stop_after_block_import; }
/** Calculate the amount of disk space the block & undo files currently use */ /** Calculate the amount of disk space the block & undo files currently use */
uint64_t CalculateCurrentUsage(); uint64_t CalculateCurrentUsage();
@ -219,28 +227,29 @@ public:
//! Create or update a prune lock identified by its name //! Create or update a prune lock identified by its name
void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
};
void CleanupBlockRevFiles();
/** Open a block file (blk?????.dat) */ /** Open a block file (blk?????.dat) */
FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false); FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false) const;
/** Translation to a filesystem path */ /** Translation to a filesystem path */
fs::path GetBlockPosFilename(const FlatFilePos& pos); fs::path GetBlockPosFilename(const FlatFilePos& pos) const;
/** /**
* Actually unlink the specified files * Actually unlink the specified files
*/ */
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune); void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const;
/** Functions for disk access for blocks */ /** Functions for disk access for blocks */
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams); bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const;
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const;
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start); bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start) const;
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex); bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex& index) const;
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args, const fs::path& mempool_path); void CleanupBlockRevFiles() const;
};
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const fs::path& mempool_path);
} // namespace node } // namespace node
#endif // BITCOIN_NODE_BLOCKSTORAGE_H #endif // BITCOIN_NODE_BLOCKSTORAGE_H

View file

@ -51,7 +51,7 @@ static ChainstateLoadResult CompleteChainstateInitialization(
pblocktree->WriteReindexing(true); pblocktree->WriteReindexing(true);
//If we're reindexing in prune mode, wipe away unusable block files and all undo data files //If we're reindexing in prune mode, wipe away unusable block files and all undo data files
if (options.prune) { if (options.prune) {
CleanupBlockRevFiles(); chainman.m_blockman.CleanupBlockRevFiles();
} }
} }

View file

@ -394,7 +394,7 @@ public:
NodeContext* m_context{nullptr}; NodeContext* m_context{nullptr};
}; };
bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active) bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<RecursiveMutex>& lock, const CChain& active, const BlockManager& blockman)
{ {
if (!index) return false; if (!index) return false;
if (block.m_hash) *block.m_hash = index->GetBlockHash(); if (block.m_hash) *block.m_hash = index->GetBlockHash();
@ -404,10 +404,10 @@ bool FillBlock(const CBlockIndex* index, const FoundBlock& block, UniqueLock<Rec
if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast(); if (block.m_mtp_time) *block.m_mtp_time = index->GetMedianTimePast();
if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index; if (block.m_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == index;
if (block.m_locator) { *block.m_locator = GetLocator(index); } if (block.m_locator) { *block.m_locator = GetLocator(index); }
if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active); if (block.m_next_block) FillBlock(active[index->nHeight] == index ? active[index->nHeight + 1] : nullptr, *block.m_next_block, lock, active, blockman);
if (block.m_data) { if (block.m_data) {
REVERSE_LOCK(lock); REVERSE_LOCK(lock);
if (!ReadBlockFromDisk(*block.m_data, index, Params().GetConsensus())) block.m_data->SetNull(); if (!blockman.ReadBlockFromDisk(*block.m_data, *index)) block.m_data->SetNull();
} }
block.found = true; block.found = true;
return true; return true;
@ -557,13 +557,13 @@ public:
bool findBlock(const uint256& hash, const FoundBlock& block) override bool findBlock(const uint256& hash, const FoundBlock& block) override
{ {
WAIT_LOCK(cs_main, lock); WAIT_LOCK(cs_main, lock);
return FillBlock(chainman().m_blockman.LookupBlockIndex(hash), block, lock, chainman().ActiveChain()); return FillBlock(chainman().m_blockman.LookupBlockIndex(hash), block, lock, chainman().ActiveChain(), chainman().m_blockman);
} }
bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override bool findFirstBlockWithTimeAndHeight(int64_t min_time, int min_height, const FoundBlock& block) override
{ {
WAIT_LOCK(cs_main, lock); WAIT_LOCK(cs_main, lock);
const CChain& active = chainman().ActiveChain(); const CChain& active = chainman().ActiveChain();
return FillBlock(active.FindEarliestAtLeast(min_time, min_height), block, lock, active); return FillBlock(active.FindEarliestAtLeast(min_time, min_height), block, lock, active, chainman().m_blockman);
} }
bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override bool findAncestorByHeight(const uint256& block_hash, int ancestor_height, const FoundBlock& ancestor_out) override
{ {
@ -571,10 +571,10 @@ public:
const CChain& active = chainman().ActiveChain(); const CChain& active = chainman().ActiveChain();
if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) { if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) { if (const CBlockIndex* ancestor = block->GetAncestor(ancestor_height)) {
return FillBlock(ancestor, ancestor_out, lock, active); return FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman);
} }
} }
return FillBlock(nullptr, ancestor_out, lock, active); return FillBlock(nullptr, ancestor_out, lock, active, chainman().m_blockman);
} }
bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override bool findAncestorByHash(const uint256& block_hash, const uint256& ancestor_hash, const FoundBlock& ancestor_out) override
{ {
@ -582,7 +582,7 @@ public:
const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash); const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash);
const CBlockIndex* ancestor = chainman().m_blockman.LookupBlockIndex(ancestor_hash); const CBlockIndex* ancestor = chainman().m_blockman.LookupBlockIndex(ancestor_hash);
if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr; if (block && ancestor && block->GetAncestor(ancestor->nHeight) != ancestor) ancestor = nullptr;
return FillBlock(ancestor, ancestor_out, lock, chainman().ActiveChain()); return FillBlock(ancestor, ancestor_out, lock, chainman().ActiveChain(), chainman().m_blockman);
} }
bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override bool findCommonAncestor(const uint256& block_hash1, const uint256& block_hash2, const FoundBlock& ancestor_out, const FoundBlock& block1_out, const FoundBlock& block2_out) override
{ {
@ -594,9 +594,9 @@ public:
// Using & instead of && below to avoid short circuiting and leaving // Using & instead of && below to avoid short circuiting and leaving
// output uninitialized. Cast bool to int to avoid -Wbitwise-instead-of-logical // output uninitialized. Cast bool to int to avoid -Wbitwise-instead-of-logical
// compiler warnings. // compiler warnings.
return int{FillBlock(ancestor, ancestor_out, lock, active)} & return int{FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman)} &
int{FillBlock(block1, block1_out, lock, active)} & int{FillBlock(block1, block1_out, lock, active, chainman().m_blockman)} &
int{FillBlock(block2, block2_out, lock, active)}; int{FillBlock(block2, block2_out, lock, active, chainman().m_blockman)};
} }
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); } void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
double guessVerificationProgress(const uint256& block_hash) override double guessVerificationProgress(const uint256& block_hash) override

View file

@ -122,7 +122,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
return TransactionError::OK; return TransactionError::OK;
} }
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock) CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, uint256& hashBlock, const BlockManager& blockman)
{ {
if (mempool && !block_index) { if (mempool && !block_index) {
CTransactionRef ptx = mempool->get(hash); CTransactionRef ptx = mempool->get(hash);
@ -143,7 +143,7 @@ CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMe
} }
if (block_index) { if (block_index) {
CBlock block; CBlock block;
if (ReadBlockFromDisk(block, block_index, consensusParams)) { if (blockman.ReadBlockFromDisk(block, *block_index)) {
for (const auto& tx : block.vtx) { for (const auto& tx : block.vtx) {
if (tx->GetHash() == hash) { if (tx->GetHash() == hash) {
hashBlock = block_index->GetBlockHash(); hashBlock = block_index->GetBlockHash();

View file

@ -16,6 +16,7 @@ struct Params;
} }
namespace node { namespace node {
class BlockManager;
struct NodeContext; struct NodeContext;
/** Maximum fee rate for sendrawtransaction and testmempoolaccept RPC calls. /** Maximum fee rate for sendrawtransaction and testmempoolaccept RPC calls.
@ -53,11 +54,10 @@ static const CFeeRate DEFAULT_MAX_RAW_TX_FEE_RATE{COIN / 10};
* @param[in] block_index The block to read from disk, or nullptr * @param[in] block_index The block to read from disk, or nullptr
* @param[in] mempool If provided, check mempool for tx * @param[in] mempool If provided, check mempool for tx
* @param[in] hash The txid * @param[in] hash The txid
* @param[in] consensusParams The params
* @param[out] hashBlock The block hash, if the tx was found via -txindex or block_index * @param[out] hashBlock The block hash, if the tx was found via -txindex or block_index
* @returns The tx if found, otherwise nullptr * @returns The tx if found, otherwise nullptr
*/ */
CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, const Consensus::Params& consensusParams, uint256& hashBlock); CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMemPool* const mempool, const uint256& hash, uint256& hashBlock, const BlockManager& blockman);
} // namespace node } // namespace node
#endif // BITCOIN_NODE_TRANSACTION_H #endif // BITCOIN_NODE_TRANSACTION_H

View file

@ -36,7 +36,6 @@
using node::GetTransaction; using node::GetTransaction;
using node::NodeContext; using node::NodeContext;
using node::ReadBlockFromDisk;
static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
static constexpr unsigned int MAX_REST_HEADERS_RESULTS = 2000; static constexpr unsigned int MAX_REST_HEADERS_RESULTS = 2000;
@ -311,7 +310,7 @@ static bool rest_block(const std::any& context,
} }
if (!ReadBlockFromDisk(block, pblockindex, chainman.GetParams().GetConsensus())) { if (!chainman.m_blockman.ReadBlockFromDisk(block, *pblockindex)) {
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
} }
@ -716,7 +715,7 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string
const NodeContext* const node = GetNodeContext(context, req); const NodeContext* const node = GetNodeContext(context, req);
if (!node) return false; if (!node) return false;
uint256 hashBlock = uint256(); uint256 hashBlock = uint256();
const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, node->mempool.get(), hash, Params().GetConsensus(), hashBlock); const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, node->mempool.get(), hash, hashBlock, node->chainman->m_blockman);
if (!tx) { if (!tx) {
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found"); return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
} }

View file

@ -58,9 +58,7 @@ using kernel::CoinStatsHashType;
using node::BlockManager; using node::BlockManager;
using node::NodeContext; using node::NodeContext;
using node::ReadBlockFromDisk;
using node::SnapshotMetadata; using node::SnapshotMetadata;
using node::UndoReadFromDisk;
struct CUpdatedBlock struct CUpdatedBlock
{ {
@ -183,7 +181,7 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT: case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
CBlockUndo blockUndo; CBlockUndo blockUndo;
const bool is_not_pruned{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex))}; const bool is_not_pruned{WITH_LOCK(::cs_main, return !blockman.IsBlockPruned(blockindex))};
const bool have_undo{is_not_pruned && UndoReadFromDisk(blockUndo, blockindex)}; const bool have_undo{is_not_pruned && blockman.UndoReadFromDisk(blockUndo, *blockindex)};
for (size_t i = 0; i < block.vtx.size(); ++i) { for (size_t i = 0; i < block.vtx.size(); ++i) {
const CTransactionRef& tx = block.vtx.at(i); const CTransactionRef& tx = block.vtx.at(i);
@ -587,7 +585,7 @@ static CBlock GetBlockChecked(BlockManager& blockman, const CBlockIndex* pblocki
} }
} }
if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { if (!blockman.ReadBlockFromDisk(block, *pblockindex)) {
// Block not found on disk. This could be because we have the block // Block not found on disk. This could be because we have the block
// header in our index but not yet have the block or did not accept the // header in our index but not yet have the block or did not accept the
// block. Or if the block was pruned right after we released the lock above. // block. Or if the block was pruned right after we released the lock above.
@ -611,7 +609,7 @@ static CBlockUndo GetUndoChecked(BlockManager& blockman, const CBlockIndex* pblo
} }
} }
if (!UndoReadFromDisk(blockUndo, pblockindex)) { if (!blockman.UndoReadFromDisk(blockUndo, *pblockindex)) {
throw JSONRPCError(RPC_MISC_ERROR, "Can't read undo data from disk"); throw JSONRPCError(RPC_MISC_ERROR, "Can't read undo data from disk");
} }

View file

@ -51,8 +51,6 @@ using node::FindCoins;
using node::GetTransaction; using node::GetTransaction;
using node::NodeContext; using node::NodeContext;
using node::PSBTAnalysis; using node::PSBTAnalysis;
using node::ReadBlockFromDisk;
using node::UndoReadFromDisk;
static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry, static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry,
Chainstate& active_chainstate, const CTxUndo* txundo = nullptr, Chainstate& active_chainstate, const CTxUndo* txundo = nullptr,
@ -362,7 +360,7 @@ static RPCHelpMan getrawtransaction()
} }
uint256 hash_block; uint256 hash_block;
const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, chainman.GetConsensus(), hash_block); const CTransactionRef tx = GetTransaction(blockindex, node.mempool.get(), hash, hash_block, chainman.m_blockman);
if (!tx) { if (!tx) {
std::string errmsg; std::string errmsg;
if (blockindex) { if (blockindex) {
@ -406,7 +404,7 @@ static RPCHelpMan getrawtransaction()
if (tx->IsCoinBase() || if (tx->IsCoinBase() ||
!blockindex || is_block_pruned || !blockindex || is_block_pruned ||
!(UndoReadFromDisk(blockUndo, blockindex) && ReadBlockFromDisk(block, blockindex, Params().GetConsensus()))) { !(chainman.m_blockman.UndoReadFromDisk(blockUndo, *blockindex) && chainman.m_blockman.ReadBlockFromDisk(block, *blockindex))) {
TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate()); TxToJSON(*tx, hash_block, result, chainman.ActiveChainstate());
return result; return result;
} }

View file

@ -18,7 +18,6 @@
#include <validation.h> #include <validation.h>
using node::GetTransaction; using node::GetTransaction;
using node::ReadBlockFromDisk;
static RPCHelpMan gettxoutproof() static RPCHelpMan gettxoutproof()
{ {
@ -85,7 +84,7 @@ static RPCHelpMan gettxoutproof()
} }
if (pblockindex == nullptr) { if (pblockindex == nullptr) {
const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, /*mempool=*/nullptr, *setTxids.begin(), chainman.GetConsensus(), hashBlock); const CTransactionRef tx = GetTransaction(/*block_index=*/nullptr, /*mempool=*/nullptr, *setTxids.begin(), hashBlock, chainman.m_blockman);
if (!tx || hashBlock.IsNull()) { if (!tx || hashBlock.IsNull()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
} }
@ -98,7 +97,7 @@ static RPCHelpMan gettxoutproof()
} }
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pblockindex, chainman.GetConsensus())) { if (!chainman.m_blockman.ReadBlockFromDisk(block, *pblockindex)) {
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk"); throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
} }

View file

@ -19,6 +19,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using node::BlockAssembler; using node::BlockAssembler;
using node::BlockManager;
using node::CBlockTemplate; using node::CBlockTemplate;
BOOST_AUTO_TEST_SUITE(blockfilter_index_tests) BOOST_AUTO_TEST_SUITE(blockfilter_index_tests)
@ -29,10 +30,10 @@ struct BuildChainTestingSetup : public TestChain100Setup {
}; };
static bool CheckFilterLookups(BlockFilterIndex& filter_index, const CBlockIndex* block_index, static bool CheckFilterLookups(BlockFilterIndex& filter_index, const CBlockIndex* block_index,
uint256& last_header) uint256& last_header, const BlockManager& blockman)
{ {
BlockFilter expected_filter; BlockFilter expected_filter;
if (!ComputeFilter(filter_index.GetFilterType(), block_index, expected_filter)) { if (!ComputeFilter(filter_index.GetFilterType(), *block_index, expected_filter, blockman)) {
BOOST_ERROR("ComputeFilter failed on block " << block_index->nHeight); BOOST_ERROR("ComputeFilter failed on block " << block_index->nHeight);
return false; return false;
} }
@ -155,7 +156,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
for (block_index = m_node.chainman->ActiveChain().Genesis(); for (block_index = m_node.chainman->ActiveChain().Genesis();
block_index != nullptr; block_index != nullptr;
block_index = m_node.chainman->ActiveChain().Next(block_index)) { block_index = m_node.chainman->ActiveChain().Next(block_index)) {
CheckFilterLookups(filter_index, block_index, last_header); CheckFilterLookups(filter_index, block_index, last_header, m_node.chainman->m_blockman);
} }
} }
@ -189,7 +190,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainA_last_header); CheckFilterLookups(filter_index, block_index, chainA_last_header, m_node.chainman->m_blockman);
} }
// Reorg to chain B. // Reorg to chain B.
@ -207,7 +208,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainB_last_header); CheckFilterLookups(filter_index, block_index, chainB_last_header, m_node.chainman->m_blockman);
} }
// Check that filters for stale blocks on A can be retrieved. // Check that filters for stale blocks on A can be retrieved.
@ -221,7 +222,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainA_last_header); CheckFilterLookups(filter_index, block_index, chainA_last_header, m_node.chainman->m_blockman);
} }
// Reorg back to chain A. // Reorg back to chain A.
@ -241,14 +242,14 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainA[i]->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainA[i]->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainA_last_header); CheckFilterLookups(filter_index, block_index, chainA_last_header, m_node.chainman->m_blockman);
{ {
LOCK(cs_main); LOCK(cs_main);
block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainB[i]->GetHash()); block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainB[i]->GetHash());
} }
BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain()); BOOST_CHECK(filter_index.BlockUntilSyncedToCurrentChain());
CheckFilterLookups(filter_index, block_index, chainB_last_header); CheckFilterLookups(filter_index, block_index, chainB_last_header, m_node.chainman->m_blockman);
} }
// Test lookups for a range of filters/hashes. // Test lookups for a range of filters/hashes.

View file

@ -14,7 +14,6 @@
using node::BlockManager; using node::BlockManager;
using node::BLOCK_SERIALIZATION_HEADER_SIZE; using node::BLOCK_SERIALIZATION_HEADER_SIZE;
using node::MAX_BLOCKFILE_SIZE; using node::MAX_BLOCKFILE_SIZE;
using node::OpenBlockFile;
// use BasicTestingSetup here for the data directory configuration, setup, and cleanup // use BasicTestingSetup here for the data directory configuration, setup, and cleanup
BOOST_FIXTURE_TEST_SUITE(blockmanager_tests, BasicTestingSetup) BOOST_FIXTURE_TEST_SUITE(blockmanager_tests, BasicTestingSetup)
@ -22,8 +21,9 @@ BOOST_FIXTURE_TEST_SUITE(blockmanager_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos) BOOST_AUTO_TEST_CASE(blockmanager_find_block_pos)
{ {
const auto params {CreateChainParams(ArgsManager{}, ChainType::MAIN)}; const auto params {CreateChainParams(ArgsManager{}, ChainType::MAIN)};
node::BlockManager::Options blockman_opts{ const BlockManager::Options blockman_opts{
.chainparams = *params, .chainparams = *params,
.blocks_dir = m_args.GetBlocksDirPath(),
}; };
BlockManager blockman{blockman_opts}; BlockManager blockman{blockman_opts};
CChain chain {}; CChain chain {};
@ -67,13 +67,13 @@ BOOST_FIXTURE_TEST_CASE(blockmanager_scan_unlink_already_pruned_files, TestChain
// Check that the file is not unlinked after ScanAndUnlinkAlreadyPrunedFiles // Check that the file is not unlinked after ScanAndUnlinkAlreadyPrunedFiles
// if m_have_pruned is not yet set // if m_have_pruned is not yet set
WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles()); WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles());
BOOST_CHECK(!AutoFile(OpenBlockFile(pos, true)).IsNull()); BOOST_CHECK(!AutoFile(blockman.OpenBlockFile(pos, true)).IsNull());
// Check that the file is unlinked after ScanAndUnlinkAlreadyPrunedFiles // Check that the file is unlinked after ScanAndUnlinkAlreadyPrunedFiles
// once m_have_pruned is set // once m_have_pruned is set
blockman.m_have_pruned = true; blockman.m_have_pruned = true;
WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles()); WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles());
BOOST_CHECK(AutoFile(OpenBlockFile(pos, true)).IsNull()); BOOST_CHECK(AutoFile(blockman.OpenBlockFile(pos, true)).IsNull());
// Check that calling with already pruned files doesn't cause an error // Check that calling with already pruned files doesn't cause an error
WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles()); WITH_LOCK(chainman->GetMutex(), blockman.ScanAndUnlinkAlreadyPrunedFiles());
@ -83,7 +83,7 @@ BOOST_FIXTURE_TEST_CASE(blockmanager_scan_unlink_already_pruned_files, TestChain
BOOST_CHECK_NE(old_tip, new_tip); BOOST_CHECK_NE(old_tip, new_tip);
const int new_file_number{WITH_LOCK(chainman->GetMutex(), return new_tip->GetBlockPos().nFile)}; const int new_file_number{WITH_LOCK(chainman->GetMutex(), return new_tip->GetBlockPos().nFile)};
const FlatFilePos new_pos(new_file_number, 0); const FlatFilePos new_pos(new_file_number, 0);
BOOST_CHECK(!AutoFile(OpenBlockFile(new_pos, true)).IsNull()); BOOST_CHECK(!AutoFile(blockman.OpenBlockFile(new_pos, true)).IsNull());
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View file

@ -8,20 +8,19 @@
#include <node/blockstorage.h> #include <node/blockstorage.h>
#include <validation.h> #include <validation.h>
using node::ReadBlockFromDisk; using node::BlockManager;
using node::UndoReadFromDisk;
bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter) bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex& block_index, BlockFilter& filter, const BlockManager& blockman)
{ {
LOCK(::cs_main); LOCK(::cs_main);
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, block_index->GetBlockPos(), Params().GetConsensus())) { if (!blockman.ReadBlockFromDisk(block, block_index.GetBlockPos())) {
return false; return false;
} }
CBlockUndo block_undo; CBlockUndo block_undo;
if (block_index->nHeight > 0 && !UndoReadFromDisk(block_undo, block_index)) { if (block_index.nHeight > 0 && !blockman.UndoReadFromDisk(block_undo, block_index)) {
return false; return false;
} }

View file

@ -6,8 +6,12 @@
#define BITCOIN_TEST_UTIL_BLOCKFILTER_H #define BITCOIN_TEST_UTIL_BLOCKFILTER_H
#include <blockfilter.h> #include <blockfilter.h>
class CBlockIndex;
bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter); class CBlockIndex;
namespace node {
class BlockManager;
}
bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex& block_index, BlockFilter& filter, const node::BlockManager& blockman);
#endif // BITCOIN_TEST_UTIL_BLOCKFILTER_H #endif // BITCOIN_TEST_UTIL_BLOCKFILTER_H

View file

@ -62,6 +62,7 @@
using kernel::ValidationCacheSizes; using kernel::ValidationCacheSizes;
using node::ApplyArgsManOptions; using node::ApplyArgsManOptions;
using node::BlockAssembler; using node::BlockAssembler;
using node::BlockManager;
using node::CalculateCacheSizes; using node::CalculateCacheSizes;
using node::LoadChainstate; using node::LoadChainstate;
using node::RegenerateCommitments; using node::RegenerateCommitments;
@ -186,8 +187,9 @@ ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vecto
.adjusted_time_callback = GetAdjustedTime, .adjusted_time_callback = GetAdjustedTime,
.check_block_index = true, .check_block_index = true,
}; };
node::BlockManager::Options blockman_opts{ const BlockManager::Options blockman_opts{
.chainparams = chainman_opts.chainparams, .chainparams = chainman_opts.chainparams,
.blocks_dir = m_args.GetBlocksDirPath(),
}; };
m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts, blockman_opts); m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts, blockman_opts);
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(DBParams{ m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(DBParams{

View file

@ -22,6 +22,7 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
using node::BlockManager;
using node::SnapshotMetadata; using node::SnapshotMetadata;
BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests, ChainTestingSetup) BOOST_FIXTURE_TEST_SUITE(validation_chainstatemanager_tests, ChainTestingSetup)
@ -381,8 +382,9 @@ struct SnapshotTestSetup : TestChain100Setup {
.datadir = m_args.GetDataDirNet(), .datadir = m_args.GetDataDirNet(),
.adjusted_time_callback = GetAdjustedTime, .adjusted_time_callback = GetAdjustedTime,
}; };
node::BlockManager::Options blockman_opts{ const BlockManager::Options blockman_opts{
.chainparams = chainman_opts.chainparams, .chainparams = chainman_opts.chainparams,
.blocks_dir = m_args.GetBlocksDirPath(),
}; };
// For robustness, ensure the old manager is destroyed before creating a // For robustness, ensure the old manager is destroyed before creating a
// new one. // new one.

View file

@ -79,10 +79,7 @@ using node::BlockMap;
using node::CBlockIndexHeightOnlyComparator; using node::CBlockIndexHeightOnlyComparator;
using node::CBlockIndexWorkComparator; using node::CBlockIndexWorkComparator;
using node::fReindex; using node::fReindex;
using node::ReadBlockFromDisk;
using node::SnapshotMetadata; using node::SnapshotMetadata;
using node::UndoReadFromDisk;
using node::UnlinkPrunedFiles;
/** Maximum kilobytes for transactions to store for processing during reorg */ /** Maximum kilobytes for transactions to store for processing during reorg */
static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE = 20000; static const unsigned int MAX_DISCONNECTED_TX_POOL_SIZE = 20000;
@ -1914,7 +1911,7 @@ DisconnectResult Chainstate::DisconnectBlock(const CBlock& block, const CBlockIn
bool fClean = true; bool fClean = true;
CBlockUndo blockUndo; CBlockUndo blockUndo;
if (!UndoReadFromDisk(blockUndo, pindex)) { if (!m_blockman.UndoReadFromDisk(blockUndo, *pindex)) {
error("DisconnectBlock(): failure reading undo data"); error("DisconnectBlock(): failure reading undo data");
return DISCONNECT_FAILED; return DISCONNECT_FAILED;
} }
@ -2545,7 +2542,7 @@ bool Chainstate::FlushStateToDisk(
if (fFlushForPrune) { if (fFlushForPrune) {
LOG_TIME_MILLIS_WITH_CATEGORY("unlink pruned files", BCLog::BENCH); LOG_TIME_MILLIS_WITH_CATEGORY("unlink pruned files", BCLog::BENCH);
UnlinkPrunedFiles(setFilesToPrune); m_blockman.UnlinkPrunedFiles(setFilesToPrune);
} }
m_last_write = nNow; m_last_write = nNow;
} }
@ -2709,7 +2706,7 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra
// Read block from disk. // Read block from disk.
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock& block = *pblock; CBlock& block = *pblock;
if (!ReadBlockFromDisk(block, pindexDelete, m_chainman.GetConsensus())) { if (!m_blockman.ReadBlockFromDisk(block, *pindexDelete)) {
return error("DisconnectTip(): Failed to read block"); return error("DisconnectTip(): Failed to read block");
} }
// Apply the block atomically to the chain state. // Apply the block atomically to the chain state.
@ -2826,7 +2823,7 @@ bool Chainstate::ConnectTip(BlockValidationState& state, CBlockIndex* pindexNew,
std::shared_ptr<const CBlock> pthisBlock; std::shared_ptr<const CBlock> pthisBlock;
if (!pblock) { if (!pblock) {
std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblockNew = std::make_shared<CBlock>();
if (!ReadBlockFromDisk(*pblockNew, pindexNew, m_chainman.GetConsensus())) { if (!m_blockman.ReadBlockFromDisk(*pblockNew, *pindexNew)) {
return AbortNode(state, "Failed to read block"); return AbortNode(state, "Failed to read block");
} }
pthisBlock = pblockNew; pthisBlock = pblockNew;
@ -4208,7 +4205,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
} }
CBlock block; CBlock block;
// check level 0: read from disk // check level 0: read from disk
if (!ReadBlockFromDisk(block, pindex, consensus_params)) { if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex)) {
LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
return VerifyDBResult::CORRUPTED_BLOCK_DB; return VerifyDBResult::CORRUPTED_BLOCK_DB;
} }
@ -4222,7 +4219,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
if (nCheckLevel >= 2 && pindex) { if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo; CBlockUndo undo;
if (!pindex->GetUndoPos().IsNull()) { if (!pindex->GetUndoPos().IsNull()) {
if (!UndoReadFromDisk(undo, pindex)) { if (!chainstate.m_blockman.UndoReadFromDisk(undo, *pindex)) {
LogPrintf("Verification error: found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); LogPrintf("Verification error: found bad undo data at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
return VerifyDBResult::CORRUPTED_BLOCK_DB; return VerifyDBResult::CORRUPTED_BLOCK_DB;
} }
@ -4274,7 +4271,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false); uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
pindex = chainstate.m_chain.Next(pindex); pindex = chainstate.m_chain.Next(pindex);
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, consensus_params)) { if (!chainstate.m_blockman.ReadBlockFromDisk(block, *pindex)) {
LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString()); LogPrintf("Verification error: ReadBlockFromDisk failed at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString());
return VerifyDBResult::CORRUPTED_BLOCK_DB; return VerifyDBResult::CORRUPTED_BLOCK_DB;
} }
@ -4303,7 +4300,7 @@ bool Chainstate::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& in
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
// TODO: merge with ConnectBlock // TODO: merge with ConnectBlock
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, m_chainman.GetConsensus())) { if (!m_blockman.ReadBlockFromDisk(block, *pindex)) {
return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); return error("ReplayBlock(): ReadBlockFromDisk failed at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString());
} }
@ -4355,7 +4352,7 @@ bool Chainstate::ReplayBlocks()
while (pindexOld != pindexFork) { while (pindexOld != pindexFork) {
if (pindexOld->nHeight > 0) { // Never disconnect the genesis block. if (pindexOld->nHeight > 0) { // Never disconnect the genesis block.
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindexOld, m_chainman.GetConsensus())) { if (!m_blockman.ReadBlockFromDisk(block, *pindexOld)) {
return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString()); return error("RollbackBlock(): ReadBlockFromDisk() failed at %d, hash=%s", pindexOld->nHeight, pindexOld->GetBlockHash().ToString());
} }
LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight); LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
@ -4666,7 +4663,7 @@ void Chainstate::LoadExternalBlockFile(
while (range.first != range.second) { while (range.first != range.second) {
std::multimap<uint256, FlatFilePos>::iterator it = range.first; std::multimap<uint256, FlatFilePos>::iterator it = range.first;
std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>(); std::shared_ptr<CBlock> pblockrecursive = std::make_shared<CBlock>();
if (ReadBlockFromDisk(*pblockrecursive, it->second, params.GetConsensus())) { if (m_blockman.ReadBlockFromDisk(*pblockrecursive, it->second)) {
LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(), LogPrint(BCLog::REINDEX, "%s: Processing out of order child %s of %s\n", __func__, pblockrecursive->GetHash().ToString(),
head.ToString()); head.ToString());
LOCK(cs_main); LOCK(cs_main);

View file

@ -29,7 +29,6 @@
#include <univalue.h> #include <univalue.h>
using node::MAX_BLOCKFILE_SIZE; using node::MAX_BLOCKFILE_SIZE;
using node::UnlinkPrunedFiles;
namespace wallet { namespace wallet {
RPCHelpMan importmulti(); RPCHelpMan importmulti();
@ -159,7 +158,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
file_number = oldTip->GetBlockPos().nFile; file_number = oldTip->GetBlockPos().nFile;
Assert(m_node.chainman)->m_blockman.PruneOneBlockFile(file_number); Assert(m_node.chainman)->m_blockman.PruneOneBlockFile(file_number);
} }
UnlinkPrunedFiles({file_number}); m_node.chainman->m_blockman.UnlinkPrunedFiles({file_number});
// Verify ScanForWalletTransactions only picks transactions in the new block // Verify ScanForWalletTransactions only picks transactions in the new block
// file. // file.
@ -188,7 +187,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
file_number = newTip->GetBlockPos().nFile; file_number = newTip->GetBlockPos().nFile;
Assert(m_node.chainman)->m_blockman.PruneOneBlockFile(file_number); Assert(m_node.chainman)->m_blockman.PruneOneBlockFile(file_number);
} }
UnlinkPrunedFiles({file_number}); m_node.chainman->m_blockman.UnlinkPrunedFiles({file_number});
// Verify ScanForWalletTransactions scans no blocks. // Verify ScanForWalletTransactions scans no blocks.
{ {
@ -226,7 +225,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
file_number = oldTip->GetBlockPos().nFile; file_number = oldTip->GetBlockPos().nFile;
Assert(m_node.chainman)->m_blockman.PruneOneBlockFile(file_number); Assert(m_node.chainman)->m_blockman.PruneOneBlockFile(file_number);
} }
UnlinkPrunedFiles({file_number}); m_node.chainman->m_blockman.UnlinkPrunedFiles({file_number});
// Verify importmulti RPC returns failure for a key whose creation time is // Verify importmulti RPC returns failure for a key whose creation time is
// before the missing block, and success for a key whose creation time is // before the missing block, and success for a key whose creation time is

View file

@ -6,6 +6,7 @@
#define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H #define BITCOIN_ZMQ_ZMQABSTRACTNOTIFIER_H
#include <cstdint> #include <cstdint>
#include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
@ -13,7 +14,7 @@ class CBlockIndex;
class CTransaction; class CTransaction;
class CZMQAbstractNotifier; class CZMQAbstractNotifier;
using CZMQNotifierFactory = std::unique_ptr<CZMQAbstractNotifier> (*)(); using CZMQNotifierFactory = std::function<std::unique_ptr<CZMQAbstractNotifier>()>;
class CZMQAbstractNotifier class CZMQAbstractNotifier
{ {

View file

@ -39,12 +39,14 @@ std::list<const CZMQAbstractNotifier*> CZMQNotificationInterface::GetActiveNotif
return result; return result;
} }
CZMQNotificationInterface* CZMQNotificationInterface::Create() std::unique_ptr<CZMQNotificationInterface> CZMQNotificationInterface::Create(std::function<bool(CBlock&, const CBlockIndex&)> get_block_by_index)
{ {
std::map<std::string, CZMQNotifierFactory> factories; std::map<std::string, CZMQNotifierFactory> factories;
factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>; factories["pubhashblock"] = CZMQAbstractNotifier::Create<CZMQPublishHashBlockNotifier>;
factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>; factories["pubhashtx"] = CZMQAbstractNotifier::Create<CZMQPublishHashTransactionNotifier>;
factories["pubrawblock"] = CZMQAbstractNotifier::Create<CZMQPublishRawBlockNotifier>; factories["pubrawblock"] = [&get_block_by_index]() -> std::unique_ptr<CZMQAbstractNotifier> {
return std::make_unique<CZMQPublishRawBlockNotifier>(get_block_by_index);
};
factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>; factories["pubrawtx"] = CZMQAbstractNotifier::Create<CZMQPublishRawTransactionNotifier>;
factories["pubsequence"] = CZMQAbstractNotifier::Create<CZMQPublishSequenceNotifier>; factories["pubsequence"] = CZMQAbstractNotifier::Create<CZMQPublishSequenceNotifier>;
@ -68,7 +70,7 @@ CZMQNotificationInterface* CZMQNotificationInterface::Create()
notificationInterface->notifiers = std::move(notifiers); notificationInterface->notifiers = std::move(notifiers);
if (notificationInterface->Initialize()) { if (notificationInterface->Initialize()) {
return notificationInterface.release(); return notificationInterface;
} }
} }
@ -198,4 +200,4 @@ void CZMQNotificationInterface::BlockDisconnected(const std::shared_ptr<const CB
}); });
} }
CZMQNotificationInterface* g_zmq_notification_interface = nullptr; std::unique_ptr<CZMQNotificationInterface> g_zmq_notification_interface;

View file

@ -9,6 +9,7 @@
#include <validationinterface.h> #include <validationinterface.h>
#include <cstdint> #include <cstdint>
#include <functional>
#include <list> #include <list>
#include <memory> #include <memory>
@ -23,7 +24,7 @@ public:
std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const; std::list<const CZMQAbstractNotifier*> GetActiveNotifiers() const;
static CZMQNotificationInterface* Create(); static std::unique_ptr<CZMQNotificationInterface> Create(std::function<bool(CBlock&, const CBlockIndex&)> get_block_by_index);
protected: protected:
bool Initialize(); bool Initialize();
@ -43,6 +44,6 @@ private:
std::list<std::unique_ptr<CZMQAbstractNotifier>> notifiers; std::list<std::unique_ptr<CZMQAbstractNotifier>> notifiers;
}; };
extern CZMQNotificationInterface* g_zmq_notification_interface; extern std::unique_ptr<CZMQNotificationInterface> g_zmq_notification_interface;
#endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H #endif // BITCOIN_ZMQ_ZMQNOTIFICATIONINTERFACE_H

View file

@ -39,8 +39,6 @@ namespace Consensus {
struct Params; struct Params;
} }
using node::ReadBlockFromDisk;
static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers; static std::multimap<std::string, CZMQAbstractPublishNotifier*> mapPublishNotifiers;
static const char *MSG_HASHBLOCK = "hashblock"; static const char *MSG_HASHBLOCK = "hashblock";
@ -247,10 +245,9 @@ bool CZMQPublishRawBlockNotifier::NotifyBlock(const CBlockIndex *pindex)
{ {
LogPrint(BCLog::ZMQ, "Publish rawblock %s to %s\n", pindex->GetBlockHash().GetHex(), this->address); LogPrint(BCLog::ZMQ, "Publish rawblock %s to %s\n", pindex->GetBlockHash().GetHex(), this->address);
const Consensus::Params& consensusParams = Params().GetConsensus();
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags()); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION | RPCSerializationFlags());
CBlock block; CBlock block;
if (!ReadBlockFromDisk(block, pindex, consensusParams)) { if (!m_get_block_by_index(block, *pindex)) {
zmqError("Can't read block from disk"); zmqError("Can't read block from disk");
return false; return false;
} }

View file

@ -9,7 +9,9 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <functional>
class CBlock;
class CBlockIndex; class CBlockIndex;
class CTransaction; class CTransaction;
@ -46,7 +48,12 @@ public:
class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier class CZMQPublishRawBlockNotifier : public CZMQAbstractPublishNotifier
{ {
private:
const std::function<bool(CBlock&, const CBlockIndex&)> m_get_block_by_index;
public: public:
CZMQPublishRawBlockNotifier(std::function<bool(CBlock&, const CBlockIndex&)> get_block_by_index)
: m_get_block_by_index{std::move(get_block_by_index)} {}
bool NotifyBlock(const CBlockIndex *pindex) override; bool NotifyBlock(const CBlockIndex *pindex) override;
}; };