refactor: Move functions to BlockManager methods

This is a commit in preparation for the next few commits. The functions
are moved to methods to avoid their re-declaration for the purpose of
passing in BlockManager options.

The functions that were now moved into the BlockManager should no longer
use the params as an argument, but instead use the member variable.

In the moved ReadBlockFromDisk and UndoReadFromDisk, change
the function signature to accept a reference to a CBlockIndex instead of
a raw pointer. The pointer is expected to be non-null, so reflect that
in the type.

To allow for the move of functions to BlockManager methods all call
sites require an instantiated BlockManager, or a callback to one.
This commit is contained in:
TheCharlatan 2023-02-18 15:49:41 +01:00
parent cfbb212493
commit f0bb1021f0
No known key found for this signature in database
GPG key ID: 9B79B45691DB4173
22 changed files with 122 additions and 139 deletions

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

@ -1427,7 +1427,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
g_zmq_notification_interface = CZMQNotificationInterface::Create( g_zmq_notification_interface = CZMQNotificationInterface::Create(
[&chainman = node.chainman](CBlock& block, const CBlockIndex& index) { [&chainman = node.chainman](CBlock& block, const CBlockIndex& index) {
assert(chainman); assert(chainman);
return node::ReadBlockFromDisk(block, &index, chainman->GetConsensus()); return chainman->m_blockman.ReadBlockFromDisk(block, index);
}); });
if (g_zmq_notification_interface) { if (g_zmq_notification_interface) {

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

@ -53,10 +53,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 +419,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;
@ -467,7 +463,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 +492,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 +510,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 +566,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 +579,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(gArgs.GetBlocksDirPath(), "blk", gArgs.GetBoolArg("-fastprune", false) ? 0x4000 /* 16kb */ : BLOCKFILE_CHUNK_SIZE);
} }
static FlatFileSeq UndoFileSeq() FlatFileSeq BlockManager::UndoFileSeq() const
{ {
return FlatFileSeq(gArgs.GetBlocksDirPath(), "rev", UNDOFILE_CHUNK_SIZE); return FlatFileSeq(gArgs.GetBlocksDirPath(), "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);
} }
@ -697,7 +693,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 +746,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 +764,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
@ -888,10 +884,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
} }

View file

@ -96,6 +96,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);
@ -219,26 +227,27 @@ 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) */
FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false) const;
/** Open a block file (blk?????.dat) */ /** Translation to a filesystem path */
FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false); fs::path GetBlockPosFilename(const FlatFilePos& pos) const;
/** Translation to a filesystem path */
fs::path GetBlockPosFilename(const FlatFilePos& pos);
/** /**
* 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 CleanupBlockRevFiles() const;
};
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 ArgsManager& args, const fs::path& mempool_path);
} // namespace node } // namespace node

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)
@ -67,13 +66,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 +82,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

@ -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