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 <utility>
using node::ReadBlockFromDisk;
constexpr uint8_t DB_BEST_BLOCK{'B'};
constexpr auto SYNC_LOG_INTERVAL{30s};
@ -159,8 +157,6 @@ void BaseIndex::ThreadSync()
SetSyscallSandboxPolicy(SyscallSandboxPolicy::TX_INDEX);
const CBlockIndex* pindex = m_best_block_index.load();
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_locator_write_time{0s};
while (true) {
@ -207,7 +203,7 @@ void BaseIndex::ThreadSync()
CBlock block;
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",
__func__, pindex->GetBlockHash().ToString());
return;

View File

@ -12,8 +12,6 @@
#include <util/fs_helpers.h>
#include <validation.h>
using node::UndoReadFromDisk;
/* 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
* 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
// will be removed in upcoming commit
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;
}

View File

@ -19,9 +19,6 @@ using kernel::CCoinsStats;
using kernel::GetBogoSize;
using kernel::TxOutSer;
using node::ReadBlockFromDisk;
using node::UndoReadFromDisk;
static constexpr uint8_t DB_BLOCK_HASH{'s'};
static constexpr uint8_t DB_BLOCK_HEIGHT{'t'};
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
// will be removed in upcoming commit
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;
}
@ -282,12 +279,11 @@ bool CoinStatsIndex::CustomRewind(const interfaces::BlockKey& current_tip, const
LOCK(cs_main);
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 auto& consensus_params{Params().GetConsensus()};
do {
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",
__func__, iter_tip->GetBlockHash().ToString());
}
@ -409,7 +405,7 @@ bool CoinStatsIndex::ReverseBlock(const CBlock& block, const CBlockIndex* pindex
// Ignore genesis block
if (pindex->nHeight > 0) {
if (!UndoReadFromDisk(block_undo, pindex)) {
if (!m_chainstate->m_blockman.UndoReadFromDisk(block_undo, *pindex)) {
return false;
}

View File

@ -10,8 +10,6 @@
#include <node/blockstorage.h>
#include <validation.h>
using node::OpenBlockFile;
constexpr uint8_t DB_TXINDEX{'t'};
std::unique_ptr<TxIndex> g_txindex;
@ -80,7 +78,7 @@ bool TxIndex::FindTx(const uint256& tx_hash, uint256& block_hash, CTransactionRe
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()) {
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(
[&chainman = node.chainman](CBlock& block, const CBlockIndex& index) {
assert(chainman);
return node::ReadBlockFromDisk(block, &index, chainman->GetConsensus());
return chainman->m_blockman.ReadBlockFromDisk(block, index);
});
if (g_zmq_notification_interface) {

View File

@ -51,9 +51,6 @@
#include <optional>
#include <typeinfo>
using node::ReadBlockFromDisk;
using node::ReadRawBlockFromDisk;
/** How long to cache transactions in mapRelay for normal relay */
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). */
@ -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,
// as the network format matches the format on disk
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");
}
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 {
// Send block from disk
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");
}
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) {
CBlock block;
bool ret = ReadBlockFromDisk(block, pindex, m_chainparams.GetConsensus());
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pindex)};
assert(ret);
SendBlockTransactions(pfrom, *peer, block, req);
@ -5546,7 +5543,7 @@ bool PeerManagerImpl::SendMessages(CNode* pto)
m_connman.PushMessage(pto, std::move(cached_cmpctblock_msg.value()));
} else {
CBlock block;
bool ret = ReadBlockFromDisk(block, pBestIndex, consensusParams);
const bool ret{m_chainman.m_blockman.ReadBlockFromDisk(block, *pBestIndex)};
assert(ret);
CBlockHeaderAndShortTxIDs cmpctblock{block};
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;
}
static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false);
static FlatFileSeq BlockFileSeq();
static FlatFileSeq UndoFileSeq();
std::vector<CBlockIndex*> BlockManager::GetAllBlockIndices()
{
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
// is in sync with what's actually on disk by the time we start downloading, so that pruning
// works correctly.
void CleanupBlockRevFiles()
void BlockManager::CleanupBlockRevFiles() const
{
std::map<std::string, fs::path> mapBlockFiles;
@ -467,7 +463,7 @@ CBlockFileInfo* BlockManager::GetBlockFileInfo(size_t 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
AutoFile fileout{OpenUndoFile(pos)};
@ -496,9 +492,9 @@ static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const
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()) {
return error("%s: no undo data available", __func__);
@ -514,7 +510,7 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
uint256 hashChecksum;
HashVerifier verifier{filein}; // Use HashVerifier as reserializing may lose data, c.f. commit d342424301013ec47dc146a4beb49d5c9319d80a
try {
verifier << pindex->pprev->GetBlockHash();
verifier << index.pprev->GetBlockHash();
verifier >> blockundo;
filein >> hashChecksum;
} catch (const std::exception& e) {
@ -570,7 +566,7 @@ uint64_t BlockManager::CalculateCurrentUsage()
return retval;
}
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune)
void BlockManager::UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const
{
std::error_code ec;
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);
}
static FlatFileSeq UndoFileSeq()
FlatFileSeq BlockManager::UndoFileSeq() const
{
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);
}
/** 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);
}
fs::path GetBlockPosFilename(const FlatFilePos& pos)
fs::path BlockManager::GetBlockPosFilename(const FlatFilePos& pos) const
{
return BlockFileSeq().FileName(pos);
}
@ -697,7 +693,7 @@ bool BlockManager::FindUndoPos(BlockValidationState& state, int nFile, FlatFileP
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
CAutoFile fileout(OpenBlockFile(pos), SER_DISK, CLIENT_VERSION);
@ -750,7 +746,7 @@ bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValid
return true;
}
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
bool BlockManager::ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const
{
block.SetNull();
@ -768,33 +764,33 @@ bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::P
}
// 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());
}
// 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 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;
}
if (block.GetHash() != pindex->GetBlockHash()) {
if (block.GetHash() != index.GetBlockHash()) {
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;
}
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;
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;
while (true) {
FlatFilePos pos(nFile, 0);
if (!fs::exists(GetBlockPosFilename(pos))) {
if (!fs::exists(chainman.m_blockman.GetBlockPosFilename(pos))) {
break; // No block files left to reindex
}
FILE* file = OpenBlockFile(pos, true);
FILE* file = chainman.m_blockman.OpenBlockFile(pos, true);
if (!file) {
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 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 */
void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height);
@ -219,27 +227,28 @@ public:
//! 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);
/** Open a block file (blk?????.dat) */
FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false) const;
/** Translation to a filesystem path */
fs::path GetBlockPosFilename(const FlatFilePos& pos) const;
/**
* Actually unlink the specified files
*/
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const;
/** Functions for disk access for blocks */
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const;
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const;
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start) const;
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex& index) const;
void CleanupBlockRevFiles() const;
};
void CleanupBlockRevFiles();
/** Open a block file (blk?????.dat) */
FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false);
/** Translation to a filesystem path */
fs::path GetBlockPosFilename(const FlatFilePos& pos);
/**
* Actually unlink the specified files
*/
void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune);
/** Functions for disk access for blocks */
bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args, const fs::path& mempool_path);
} // namespace node

View File

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

View File

@ -394,7 +394,7 @@ public:
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 (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_in_active_chain) *block.m_in_active_chain = active[index->nHeight] == 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) {
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;
return true;
@ -557,13 +557,13 @@ public:
bool findBlock(const uint256& hash, const FoundBlock& block) override
{
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
{
WAIT_LOCK(cs_main, lock);
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
{
@ -571,10 +571,10 @@ public:
const CChain& active = chainman().ActiveChain();
if (const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash)) {
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
{
@ -582,7 +582,7 @@ public:
const CBlockIndex* block = chainman().m_blockman.LookupBlockIndex(block_hash);
const CBlockIndex* ancestor = chainman().m_blockman.LookupBlockIndex(ancestor_hash);
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
{
@ -594,9 +594,9 @@ public:
// Using & instead of && below to avoid short circuiting and leaving
// output uninitialized. Cast bool to int to avoid -Wbitwise-instead-of-logical
// compiler warnings.
return int{FillBlock(ancestor, ancestor_out, lock, active)} &
int{FillBlock(block1, block1_out, lock, active)} &
int{FillBlock(block2, block2_out, lock, active)};
return int{FillBlock(ancestor, ancestor_out, lock, active, chainman().m_blockman)} &
int{FillBlock(block1, block1_out, lock, active, chainman().m_blockman)} &
int{FillBlock(block2, block2_out, lock, active, chainman().m_blockman)};
}
void findCoins(std::map<COutPoint, Coin>& coins) override { return FindCoins(m_node, coins); }
double guessVerificationProgress(const uint256& block_hash) override

View File

@ -122,7 +122,7 @@ TransactionError BroadcastTransaction(NodeContext& node, const CTransactionRef t
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) {
CTransactionRef ptx = mempool->get(hash);
@ -143,7 +143,7 @@ CTransactionRef GetTransaction(const CBlockIndex* const block_index, const CTxMe
}
if (block_index) {
CBlock block;
if (ReadBlockFromDisk(block, block_index, consensusParams)) {
if (blockman.ReadBlockFromDisk(block, *block_index)) {
for (const auto& tx : block.vtx) {
if (tx->GetHash() == hash) {
hashBlock = block_index->GetBlockHash();

View File

@ -16,6 +16,7 @@ struct Params;
}
namespace node {
class BlockManager;
struct NodeContext;
/** 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] mempool If provided, check mempool for tx
* @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
* @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
#endif // BITCOIN_NODE_TRANSACTION_H

View File

@ -36,7 +36,6 @@
using node::GetTransaction;
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 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");
}
@ -716,7 +715,7 @@ static bool rest_tx(const std::any& context, HTTPRequest* req, const std::string
const NodeContext* const node = GetNodeContext(context, req);
if (!node) return false;
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) {
return RESTERR(req, HTTP_NOT_FOUND, hashStr + " not found");
}

View File

@ -58,9 +58,7 @@ using kernel::CoinStatsHashType;
using node::BlockManager;
using node::NodeContext;
using node::ReadBlockFromDisk;
using node::SnapshotMetadata;
using node::UndoReadFromDisk;
struct CUpdatedBlock
{
@ -183,7 +181,7 @@ UniValue blockToJSON(BlockManager& blockman, const CBlock& block, const CBlockIn
case TxVerbosity::SHOW_DETAILS_AND_PREVOUT:
CBlockUndo blockUndo;
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) {
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
// 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.
@ -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");
}

View File

@ -51,8 +51,6 @@ using node::FindCoins;
using node::GetTransaction;
using node::NodeContext;
using node::PSBTAnalysis;
using node::ReadBlockFromDisk;
using node::UndoReadFromDisk;
static void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry,
Chainstate& active_chainstate, const CTxUndo* txundo = nullptr,
@ -362,7 +360,7 @@ static RPCHelpMan getrawtransaction()
}
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) {
std::string errmsg;
if (blockindex) {
@ -406,7 +404,7 @@ static RPCHelpMan getrawtransaction()
if (tx->IsCoinBase() ||
!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());
return result;
}

View File

@ -18,7 +18,6 @@
#include <validation.h>
using node::GetTransaction;
using node::ReadBlockFromDisk;
static RPCHelpMan gettxoutproof()
{
@ -85,7 +84,7 @@ static RPCHelpMan gettxoutproof()
}
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()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transaction not yet in block");
}
@ -98,7 +97,7 @@ static RPCHelpMan gettxoutproof()
}
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");
}

View File

@ -19,6 +19,7 @@
#include <boost/test/unit_test.hpp>
using node::BlockAssembler;
using node::BlockManager;
using node::CBlockTemplate;
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,
uint256& last_header)
uint256& last_header, const BlockManager& blockman)
{
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);
return false;
}
@ -155,7 +156,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
for (block_index = m_node.chainman->ActiveChain().Genesis();
block_index != nullptr;
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());
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.
@ -207,7 +208,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
}
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.
@ -221,7 +222,7 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
}
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.
@ -241,14 +242,14 @@ BOOST_FIXTURE_TEST_CASE(blockfilter_index_initial_sync, BuildChainTestingSetup)
block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainA[i]->GetHash());
}
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);
block_index = m_node.chainman->m_blockman.LookupBlockIndex(chainB[i]->GetHash());
}
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.

View File

@ -14,7 +14,6 @@
using node::BlockManager;
using node::BLOCK_SERIALIZATION_HEADER_SIZE;
using node::MAX_BLOCKFILE_SIZE;
using node::OpenBlockFile;
// use BasicTestingSetup here for the data directory configuration, setup, and cleanup
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
// if m_have_pruned is not yet set
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
// once m_have_pruned is set
blockman.m_have_pruned = true;
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
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);
const int new_file_number{WITH_LOCK(chainman->GetMutex(), return new_tip->GetBlockPos().nFile)};
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()

View File

@ -8,20 +8,19 @@
#include <node/blockstorage.h>
#include <validation.h>
using node::ReadBlockFromDisk;
using node::UndoReadFromDisk;
using node::BlockManager;
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);
CBlock block;
if (!ReadBlockFromDisk(block, block_index->GetBlockPos(), Params().GetConsensus())) {
if (!blockman.ReadBlockFromDisk(block, block_index.GetBlockPos())) {
return false;
}
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;
}

View File

@ -6,8 +6,12 @@
#define BITCOIN_TEST_UTIL_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

View File

@ -79,10 +79,7 @@ using node::BlockMap;
using node::CBlockIndexHeightOnlyComparator;
using node::CBlockIndexWorkComparator;
using node::fReindex;
using node::ReadBlockFromDisk;
using node::SnapshotMetadata;
using node::UndoReadFromDisk;
using node::UnlinkPrunedFiles;
/** Maximum kilobytes for transactions to store for processing during reorg */
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;
CBlockUndo blockUndo;
if (!UndoReadFromDisk(blockUndo, pindex)) {
if (!m_blockman.UndoReadFromDisk(blockUndo, *pindex)) {
error("DisconnectBlock(): failure reading undo data");
return DISCONNECT_FAILED;
}
@ -2545,7 +2542,7 @@ bool Chainstate::FlushStateToDisk(
if (fFlushForPrune) {
LOG_TIME_MILLIS_WITH_CATEGORY("unlink pruned files", BCLog::BENCH);
UnlinkPrunedFiles(setFilesToPrune);
m_blockman.UnlinkPrunedFiles(setFilesToPrune);
}
m_last_write = nNow;
}
@ -2709,7 +2706,7 @@ bool Chainstate::DisconnectTip(BlockValidationState& state, DisconnectedBlockTra
// Read block from disk.
std::shared_ptr<CBlock> pblock = std::make_shared<CBlock>();
CBlock& block = *pblock;
if (!ReadBlockFromDisk(block, pindexDelete, m_chainman.GetConsensus())) {
if (!m_blockman.ReadBlockFromDisk(block, *pindexDelete)) {
return error("DisconnectTip(): Failed to read block");
}
// 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;
if (!pblock) {
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");
}
pthisBlock = pblockNew;
@ -4208,7 +4205,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
}
CBlock block;
// 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());
return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
@ -4222,7 +4219,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
if (nCheckLevel >= 2 && pindex) {
CBlockUndo undo;
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());
return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
@ -4274,7 +4271,7 @@ VerifyDBResult CVerifyDB::VerifyDB(
uiInterface.ShowProgress(_("Verifying blocks…").translated, percentageDone, false);
pindex = chainstate.m_chain.Next(pindex);
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());
return VerifyDBResult::CORRUPTED_BLOCK_DB;
}
@ -4303,7 +4300,7 @@ bool Chainstate::RollforwardBlock(const CBlockIndex* pindex, CCoinsViewCache& in
AssertLockHeld(cs_main);
// TODO: merge with ConnectBlock
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());
}
@ -4355,7 +4352,7 @@ bool Chainstate::ReplayBlocks()
while (pindexOld != pindexFork) {
if (pindexOld->nHeight > 0) { // Never disconnect the genesis 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());
}
LogPrintf("Rolling back %s (%i)\n", pindexOld->GetBlockHash().ToString(), pindexOld->nHeight);
@ -4666,7 +4663,7 @@ void Chainstate::LoadExternalBlockFile(
while (range.first != range.second) {
std::multimap<uint256, FlatFilePos>::iterator it = range.first;
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(),
head.ToString());
LOCK(cs_main);

View File

@ -29,7 +29,6 @@
#include <univalue.h>
using node::MAX_BLOCKFILE_SIZE;
using node::UnlinkPrunedFiles;
namespace wallet {
RPCHelpMan importmulti();
@ -159,7 +158,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
file_number = oldTip->GetBlockPos().nFile;
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
// file.
@ -188,7 +187,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
file_number = newTip->GetBlockPos().nFile;
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.
{
@ -226,7 +225,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
file_number = oldTip->GetBlockPos().nFile;
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
// before the missing block, and success for a key whose creation time is