0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-02-13 11:25:02 -05:00

Merge bitcoin/bitcoin#23974: Make blockstorage globals private members of BlockManager

fa68a6c2fc scripted-diff: Rename touched member variables (MarcoFalke)
facd3df21f Make blockstorage globals private members of BlockManager (MarcoFalke)
faa8c2d7d7 doc: Clarify nPruneAfterHeight for signet (MarcoFalke)
fad381b2f8 test: Load genesis block to allow flush (MarcoFalke)
fab262174b Move blockstorage-related unload to BlockManager::Unload (MarcoFalke)
fa467f3913 move-only: Create WriteBlockIndexDB helper (MarcoFalke)
fa88cfd3f9 Move functions to BlockManager (MarcoFalke)

Pull request description:

  Globals aren't too nice because they hide dependencies, also they make testing harder.

  Fix that by removing some.

ACKs for top commit:
  Sjors:
    ACK fa68a6c2fc
  ryanofsky:
    Code review ACK fa68a6c2fc. Nice changes!

Tree-SHA512: 6abc5929a5e43a05e238276721d46a64a44f23dca18c2caa9775437a32351d6815d88b88757254686421531d0df13861bbd3a202e13a3192798d87a96abef65d
This commit is contained in:
fanquake 2022-01-07 10:37:12 +08:00
commit 4ada74206a
No known key found for this signature in database
GPG key ID: 2EEB9F5CC09526C1
6 changed files with 141 additions and 134 deletions

View file

@ -27,23 +27,6 @@ bool fHavePruned = false;
bool fPruneMode = false; bool fPruneMode = false;
uint64_t nPruneTarget = 0; uint64_t nPruneTarget = 0;
// TODO make namespace {
RecursiveMutex cs_LastBlockFile;
std::vector<CBlockFileInfo> vinfoBlockFile;
int nLastBlockFile = 0;
/** Global flag to indicate we should check to see if there are
* block/undo files that should be deleted. Set on startup
* or if we allocate more file space when we're in prune mode
*/
bool fCheckForPruning = false;
/** Dirty block index entries. */
std::set<CBlockIndex*> setDirtyBlockIndex;
/** Dirty block file entries. */
std::set<int> setDirtyFileInfo;
// } // namespace
static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false); static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false);
static FlatFileSeq BlockFileSeq(); static FlatFileSeq BlockFileSeq();
static FlatFileSeq UndoFileSeq(); static FlatFileSeq UndoFileSeq();
@ -86,7 +69,7 @@ CBlockIndex* BlockManager::AddToBlockIndex(const CBlockHeader& block)
if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork) if (pindexBestHeader == nullptr || pindexBestHeader->nChainWork < pindexNew->nChainWork)
pindexBestHeader = pindexNew; pindexBestHeader = pindexNew;
setDirtyBlockIndex.insert(pindexNew); m_dirty_blockindex.insert(pindexNew);
return pindexNew; return pindexNew;
} }
@ -104,7 +87,7 @@ void BlockManager::PruneOneBlockFile(const int fileNumber)
pindex->nFile = 0; pindex->nFile = 0;
pindex->nDataPos = 0; pindex->nDataPos = 0;
pindex->nUndoPos = 0; pindex->nUndoPos = 0;
setDirtyBlockIndex.insert(pindex); m_dirty_blockindex.insert(pindex);
// Prune from m_blocks_unlinked -- any block we prune would have // Prune from m_blocks_unlinked -- any block we prune would have
// to be downloaded again in order to consider its chain, at which // to be downloaded again in order to consider its chain, at which
@ -121,8 +104,8 @@ void BlockManager::PruneOneBlockFile(const int fileNumber)
} }
} }
vinfoBlockFile[fileNumber].SetNull(); m_blockfile_info[fileNumber].SetNull();
setDirtyFileInfo.insert(fileNumber); m_dirty_fileinfo.insert(fileNumber);
} }
void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height) void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
@ -137,8 +120,8 @@ void BlockManager::FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nM
// last block to prune is the lesser of (user-specified height, MIN_BLOCKS_TO_KEEP from the tip) // last block to prune is the lesser of (user-specified height, MIN_BLOCKS_TO_KEEP from the tip)
unsigned int nLastBlockWeCanPrune = std::min((unsigned)nManualPruneHeight, chain_tip_height - MIN_BLOCKS_TO_KEEP); unsigned int nLastBlockWeCanPrune = std::min((unsigned)nManualPruneHeight, chain_tip_height - MIN_BLOCKS_TO_KEEP);
int count = 0; int count = 0;
for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { for (int fileNumber = 0; fileNumber < m_last_blockfile; fileNumber++) {
if (vinfoBlockFile[fileNumber].nSize == 0 || vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) { if (m_blockfile_info[fileNumber].nSize == 0 || m_blockfile_info[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
continue; continue;
} }
PruneOneBlockFile(fileNumber); PruneOneBlockFile(fileNumber);
@ -177,10 +160,10 @@ void BlockManager::FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPr
nBuffer += nPruneTarget / 10; nBuffer += nPruneTarget / 10;
} }
for (int fileNumber = 0; fileNumber < nLastBlockFile; fileNumber++) { for (int fileNumber = 0; fileNumber < m_last_blockfile; fileNumber++) {
nBytesToPrune = vinfoBlockFile[fileNumber].nSize + vinfoBlockFile[fileNumber].nUndoSize; nBytesToPrune = m_blockfile_info[fileNumber].nSize + m_blockfile_info[fileNumber].nUndoSize;
if (vinfoBlockFile[fileNumber].nSize == 0) { if (m_blockfile_info[fileNumber].nSize == 0) {
continue; continue;
} }
@ -189,7 +172,7 @@ void BlockManager::FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPr
} }
// don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning // don't prune files that could have a block within MIN_BLOCKS_TO_KEEP of the main chain's tip but keep scanning
if (vinfoBlockFile[fileNumber].nHeightLast > nLastBlockWeCanPrune) { if (m_blockfile_info[fileNumber].nHeightLast > nLastBlockWeCanPrune) {
continue; continue;
} }
@ -290,7 +273,7 @@ bool BlockManager::LoadBlockIndex(
} }
if (!(pindex->nStatus & BLOCK_FAILED_MASK) && pindex->pprev && (pindex->pprev->nStatus & BLOCK_FAILED_MASK)) { if (!(pindex->nStatus & BLOCK_FAILED_MASK) && pindex->pprev && (pindex->pprev->nStatus & BLOCK_FAILED_MASK)) {
pindex->nStatus |= BLOCK_FAILED_CHILD; pindex->nStatus |= BLOCK_FAILED_CHILD;
setDirtyBlockIndex.insert(pindex); m_dirty_blockindex.insert(pindex);
} }
if (pindex->IsAssumedValid() || if (pindex->IsAssumedValid() ||
(pindex->IsValid(BLOCK_VALID_TRANSACTIONS) && (pindex->IsValid(BLOCK_VALID_TRANSACTIONS) &&
@ -348,6 +331,31 @@ void BlockManager::Unload()
} }
m_block_index.clear(); m_block_index.clear();
m_blockfile_info.clear();
m_last_blockfile = 0;
m_dirty_blockindex.clear();
m_dirty_fileinfo.clear();
}
bool BlockManager::WriteBlockIndexDB()
{
std::vector<std::pair<int, const CBlockFileInfo*>> vFiles;
vFiles.reserve(m_dirty_fileinfo.size());
for (std::set<int>::iterator it = m_dirty_fileinfo.begin(); it != m_dirty_fileinfo.end();) {
vFiles.push_back(std::make_pair(*it, &m_blockfile_info[*it]));
m_dirty_fileinfo.erase(it++);
}
std::vector<const CBlockIndex*> vBlocks;
vBlocks.reserve(m_dirty_blockindex.size());
for (std::set<CBlockIndex*>::iterator it = m_dirty_blockindex.begin(); it != m_dirty_blockindex.end();) {
vBlocks.push_back(*it);
m_dirty_blockindex.erase(it++);
}
if (!m_block_tree_db->WriteBatchSync(vFiles, m_last_blockfile, vBlocks)) {
return false;
}
return true;
} }
bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman) bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman)
@ -357,17 +365,17 @@ bool BlockManager::LoadBlockIndexDB(ChainstateManager& chainman)
} }
// Load block file info // Load block file info
m_block_tree_db->ReadLastBlockFile(nLastBlockFile); m_block_tree_db->ReadLastBlockFile(m_last_blockfile);
vinfoBlockFile.resize(nLastBlockFile + 1); m_blockfile_info.resize(m_last_blockfile + 1);
LogPrintf("%s: last block file = %i\n", __func__, nLastBlockFile); LogPrintf("%s: last block file = %i\n", __func__, m_last_blockfile);
for (int nFile = 0; nFile <= nLastBlockFile; nFile++) { for (int nFile = 0; nFile <= m_last_blockfile; nFile++) {
m_block_tree_db->ReadBlockFileInfo(nFile, vinfoBlockFile[nFile]); m_block_tree_db->ReadBlockFileInfo(nFile, m_blockfile_info[nFile]);
} }
LogPrintf("%s: last block file info: %s\n", __func__, vinfoBlockFile[nLastBlockFile].ToString()); LogPrintf("%s: last block file info: %s\n", __func__, m_blockfile_info[m_last_blockfile].ToString());
for (int nFile = nLastBlockFile + 1; true; nFile++) { for (int nFile = m_last_blockfile + 1; true; nFile++) {
CBlockFileInfo info; CBlockFileInfo info;
if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) { if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) {
vinfoBlockFile.push_back(info); m_blockfile_info.push_back(info);
} else { } else {
break; break;
} }
@ -425,7 +433,7 @@ bool IsBlockPruned(const CBlockIndex* pblockindex)
// If we're using -prune with -reindex, then delete block files that will be ignored by the // If we're using -prune with -reindex, then delete block files that will be ignored by the
// reindex. Since reindexing works by starting at block file 0 and looping until a blockfile // reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
// is missing, do the same here to delete any later block files after a gap. Also delete all // is missing, do the same here to delete any later block files after a gap. Also delete all
// rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile // 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 CleanupBlockRevFiles()
@ -470,11 +478,11 @@ std::string CBlockFileInfo::ToString() const
return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast)); return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
} }
CBlockFileInfo* GetBlockFileInfo(size_t n) CBlockFileInfo* BlockManager::GetBlockFileInfo(size_t n)
{ {
LOCK(cs_LastBlockFile); LOCK(cs_LastBlockFile);
return &vinfoBlockFile.at(n); return &m_blockfile_info.at(n);
} }
static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart) static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
@ -538,32 +546,32 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
return true; return true;
} }
static void FlushUndoFile(int block_file, bool finalize = false) void BlockManager::FlushUndoFile(int block_file, bool finalize)
{ {
FlatFilePos undo_pos_old(block_file, vinfoBlockFile[block_file].nUndoSize); FlatFilePos undo_pos_old(block_file, m_blockfile_info[block_file].nUndoSize);
if (!UndoFileSeq().Flush(undo_pos_old, finalize)) { if (!UndoFileSeq().Flush(undo_pos_old, finalize)) {
AbortNode("Flushing undo file to disk failed. This is likely the result of an I/O error."); AbortNode("Flushing undo file to disk failed. This is likely the result of an I/O error.");
} }
} }
void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false) void BlockManager::FlushBlockFile(bool fFinalize, bool finalize_undo)
{ {
LOCK(cs_LastBlockFile); LOCK(cs_LastBlockFile);
FlatFilePos block_pos_old(nLastBlockFile, vinfoBlockFile[nLastBlockFile].nSize); FlatFilePos block_pos_old(m_last_blockfile, m_blockfile_info[m_last_blockfile].nSize);
if (!BlockFileSeq().Flush(block_pos_old, fFinalize)) { if (!BlockFileSeq().Flush(block_pos_old, fFinalize)) {
AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error."); AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error.");
} }
// we do not always flush the undo file, as the chain tip may be lagging behind the incoming blocks, // we do not always flush the undo file, as the chain tip may be lagging behind the incoming blocks,
// e.g. during IBD or a sync after a node going offline // e.g. during IBD or a sync after a node going offline
if (!fFinalize || finalize_undo) FlushUndoFile(nLastBlockFile, finalize_undo); if (!fFinalize || finalize_undo) FlushUndoFile(m_last_blockfile, finalize_undo);
} }
uint64_t CalculateCurrentUsage() uint64_t BlockManager::CalculateCurrentUsage()
{ {
LOCK(cs_LastBlockFile); LOCK(cs_LastBlockFile);
uint64_t retval = 0; uint64_t retval = 0;
for (const CBlockFileInfo& file : vinfoBlockFile) { for (const CBlockFileInfo& file : m_blockfile_info) {
retval += file.nSize + file.nUndoSize; retval += file.nSize + file.nUndoSize;
} }
return retval; return retval;
@ -605,44 +613,44 @@ fs::path GetBlockPosFilename(const FlatFilePos& pos)
return BlockFileSeq().FileName(pos); return BlockFileSeq().FileName(pos);
} }
bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false) bool BlockManager::FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown)
{ {
LOCK(cs_LastBlockFile); LOCK(cs_LastBlockFile);
unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile; unsigned int nFile = fKnown ? pos.nFile : m_last_blockfile;
if (vinfoBlockFile.size() <= nFile) { if (m_blockfile_info.size() <= nFile) {
vinfoBlockFile.resize(nFile + 1); m_blockfile_info.resize(nFile + 1);
} }
bool finalize_undo = false; bool finalize_undo = false;
if (!fKnown) { if (!fKnown) {
while (vinfoBlockFile[nFile].nSize + nAddSize >= (gArgs.GetBoolArg("-fastprune", false) ? 0x10000 /* 64kb */ : MAX_BLOCKFILE_SIZE)) { while (m_blockfile_info[nFile].nSize + nAddSize >= (gArgs.GetBoolArg("-fastprune", false) ? 0x10000 /* 64kb */ : MAX_BLOCKFILE_SIZE)) {
// when the undo file is keeping up with the block file, we want to flush it explicitly // when the undo file is keeping up with the block file, we want to flush it explicitly
// when it is lagging behind (more blocks arrive than are being connected), we let the // when it is lagging behind (more blocks arrive than are being connected), we let the
// undo block write case handle it // undo block write case handle it
finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight); finalize_undo = (m_blockfile_info[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight);
nFile++; nFile++;
if (vinfoBlockFile.size() <= nFile) { if (m_blockfile_info.size() <= nFile) {
vinfoBlockFile.resize(nFile + 1); m_blockfile_info.resize(nFile + 1);
} }
} }
pos.nFile = nFile; pos.nFile = nFile;
pos.nPos = vinfoBlockFile[nFile].nSize; pos.nPos = m_blockfile_info[nFile].nSize;
} }
if ((int)nFile != nLastBlockFile) { if ((int)nFile != m_last_blockfile) {
if (!fKnown) { if (!fKnown) {
LogPrint(BCLog::BLOCKSTORE, "Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString()); LogPrint(BCLog::BLOCKSTORE, "Leaving block file %i: %s\n", m_last_blockfile, m_blockfile_info[m_last_blockfile].ToString());
} }
FlushBlockFile(!fKnown, finalize_undo); FlushBlockFile(!fKnown, finalize_undo);
nLastBlockFile = nFile; m_last_blockfile = nFile;
} }
vinfoBlockFile[nFile].AddBlock(nHeight, nTime); m_blockfile_info[nFile].AddBlock(nHeight, nTime);
if (fKnown) { if (fKnown) {
vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize); m_blockfile_info[nFile].nSize = std::max(pos.nPos + nAddSize, m_blockfile_info[nFile].nSize);
} else { } else {
vinfoBlockFile[nFile].nSize += nAddSize; m_blockfile_info[nFile].nSize += nAddSize;
} }
if (!fKnown) { if (!fKnown) {
@ -652,23 +660,23 @@ bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight,
return AbortNode("Disk space is too low!", _("Disk space is too low!")); return AbortNode("Disk space is too low!", _("Disk space is too low!"));
} }
if (bytes_allocated != 0 && fPruneMode) { if (bytes_allocated != 0 && fPruneMode) {
fCheckForPruning = true; m_check_for_pruning = true;
} }
} }
setDirtyFileInfo.insert(nFile); m_dirty_fileinfo.insert(nFile);
return true; return true;
} }
static bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize) bool BlockManager::FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize)
{ {
pos.nFile = nFile; pos.nFile = nFile;
LOCK(cs_LastBlockFile); LOCK(cs_LastBlockFile);
pos.nPos = vinfoBlockFile[nFile].nUndoSize; pos.nPos = m_blockfile_info[nFile].nUndoSize;
vinfoBlockFile[nFile].nUndoSize += nAddSize; m_blockfile_info[nFile].nUndoSize += nAddSize;
setDirtyFileInfo.insert(nFile); m_dirty_fileinfo.insert(nFile);
bool out_of_space; bool out_of_space;
size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space); size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space);
@ -676,7 +684,7 @@ static bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos
return AbortNode(state, "Disk space is too low!", _("Disk space is too low!")); return AbortNode(state, "Disk space is too low!", _("Disk space is too low!"));
} }
if (bytes_allocated != 0 && fPruneMode) { if (bytes_allocated != 0 && fPruneMode) {
fCheckForPruning = true; m_check_for_pruning = true;
} }
return true; return true;
@ -705,7 +713,7 @@ static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessa
return true; return true;
} }
bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams) bool BlockManager::WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams)
{ {
// Write undo information to disk // Write undo information to disk
if (pindex->GetUndoPos().IsNull()) { if (pindex->GetUndoPos().IsNull()) {
@ -721,14 +729,14 @@ bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& st
// in the block file info as below; note that this does not catch the case where the undo writes are keeping up // in the block file info as below; note that this does not catch the case where the undo writes are keeping up
// with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in // with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in
// the FindBlockPos function // the FindBlockPos function
if (_pos.nFile < nLastBlockFile && static_cast<uint32_t>(pindex->nHeight) == vinfoBlockFile[_pos.nFile].nHeightLast) { if (_pos.nFile < m_last_blockfile && static_cast<uint32_t>(pindex->nHeight) == m_blockfile_info[_pos.nFile].nHeightLast) {
FlushUndoFile(_pos.nFile, true); FlushUndoFile(_pos.nFile, true);
} }
// update nUndoPos in block index // update nUndoPos in block index
pindex->nUndoPos = _pos.nPos; pindex->nUndoPos = _pos.nPos;
pindex->nStatus |= BLOCK_HAVE_UNDO; pindex->nStatus |= BLOCK_HAVE_UNDO;
setDirtyBlockIndex.insert(pindex); m_dirty_blockindex.insert(pindex);
} }
return true; return true;
@ -825,7 +833,7 @@ bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex
} }
/** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */ /** Store block on disk. If dbp is non-nullptr, the file is known to already reside on disk */
FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp) FlatFilePos BlockManager::SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp)
{ {
unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION); unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
FlatFilePos blockPos; FlatFilePos blockPos;

View file

@ -64,8 +64,14 @@ struct CBlockIndexWorkComparator {
class BlockManager class BlockManager
{ {
friend CChainState; friend CChainState;
friend ChainstateManager;
private: private:
void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
void FlushUndoFile(int block_file, bool finalize = false);
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);
/* 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);
@ -75,9 +81,9 @@ private:
* space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex
* (which in this case means the blockchain must be re-downloaded.) * (which in this case means the blockchain must be re-downloaded.)
* *
* Pruning functions are called from FlushStateToDisk when the global fCheckForPruning flag has been set. * Pruning functions are called from FlushStateToDisk when the m_check_for_pruning flag has been set.
* Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.) * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
* Pruning cannot take place until the longest chain is at least a certain length (100000 on mainnet, 1000 on testnet, 1000 on regtest). * Pruning cannot take place until the longest chain is at least a certain length (CChainParams::nPruneAfterHeight).
* Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip. * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
* The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files. * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
* A db flag records the fact that at least some block files have been pruned. * A db flag records the fact that at least some block files have been pruned.
@ -86,6 +92,21 @@ private:
*/ */
void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, int prune_height, bool is_ibd); void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, int prune_height, bool is_ibd);
RecursiveMutex cs_LastBlockFile;
std::vector<CBlockFileInfo> m_blockfile_info;
int m_last_blockfile = 0;
/** Global flag to indicate we should check to see if there are
* block/undo files that should be deleted. Set on startup
* or if we allocate more file space when we're in prune mode
*/
bool m_check_for_pruning = false;
/** Dirty block index entries. */
std::set<CBlockIndex*> m_dirty_blockindex;
/** Dirty block file entries. */
std::set<int> m_dirty_fileinfo;
public: public:
BlockMap m_block_index GUARDED_BY(cs_main); BlockMap m_block_index GUARDED_BY(cs_main);
@ -97,12 +118,13 @@ public:
std::unique_ptr<CBlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main); std::unique_ptr<CBlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main);
bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
bool LoadBlockIndexDB(ChainstateManager& chainman) EXCLUSIVE_LOCKS_REQUIRED(::cs_main); bool LoadBlockIndexDB(ChainstateManager& chainman) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
/** /**
* Load the blocktree off disk and into memory. Populate certain metadata * Load the blocktree off disk and into memory. Populate certain metadata
* per index entry (nStatus, nChainWork, nTimeMax, etc.) as well as peripheral * per index entry (nStatus, nChainWork, nTimeMax, etc.) as well as peripheral
* collections like setDirtyBlockIndex. * collections like m_dirty_blockindex.
*/ */
bool LoadBlockIndex( bool LoadBlockIndex(
const Consensus::Params& consensus_params, const Consensus::Params& consensus_params,
@ -120,6 +142,16 @@ public:
CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main); CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
/** Get block file info entry for one block file */
CBlockFileInfo* GetBlockFileInfo(size_t n);
bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams);
FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
/** Calculate the amount of disk space the block & undo files currently use */
uint64_t CalculateCurrentUsage();
//! Returns last CBlockIndex* that is a checkpoint //! Returns last CBlockIndex* that is a checkpoint
CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main); CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
@ -139,12 +171,6 @@ FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false);
/** Translation to a filesystem path */ /** Translation to a filesystem path */
fs::path GetBlockPosFilename(const FlatFilePos& pos); fs::path GetBlockPosFilename(const FlatFilePos& pos);
/** Get block file info entry for one block file */
CBlockFileInfo* GetBlockFileInfo(size_t n);
/** Calculate the amount of disk space the block & undo files currently use */
uint64_t CalculateCurrentUsage();
/** /**
* Actually unlink the specified files * Actually unlink the specified files
*/ */
@ -157,9 +183,6 @@ bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, c
bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start); bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start);
bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex); bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams);
FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args); void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args);

View file

@ -1564,7 +1564,7 @@ RPCHelpMan getblockchaininfo()
obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip)); obj.pushKV("verificationprogress", GuessVerificationProgress(Params().TxData(), tip));
obj.pushKV("initialblockdownload", active_chainstate.IsInitialBlockDownload()); obj.pushKV("initialblockdownload", active_chainstate.IsInitialBlockDownload());
obj.pushKV("chainwork", tip->nChainWork.GetHex()); obj.pushKV("chainwork", tip->nChainWork.GetHex());
obj.pushKV("size_on_disk", CalculateCurrentUsage()); obj.pushKV("size_on_disk", chainman.m_blockman.CalculateCurrentUsage());
obj.pushKV("pruned", fPruneMode); obj.pushKV("pruned", fPruneMode);
if (fPruneMode) { if (fPruneMode) {
const CBlockIndex* block = tip; const CBlockIndex* block = tip;

View file

@ -43,6 +43,7 @@ BOOST_AUTO_TEST_CASE(validation_chainstate_resize_caches)
c1.InitCoinsDB( c1.InitCoinsDB(
/*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false); /*cache_size_bytes=*/1 << 23, /*in_memory=*/true, /*should_wipe=*/false);
WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23)); WITH_LOCK(::cs_main, c1.InitCoinsCache(1 << 23));
BOOST_REQUIRE(c1.LoadGenesisBlock()); // Need at least one block loaded to be able to flush caches
// Add a coin to the in-memory cache, upsize once, then downsize. // Add a coin to the in-memory cache, upsize once, then downsize.
{ {

View file

@ -133,16 +133,6 @@ arith_uint256 nMinimumChainWork;
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE); CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
// Internal stuff from blockstorage ...
extern RecursiveMutex cs_LastBlockFile;
extern std::vector<CBlockFileInfo> vinfoBlockFile;
extern int nLastBlockFile;
extern bool fCheckForPruning;
extern std::set<CBlockIndex*> setDirtyBlockIndex;
extern std::set<int> setDirtyFileInfo;
void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
// ... TODO move fully to blockstorage
CBlockIndex* CChainState::FindForkInGlobalIndex(const CBlockLocator& locator) const CBlockIndex* CChainState::FindForkInGlobalIndex(const CBlockLocator& locator) const
{ {
AssertLockHeld(cs_main); AssertLockHeld(cs_main);
@ -1505,7 +1495,7 @@ void CChainState::InvalidBlockFound(CBlockIndex* pindex, const BlockValidationSt
if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { if (state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID; pindex->nStatus |= BLOCK_FAILED_VALID;
m_chainman.m_failed_blocks.insert(pindex); m_chainman.m_failed_blocks.insert(pindex);
setDirtyBlockIndex.insert(pindex); m_blockman.m_dirty_blockindex.insert(pindex);
setBlockIndexCandidates.erase(pindex); setBlockIndexCandidates.erase(pindex);
InvalidChainFound(pindex); InvalidChainFound(pindex);
} }
@ -2135,13 +2125,13 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state,
if (fJustCheck) if (fJustCheck)
return true; return true;
if (!WriteUndoDataForBlock(blockundo, state, pindex, m_params)) { if (!m_blockman.WriteUndoDataForBlock(blockundo, state, pindex, m_params)) {
return false; return false;
} }
if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) { if (!pindex->IsValid(BLOCK_VALID_SCRIPTS)) {
pindex->RaiseValidity(BLOCK_VALID_SCRIPTS); pindex->RaiseValidity(BLOCK_VALID_SCRIPTS);
setDirtyBlockIndex.insert(pindex); m_blockman.m_dirty_blockindex.insert(pindex);
} }
assert(pindex->phashBlock); assert(pindex->phashBlock);
@ -2214,8 +2204,8 @@ bool CChainState::FlushStateToDisk(
bool fDoFullFlush = false; bool fDoFullFlush = false;
CoinsCacheSizeState cache_state = GetCoinsCacheSizeState(); CoinsCacheSizeState cache_state = GetCoinsCacheSizeState();
LOCK(cs_LastBlockFile); LOCK(m_blockman.cs_LastBlockFile);
if (fPruneMode && (fCheckForPruning || nManualPruneHeight > 0) && !fReindex) { if (fPruneMode && (m_blockman.m_check_for_pruning || nManualPruneHeight > 0) && !fReindex) {
// make sure we don't prune above the blockfilterindexes bestblocks // make sure we don't prune above the blockfilterindexes bestblocks
// pruning is height-based // pruning is height-based
int last_prune = m_chain.Height(); // last height we can prune int last_prune = m_chain.Height(); // last height we can prune
@ -2231,7 +2221,7 @@ bool CChainState::FlushStateToDisk(
LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH); LOG_TIME_MILLIS_WITH_CATEGORY("find files to prune", BCLog::BENCH);
m_blockman.FindFilesToPrune(setFilesToPrune, m_params.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload()); m_blockman.FindFilesToPrune(setFilesToPrune, m_params.PruneAfterHeight(), m_chain.Height(), last_prune, IsInitialBlockDownload());
fCheckForPruning = false; m_blockman.m_check_for_pruning = false;
} }
if (!setFilesToPrune.empty()) { if (!setFilesToPrune.empty()) {
fFlushForPrune = true; fFlushForPrune = true;
@ -2269,26 +2259,14 @@ bool CChainState::FlushStateToDisk(
LOG_TIME_MILLIS_WITH_CATEGORY("write block and undo data to disk", BCLog::BENCH); LOG_TIME_MILLIS_WITH_CATEGORY("write block and undo data to disk", BCLog::BENCH);
// First make sure all block and undo data is flushed to disk. // First make sure all block and undo data is flushed to disk.
FlushBlockFile(); m_blockman.FlushBlockFile();
} }
// Then update all block file information (which may refer to block and undo files). // Then update all block file information (which may refer to block and undo files).
{ {
LOG_TIME_MILLIS_WITH_CATEGORY("write block index to disk", BCLog::BENCH); LOG_TIME_MILLIS_WITH_CATEGORY("write block index to disk", BCLog::BENCH);
std::vector<std::pair<int, const CBlockFileInfo*> > vFiles; if (!m_blockman.WriteBlockIndexDB()) {
vFiles.reserve(setDirtyFileInfo.size());
for (std::set<int>::iterator it = setDirtyFileInfo.begin(); it != setDirtyFileInfo.end(); ) {
vFiles.push_back(std::make_pair(*it, &vinfoBlockFile[*it]));
setDirtyFileInfo.erase(it++);
}
std::vector<const CBlockIndex*> vBlocks;
vBlocks.reserve(setDirtyBlockIndex.size());
for (std::set<CBlockIndex*>::iterator it = setDirtyBlockIndex.begin(); it != setDirtyBlockIndex.end(); ) {
vBlocks.push_back(*it);
setDirtyBlockIndex.erase(it++);
}
if (!m_blockman.m_block_tree_db->WriteBatchSync(vFiles, nLastBlockFile, vBlocks)) {
return AbortNode(state, "Failed to write to block index database"); return AbortNode(state, "Failed to write to block index database");
} }
} }
@ -2348,7 +2326,7 @@ void CChainState::ForceFlushStateToDisk()
void CChainState::PruneAndFlush() void CChainState::PruneAndFlush()
{ {
BlockValidationState state; BlockValidationState state;
fCheckForPruning = true; m_blockman.m_check_for_pruning = true;
if (!this->FlushStateToDisk(state, FlushStateMode::NONE)) { if (!this->FlushStateToDisk(state, FlushStateMode::NONE)) {
LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString()); LogPrintf("%s: failed to flush state (%s)\n", __func__, state.ToString());
} }
@ -3018,14 +2996,14 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
// are no blocks that meet the "have data and are not invalid per // are no blocks that meet the "have data and are not invalid per
// nStatus" criteria for inclusion in setBlockIndexCandidates). // nStatus" criteria for inclusion in setBlockIndexCandidates).
invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID; invalid_walk_tip->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(invalid_walk_tip); m_blockman.m_dirty_blockindex.insert(invalid_walk_tip);
setBlockIndexCandidates.erase(invalid_walk_tip); setBlockIndexCandidates.erase(invalid_walk_tip);
setBlockIndexCandidates.insert(invalid_walk_tip->pprev); setBlockIndexCandidates.insert(invalid_walk_tip->pprev);
if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) { if (invalid_walk_tip->pprev == to_mark_failed && (to_mark_failed->nStatus & BLOCK_FAILED_VALID)) {
// We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children // We only want to mark the last disconnected block as BLOCK_FAILED_VALID; its children
// need to be BLOCK_FAILED_CHILD instead. // need to be BLOCK_FAILED_CHILD instead.
to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD; to_mark_failed->nStatus = (to_mark_failed->nStatus ^ BLOCK_FAILED_VALID) | BLOCK_FAILED_CHILD;
setDirtyBlockIndex.insert(to_mark_failed); m_blockman.m_dirty_blockindex.insert(to_mark_failed);
} }
// Add any equal or more work headers to setBlockIndexCandidates // Add any equal or more work headers to setBlockIndexCandidates
@ -3055,7 +3033,7 @@ bool CChainState::InvalidateBlock(BlockValidationState& state, CBlockIndex* pind
// Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain // Mark pindex (or the last disconnected block) as invalid, even when it never was in the main chain
to_mark_failed->nStatus |= BLOCK_FAILED_VALID; to_mark_failed->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(to_mark_failed); m_blockman.m_dirty_blockindex.insert(to_mark_failed);
setBlockIndexCandidates.erase(to_mark_failed); setBlockIndexCandidates.erase(to_mark_failed);
m_chainman.m_failed_blocks.insert(to_mark_failed); m_chainman.m_failed_blocks.insert(to_mark_failed);
@ -3094,7 +3072,7 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
while (it != m_blockman.m_block_index.end()) { while (it != m_blockman.m_block_index.end()) {
if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) { if (!it->second->IsValid() && it->second->GetAncestor(nHeight) == pindex) {
it->second->nStatus &= ~BLOCK_FAILED_MASK; it->second->nStatus &= ~BLOCK_FAILED_MASK;
setDirtyBlockIndex.insert(it->second); m_blockman.m_dirty_blockindex.insert(it->second);
if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), it->second)) { if (it->second->IsValid(BLOCK_VALID_TRANSACTIONS) && it->second->HaveTxsDownloaded() && setBlockIndexCandidates.value_comp()(m_chain.Tip(), it->second)) {
setBlockIndexCandidates.insert(it->second); setBlockIndexCandidates.insert(it->second);
} }
@ -3111,7 +3089,7 @@ void CChainState::ResetBlockFailureFlags(CBlockIndex *pindex) {
while (pindex != nullptr) { while (pindex != nullptr) {
if (pindex->nStatus & BLOCK_FAILED_MASK) { if (pindex->nStatus & BLOCK_FAILED_MASK) {
pindex->nStatus &= ~BLOCK_FAILED_MASK; pindex->nStatus &= ~BLOCK_FAILED_MASK;
setDirtyBlockIndex.insert(pindex); m_blockman.m_dirty_blockindex.insert(pindex);
m_chainman.m_failed_blocks.erase(pindex); m_chainman.m_failed_blocks.erase(pindex);
} }
pindex = pindex->pprev; pindex = pindex->pprev;
@ -3131,7 +3109,7 @@ void CChainState::ReceivedBlockTransactions(const CBlock& block, CBlockIndex* pi
pindexNew->nStatus |= BLOCK_OPT_WITNESS; pindexNew->nStatus |= BLOCK_OPT_WITNESS;
} }
pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS); pindexNew->RaiseValidity(BLOCK_VALID_TRANSACTIONS);
setDirtyBlockIndex.insert(pindexNew); m_blockman.m_dirty_blockindex.insert(pindexNew);
if (pindexNew->pprev == nullptr || pindexNew->pprev->HaveTxsDownloaded()) { if (pindexNew->pprev == nullptr || pindexNew->pprev->HaveTxsDownloaded()) {
// If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS. // If pindexNew is the genesis block or all parents are BLOCK_VALID_TRANSACTIONS.
@ -3493,7 +3471,7 @@ bool ChainstateManager::AcceptBlockHeader(const CBlockHeader& block, BlockValida
CBlockIndex* invalid_walk = pindexPrev; CBlockIndex* invalid_walk = pindexPrev;
while (invalid_walk != failedit) { while (invalid_walk != failedit) {
invalid_walk->nStatus |= BLOCK_FAILED_CHILD; invalid_walk->nStatus |= BLOCK_FAILED_CHILD;
setDirtyBlockIndex.insert(invalid_walk); m_blockman.m_dirty_blockindex.insert(invalid_walk);
invalid_walk = invalid_walk->pprev; invalid_walk = invalid_walk->pprev;
} }
LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString()); LogPrint(BCLog::VALIDATION, "%s: %s prev block invalid\n", __func__, hash.ToString());
@ -3591,7 +3569,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
!ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) { !ContextualCheckBlock(block, state, m_params.GetConsensus(), pindex->pprev)) {
if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) { if (state.IsInvalid() && state.GetResult() != BlockValidationResult::BLOCK_MUTATED) {
pindex->nStatus |= BLOCK_FAILED_VALID; pindex->nStatus |= BLOCK_FAILED_VALID;
setDirtyBlockIndex.insert(pindex); m_blockman.m_dirty_blockindex.insert(pindex);
} }
return error("%s: %s", __func__, state.ToString()); return error("%s: %s", __func__, state.ToString());
} }
@ -3604,7 +3582,7 @@ bool CChainState::AcceptBlock(const std::shared_ptr<const CBlock>& pblock, Block
// Write block to history file // Write block to history file
if (fNewBlock) *fNewBlock = true; if (fNewBlock) *fNewBlock = true;
try { try {
FlatFilePos blockPos = SaveBlockToDisk(block, pindex->nHeight, m_chain, m_params, dbp); FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, pindex->nHeight, m_chain, m_params, dbp)};
if (blockPos.IsNull()) { if (blockPos.IsNull()) {
state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__)); state.Error(strprintf("%s: Failed to find position to write new block to disk", __func__));
return false; return false;
@ -3992,10 +3970,6 @@ void UnloadBlockIndex(CTxMemPool* mempool, ChainstateManager& chainman)
chainman.Unload(); chainman.Unload();
pindexBestHeader = nullptr; pindexBestHeader = nullptr;
if (mempool) mempool->clear(); if (mempool) mempool->clear();
vinfoBlockFile.clear();
nLastBlockFile = 0;
setDirtyBlockIndex.clear();
setDirtyFileInfo.clear();
g_versionbitscache.Clear(); g_versionbitscache.Clear();
for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) { for (int b = 0; b < VERSIONBITS_NUM_BITS; b++) {
warningcache[b].clear(); warningcache[b].clear();
@ -4039,9 +4013,10 @@ bool CChainState::LoadGenesisBlock()
try { try {
const CBlock& block = m_params.GenesisBlock(); const CBlock& block = m_params.GenesisBlock();
FlatFilePos blockPos = SaveBlockToDisk(block, 0, m_chain, m_params, nullptr); FlatFilePos blockPos{m_blockman.SaveBlockToDisk(block, 0, m_chain, m_params, nullptr)};
if (blockPos.IsNull()) if (blockPos.IsNull()) {
return error("%s: writing genesis block to disk failed", __func__); return error("%s: writing genesis block to disk failed", __func__);
}
CBlockIndex *pindex = m_blockman.AddToBlockIndex(block); CBlockIndex *pindex = m_blockman.AddToBlockIndex(block);
ReceivedBlockTransactions(block, pindex, blockPos); ReceivedBlockTransactions(block, pindex, blockPos);
} catch (const std::runtime_error& e) { } catch (const std::runtime_error& e) {
@ -4929,7 +4904,7 @@ bool ChainstateManager::PopulateAndValidateSnapshot(
index->nStatus |= BLOCK_OPT_WITNESS; index->nStatus |= BLOCK_OPT_WITNESS;
} }
setDirtyBlockIndex.insert(index); m_blockman.m_dirty_blockindex.insert(index);
// Changes to the block index will be flushed to disk after this call // Changes to the block index will be flushed to disk after this call
// returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is // returns in `ActivateSnapshot()`, when `MaybeRebalanceCaches()` is
// called, since we've added a snapshot chainstate and therefore will // called, since we've added a snapshot chainstate and therefore will

View file

@ -92,7 +92,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
{ {
// Cap last block file size, and mine new block in a new block file. // Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip(); CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; WITH_LOCK(::cs_main, m_node.chainman->m_blockman.GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE);
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip(); CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();
@ -193,7 +193,7 @@ BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup)
{ {
// Cap last block file size, and mine new block in a new block file. // Cap last block file size, and mine new block in a new block file.
CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip(); CBlockIndex* oldTip = m_node.chainman->ActiveChain().Tip();
GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; WITH_LOCK(::cs_main, m_node.chainman->m_blockman.GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE);
CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey()));
CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip(); CBlockIndex* newTip = m_node.chainman->ActiveChain().Tip();