42#include <validation.h>
54#include <system_error>
55#include <unordered_map>
92void BlockTreeDB::WriteBatchSync(
const std::vector<std::pair<int, const CBlockFileInfo*>>& fileInfo,
int nLastFile,
const std::vector<const CBlockIndex*>& blockinfo)
95 for (
const auto& [file, info] : fileInfo) {
116 fValue = ch == uint8_t{
'1'};
123 std::unique_ptr<CDBIterator> pcursor(
NewIterator());
127 while (pcursor->Valid()) {
128 if (interrupt)
return false;
129 std::pair<uint8_t, uint256> key;
132 if (pcursor->GetValue(diskindex)) {
137 pindexNew->nFile = diskindex.nFile;
138 pindexNew->nDataPos = diskindex.nDataPos;
139 pindexNew->nUndoPos = diskindex.nUndoPos;
145 pindexNew->nStatus = diskindex.nStatus;
146 pindexNew->
nTx = diskindex.
nTx;
149 LogError(
"%s: CheckProofOfWork failed: %s\n", __func__, pindexNew->
ToString());
155 LogError(
"%s: failed to read value\n", __func__);
187 if (pa < pb)
return false;
188 if (pa > pb)
return true;
199std::vector<CBlockIndex*> BlockManager::GetAllBlockIndices()
202 std::vector<CBlockIndex*> rv;
203 rv.reserve(m_block_index.size());
204 for (
auto& [
_, block_index] : m_block_index) {
205 rv.push_back(&block_index);
213 BlockMap::iterator it = m_block_index.find(hash);
214 return it == m_block_index.end() ? nullptr : &it->second;
220 BlockMap::const_iterator it = m_block_index.find(hash);
221 return it == m_block_index.end() ? nullptr : &it->second;
228 auto [mi, inserted] = m_block_index.try_emplace(block.
GetHash(), block);
240 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
241 if (miPrev != m_block_index.end()) {
242 pindexNew->
pprev = &(*miPrev).second;
250 best_header = pindexNew;
264 for (
auto it = range.first; it != range.second; ++it) {
265 if (it->second == block)
return;
274 for (
auto& entry : m_block_index) {
276 if (pindex->nFile == fileNumber) {
277 pindex->nStatus &= ~BLOCK_HAVE_DATA;
278 pindex->nStatus &= ~BLOCK_HAVE_UNDO;
280 pindex->nDataPos = 0;
281 pindex->nUndoPos = 0;
289 while (range.first != range.second) {
290 std::multimap<CBlockIndex*, CBlockIndex*>::iterator _it = range.first;
292 if (_it->second == pindex) {
304 std::set<int>& setFilesToPrune,
305 int nManualPruneHeight,
315 const auto [min_block_to_prune, last_block_can_prune] = chain.GetPruneRange(nManualPruneHeight);
318 for (
int fileNumber = 0; fileNumber < this->
MaxBlockfileNum(); fileNumber++) {
320 if (fileinfo.nSize == 0 || fileinfo.nHeightLast > (
unsigned)last_block_can_prune || fileinfo.nHeightFirst < (unsigned)min_block_to_prune) {
325 setFilesToPrune.insert(fileNumber);
328 LogInfo(
"[%s] Prune (Manual): prune_height=%d removed %d blk/rev pairs",
329 chain.GetRole(), last_block_can_prune,
count);
333 std::set<int>& setFilesToPrune,
347 const auto target = std::max(
349 const uint64_t target_sync_height = chainman.m_best_header->nHeight;
358 const auto [min_block_to_prune, last_block_can_prune] = chain.GetPruneRange(last_prune);
360 uint64_t nCurrentUsage = CalculateCurrentUsage();
365 uint64_t nBytesToPrune;
368 if (nCurrentUsage + nBuffer >= target) {
376 static constexpr uint64_t average_block_size = 1000000;
377 const uint64_t remaining_blocks = target_sync_height - chain_tip_height;
378 nBuffer += average_block_size * remaining_blocks;
381 for (
int fileNumber = 0; fileNumber < this->
MaxBlockfileNum(); fileNumber++) {
383 nBytesToPrune = fileinfo.nSize + fileinfo.nUndoSize;
385 if (fileinfo.nSize == 0) {
389 if (nCurrentUsage + nBuffer < target) {
395 if (fileinfo.nHeightLast > (
unsigned)last_block_can_prune || fileinfo.nHeightFirst < (unsigned)min_block_to_prune) {
401 setFilesToPrune.insert(fileNumber);
402 nCurrentUsage -= nBytesToPrune;
407 LogDebug(
BCLog::PRUNE,
"[%s] target=%dMiB actual=%dMiB diff=%dMiB min_height=%d max_prune_height=%d removed %d blk/rev pairs\n",
408 chain.GetRole(), target / 1_MiB, nCurrentUsage / 1_MiB,
409 (int64_t(target) - int64_t(nCurrentUsage)) / int64_t(1_MiB),
410 min_block_to_prune, last_block_can_prune,
count);
413void BlockManager::UpdatePruneLock(
const std::string&
name,
const PruneLockInfo& lock_info) {
415 m_prune_locks[
name] = lock_info;
418bool BlockManager::DeletePruneLock(
const std::string&
name)
421 return m_prune_locks.erase(
name) > 0;
432 const auto [mi, inserted]{m_block_index.try_emplace(hash)};
442 if (!m_block_tree_db->LoadBlockIndexGuts(
447 if (snapshot_blockhash) {
449 if (!maybe_au_data) {
461 LogInfo(
"[snapshot] set m_chain_tx_count=%d for %s", au_data.
m_chain_tx_count, snapshot_blockhash->ToString());
472 std::vector<CBlockIndex*> vSortedByHeight{GetAllBlockIndices()};
473 std::sort(vSortedByHeight.begin(), vSortedByHeight.end(),
479 if (previous_index && pindex->nHeight > previous_index->nHeight + 1) {
480 LogError(
"%s: block index is non-contiguous, index of height %d missing\n", __func__, previous_index->nHeight + 1);
483 previous_index = pindex;
484 pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) +
GetBlockProof(*pindex);
485 pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime);
491 if (pindex->nTx > 0) {
494 pindex->GetBlockHash() == *snapshot_blockhash) {
496 Assert(pindex->m_chain_tx_count > 0);
497 }
else if (pindex->pprev->m_chain_tx_count > 0) {
498 pindex->m_chain_tx_count = pindex->pprev->m_chain_tx_count + pindex->nTx;
500 pindex->m_chain_tx_count = 0;
506 pindex->m_chain_tx_count = pindex->nTx;
529void BlockManager::WriteBlockIndexDB()
532 std::vector<std::pair<int, const CBlockFileInfo*>> vFiles;
538 std::vector<const CBlockIndex*> vBlocks;
541 vBlocks.push_back(*it);
545 m_block_tree_db->WriteBatchSync(vFiles, max_blockfile, vBlocks);
548bool BlockManager::LoadBlockIndexDB(
const std::optional<uint256>& snapshot_blockhash)
554 int max_blockfile_num{0};
557 m_block_tree_db->ReadLastBlockFile(max_blockfile_num);
559 LogInfo(
"Loading block index db: last block file = %i", max_blockfile_num);
560 for (
int nFile = 0; nFile <= max_blockfile_num; nFile++) {
564 for (
int nFile = max_blockfile_num + 1;
true; nFile++) {
566 if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) {
574 LogInfo(
"Checking all blk files are present...");
575 std::set<int> setBlkDataFiles;
576 for (
const auto& [
_, block_index] : m_block_index) {
578 setBlkDataFiles.insert(block_index.nFile);
581 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) {
597 m_block_tree_db->ReadFlag(
"prunedblockfiles",
m_have_pruned);
599 LogInfo(
"Loading block index db: Block files have previously been pruned");
603 bool fReindexing =
false;
604 m_block_tree_db->ReadReindexing(fReindexing);
610void BlockManager::ScanAndUnlinkAlreadyPrunedFiles()
618 std::set<int> block_files_to_prune;
619 for (
int file_number = 0; file_number < max_blockfile; file_number++) {
621 block_files_to_prune.insert(file_number);
628bool BlockManager::IsBlockPruned(
const CBlockIndex& block)
const
638 assert((last_block->nStatus & status_mask) == status_mask);
639 while (last_block->
pprev && ((last_block->
pprev->nStatus & status_mask) == status_mask)) {
642 if (last_block == lower_block)
return *lower_block;
647 last_block = last_block->
pprev;
649 assert(last_block !=
nullptr);
655 if (!(upper_block.nStatus & block_status))
return false;
656 const auto& first_block = GetFirstBlock(upper_block, block_status, &lower_block);
662 return first_block.pprev && first_block.pprev->nStatus &
flags;
664 return &first_block == &lower_block;
675 std::map<std::string, fs::path> mapBlockFiles;
680 LogInfo(
"Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune");
681 for (fs::directory_iterator it(
m_opts.
blocks_dir); it != fs::directory_iterator(); it++) {
683 if (fs::is_regular_file(*it) &&
684 path.length() == 12 &&
685 path.ends_with(
".dat"))
687 if (path.starts_with(
"blk")) {
688 mapBlockFiles[path.substr(3, 5)] = it->path();
689 }
else if (path.starts_with(
"rev")) {
699 int nContigCounter = 0;
700 for (
const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
701 if (LocaleIndependentAtoi<int>(item.first) == nContigCounter) {
722 LogError(
"OpenUndoFile failed for %s while reading block undo", pos.ToString());
732 verifier >> blockundo;
735 filein >> hashChecksum;
738 if (hashChecksum != verifier.GetHash()) {
739 LogError(
"Checksum mismatch at %s while reading block undo", pos.ToString());
742 }
catch (
const std::exception& e) {
743 LogError(
"Deserialize or I/O error - %s at %s while reading block undo", e.what(), pos.ToString());
760bool BlockManager::FlushBlockFile(
int blockfile_num,
bool fFinalize,
bool finalize_undo)
781 if (!fFinalize || finalize_undo) {
797bool BlockManager::FlushChainstateBlockFile(
int tip_height)
805 return FlushBlockFile(cursor->file_num,
false,
false);
811uint64_t BlockManager::CalculateCurrentUsage()
816 retval += file.nSize + file.nUndoSize;
824 for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
828 if (removed_blockfile || removed_undofile) {
850FlatFilePos BlockManager::FindNextBlockPos(
unsigned int nAddSize,
unsigned int nHeight, uint64_t nTime)
855 if (!m_blockfile_cursors[chain_type]) {
859 m_blockfile_cursors[chain_type] = new_cursor;
862 const int last_blockfile = m_blockfile_cursors[chain_type]->file_num;
864 int nFile = last_blockfile;
869 bool finalize_undo =
false;
874 max_blockfile_size = 0x10000;
875 if (nAddSize >= max_blockfile_size) {
877 max_blockfile_size = nAddSize + 1;
880 assert(nAddSize < max_blockfile_size);
887 Assert(m_blockfile_cursors[chain_type])->undo_height);
892 m_blockfile_cursors[chain_type] = BlockfileCursor{nFile};
902 if (nFile != last_blockfile) {
913 if (!FlushBlockFile(last_blockfile,
true, finalize_undo)) {
915 "Failed to flush previous block file %05i (finalize=1, finalize_undo=%i) before opening new block file %05i\n",
916 last_blockfile, finalize_undo, nFile);
919 m_blockfile_cursors[chain_type] = BlockfileCursor{nFile};
944 auto& cursor{m_blockfile_cursors[chain_type]};
945 if (!cursor || cursor->file_num < pos.
nFile) {
946 m_blockfile_cursors[chain_type] = BlockfileCursor{pos.
nFile};
951 const int nFile = pos.
nFile;
985 auto& cursor = *
Assert(m_blockfile_cursors[type]);
990 const auto blockundo_size{
static_cast<uint32_t
>(
GetSerializeSize(blockundo))};
992 LogError(
"FindUndoPos failed for %s while writing block undo", pos.
ToString());
999 LogError(
"OpenUndoFile failed for %s while writing block undo", pos.
ToString());
1013 fileout << blockundo << hasher.GetHash();
1019 if (file.fclose() != 0) {
1038 }
else if (pos.
nFile == cursor.file_num && block.
nHeight > cursor.undo_height) {
1039 cursor.undo_height = block.
nHeight;
1042 block.nUndoPos = pos.
nPos;
1063 }
catch (
const std::exception& e) {
1064 LogError(
"Deserialize or I/O error - %s at %s while reading block", e.what(), pos.
ToString());
1068 const auto block_hash{block.
GetHash()};
1072 LogError(
"Errors in block header at %s while reading block", pos.
ToString());
1078 LogError(
"Errors in block solution at %s while reading block", pos.
ToString());
1082 if (expected_hash && block_hash != *expected_hash) {
1083 LogError(
"GetHash() doesn't match index at %s while reading block (%s != %s)",
1084 pos.
ToString(), block_hash.ToString(), expected_hash->ToString());
1103 LogError(
"Failed for %s while reading raw block storage header", pos.
ToString());
1107 if (filein.IsNull()) {
1108 LogError(
"OpenBlockFile failed for %s while reading raw block", pos.
ToString());
1114 unsigned int blk_size;
1116 filein >> blk_start >> blk_size;
1118 if (blk_start !=
GetParams().MessageStart()) {
1119 LogError(
"Block magic mismatch for %s: %s versus expected %s while reading raw block",
1125 LogError(
"Block data is larger than maximum deserialization size for %s: %s versus %s while reading raw block",
1131 const auto [offset, size]{*block_part};
1135 filein.seek(offset, SEEK_CUR);
1139 std::vector<std::byte>
data(blk_size);
1142 }
catch (
const std::exception& e) {
1143 LogError(
"Read from block file failed: %s for %s while reading raw block", e.what(), pos.
ToString());
1154 LogError(
"FindNextBlockPos failed for %s while writing block", pos.
ToString());
1158 if (file.IsNull()) {
1159 LogError(
"OpenBlockFile failed for %s while writing block", pos.
ToString());
1173 if (file.fclose() != 0) {
1186 std::array<std::byte, Obfuscation::KEY_SIZE> obfuscation{};
1191 bool first_run =
true;
1192 for (
const auto& entry : fs::directory_iterator(opts.
blocks_dir)) {
1194 if (!entry.is_regular_file() || !path.starts_with(
'.')) {
1200 if (opts.
use_xor && first_run) {
1206 const fs::path xor_key_path{opts.
blocks_dir /
"xor.dat"};
1210 xor_key_file >> obfuscation;
1220 xor_key_file << obfuscation;
1221 if (xor_key_file.fclose() != 0) {
1222 throw std::runtime_error{
strprintf(
"Error closing XOR key file %s: %s",
1228 if (!opts.
use_xor && obfuscation !=
decltype(obfuscation){}) {
1229 throw std::runtime_error{
1230 strprintf(
"The blocksdir XOR-key can not be disabled when a random key was already stored! "
1231 "Stored key: '%s', stored path: '%s'.",
1240 : m_prune_mode{opts.prune_target > 0},
1242 m_opts{
std::move(opts)},
1245 m_interrupt{interrupt}
1250 m_block_tree_db->WriteReindexing(
true);
1289 std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
1291 for (
int nFile{0}; nFile < total_files; ++nFile) {
1294 if (file.IsNull()) {
1297 LogInfo(
"Reindexing block file blk%05u.dat (%d%% complete)...", (
unsigned int)nFile, nFile * 100 / total_files);
1300 LogInfo(
"Interrupt requested. Exit reindexing.");
1306 LogInfo(
"Reindexing finished");
1312 for (
const fs::path& path : import_paths) {
1314 if (!file.IsNull()) {
1318 LogInfo(
"Interrupt requested. Exit block importing.");
1327 if (
auto result = chainman.ActivateBestChains(); !result) {
1337 default: os.setstate(std::ios_base::failbit);
void CheckBlockDataAvailability(BlockManager &blockman, const CBlockIndex &blockindex, bool check_for_undo)
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous.
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
@ BLOCK_HAVE_DATA
full block available in blk*.dat
@ BLOCK_FAILED_CHILD
Unused flag that was previously set when descending from failed block.
@ BLOCK_FAILED_VALID
stage after last reached validness failed
arith_uint256 GetBlockProof(const CBlockIndex &block)
Compute how much work a block index entry corresponds to.
static constexpr int32_t SEQ_ID_INIT_FROM_DISK
#define Assert(val)
Identity function.
#define Assume(val)
Assume is the identity function.
Non-refcounted RAII wrapper for FILE*.
Wrapper that buffers reads from an underlying stream.
Wrapper that buffers writes to an underlying stream.
The block chain is a tree shaped structure starting with the genesis block at the root,...
std::string ToString() const
CBlockIndex * pprev
pointer to the index of the predecessor of this block
uint64_t m_chain_tx_count
(memory only) Number of transactions in the chain up to and including this block.
void BuildSkip()
Build the skiplist pointer for this entry.
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
uint256 GetBlockHash() const
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(
Raise the validity level of this block index entry.
unsigned int nTx
Number of transactions in this block.
int32_t nVersion
block header
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
Undo information for a CBlock.
int Height() const
Return the maximal height in the chain.
const MessageStartChars & MessageStart() const
std::optional< AssumeutxoData > AssumeutxoForBlockhash(const uint256 &blockhash) const
uint64_t PruneAfterHeight() const
Batch of changes queued to be written to a CDBWrapper.
void Write(const K &key, const V &value)
bool Read(const K &key, V &value) const
CDBIterator * NewIterator()
bool Exists(const K &key) const
void Erase(const K &key, bool fSync=false)
void WriteBatch(CDBBatch &batch, bool fSync=false)
void Write(const K &key, const V &value, bool fSync=false)
Used to marshal pointers into hashes for db storage.
uint256 ConstructBlockHash() const
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CChain m_chain
The current chain of blockheaders we consult and build on.
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
Chainstate * HistoricalChainstate() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Return historical chainstate targeting a specific block, if any.
bool IsInitialBlockDownload() const noexcept
Check whether we are doing an initial block download (synchronizing from disk or network)
kernel::Notifications & GetNotifications() const
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
const util::SignalInterrupt & m_interrupt
void LoadExternalBlockFile(AutoFile &file_in, FlatFilePos *dbp=nullptr, std::multimap< uint256, FlatFilePos > *blocks_with_unknown_parent=nullptr)
Import blocks from an external file.
const CChainParams & GetParams() const
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
void fillrand(std::span< std::byte > output) noexcept
Fill a byte span with random bytes.
FlatFileSeq represents a sequence of numbered files storing raw data.
FILE * Open(const FlatFilePos &pos, bool read_only=false) const
Open a handle to the file at the given position.
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
bool Flush(const FlatFilePos &pos, bool finalize=false) const
Commit a file to disk, and optionally truncate off extra pre-allocated bytes if final.
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space) const
Allocate additional space in a file after the given starting position.
Reads data from an underlying stream, while hashing the read data.
A writer stream (for serialization) that computes a 256-bit hash.
Minimal stream for reading from an existing byte array by std::span.
constexpr bool IsNull() const
void WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * > > &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
bool ReadLastBlockFile(int &nFile)
void WriteReindexing(bool fReindexing)
bool ReadFlag(const std::string &name, bool &fValue)
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
void ReadReindexing(bool &fReindexing)
void WriteFlag(const std::string &name, bool fValue)
uint32_t nSize
number of used bytes of block file
std::string ToString() const
uint64_t nTimeFirst
earliest time of block in file
uint64_t nTimeLast
latest time of block in file
uint32_t nHeightFirst
lowest height of block in file
uint32_t nBlocks
number of blocks stored in file
uint32_t nHeightLast
highest height of block in file
virtual void fatalError(const bilingual_str &message)
The fatal error notification is sent to notify the user when an error occurs in kernel code that can'...
virtual void flushError(const bilingual_str &message)
The flush error notification is sent to notify the user that an error occurred while flushing block d...
const kernel::BlockManagerOpts m_opts
std::set< int > m_dirty_fileinfo
Dirty block file entries.
const FlatFileSeq m_undo_file_seq
const CChainParams & GetParams() const
void PruneOneBlockFile(int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
void FindFilesToPrune(std::set< int > &setFilesToPrune, int last_prune, const Chainstate &chain, ChainstateManager &chainman)
Prune block and undo files (blk???.dat and rev???.dat) so that the disk space used is less than a use...
const Obfuscation m_obfuscation
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool ReadBlockUndo(CBlockUndo &blockundo, const CBlockIndex &index) const
int MaxBlockfileNum() const EXCLUSIVE_LOCKS_REQUIRED(
CBlockFileInfo *GetBlockFileInfo(size_t n) EXCLUSIVE_LOCKS_REQUIRED(bool WriteBlockUndo(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex &block) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePos WriteBlock(const CBlock &block, int nHeight) EXCLUSIVE_LOCKS_REQUIRED(void UpdateBlockInfo(const CBlock &block, unsigned int nHeight, const FlatFilePos &pos) EXCLUSIVE_LOCKS_REQUIRED(bool IsPruneMode() const
Get block file info entry for one block file.
BlockfileType BlockfileTypeForHeight(int height)
std::atomic_bool m_blockfiles_indexed
Whether all blockfiles have been added to the block tree database.
std::vector< CBlockIndex * > GetAllBlockIndices() EXCLUSIVE_LOCKS_REQUIRED(std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
const Consensus::Params & GetConsensus() const
BlockManager(const util::SignalInterrupt &interrupt, Options opts)
std::set< CBlockIndex * > m_dirty_blockindex
Dirty block index entries.
fs::path GetBlockPosFilename(const FlatFilePos &pos) const
Translation to a filesystem path.
uint64_t GetPruneTarget() const
Attempt to stay below this number of bytes of block files.
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune) const
Actually unlink the specified files.
void WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(bool LoadBlockIndexDB(const std::optional< uint256 > &snapshot_blockhash) EXCLUSIVE_LOCKS_REQUIRED(void ScanAndUnlinkAlreadyPrunedFiles() EXCLUSIVE_LOCKS_REQUIRED(CBlockIndex * AddToBlockIndex(const CBlockHeader &block, CBlockIndex *&best_header) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove any pruned block & undo files that are still on disk.
void AddUnlinkedBlock(CBlockIndex *block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool FlushBlockFile(int blockfile_num, bool fFinalize, bool finalize_undo) EXCLUSIVE_LOCKS_REQUIRED(bool FlushUndoFile(int block_file, bool finalize=false)
Return false if block file or undo file flushing fails.
const util::SignalInterrupt & m_interrupt
ReadRawBlockResult ReadRawBlock(const FlatFilePos &pos, std::optional< std::pair< size_t, size_t > > block_part=std::nullopt) const
const FlatFileSeq m_block_file_seq
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
bool ReadBlock(CBlock &block, const FlatFilePos &pos, const std::optional< uint256 > &expected_hash) const
Functions for disk access for blocks.
bool m_check_for_pruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted.
void CleanupBlockRevFiles() const
std::atomic< bool > m_importing
bool IsBlockPruned(const CBlockIndex &block) const EXCLUSIVE_LOCKS_REQUIRED(void UpdatePruneLock(const std::string &name, const PruneLockInfo &lock_info) EXCLUSIVE_LOCKS_REQUIRED(bool DeletePruneLock(const std::string &name) EXCLUSIVE_LOCKS_REQUIRED(AutoFile OpenBlockFile(const FlatFilePos &pos, bool fReadOnly) const
Check whether the block associated with this index entry is pruned or not.
std::vector< CBlockFileInfo > m_blockfile_info
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, const Chainstate &chain)
bool LoadBlockIndex(const std::optional< uint256 > &snapshot_blockhash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
FlatFilePos FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime) EXCLUSIVE_LOCKS_REQUIRED(bool FlushChainstateBlockFile(int tip_height) EXCLUSIVE_LOCKS_REQUIRED(bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize) EXCLUSIVE_LOCKS_REQUIRED(AutoFile OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false) const
Helper function performing various preparations before a block can be saved to disk: Returns the corr...
std::optional< int > m_snapshot_height
The height of the base block of an assumeutxo snapshot, if one is in use.
uint64_t CalculateCurrentUsage() EXCLUSIVE_LOCKS_REQUIRED(bool CheckBlockDataAvailability(const CBlockIndex &upper_block, const CBlockIndex &lower_block, BlockStatus block_status=BLOCK_HAVE_DATA) EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex &GetFirstBlock(const CBlockIndex &upper_block LIFETIMEBOUND, uint32_t status_mask, const CBlockIndex *lower_block LIFETIMEBOUND=nullptr) const EXCLUSIVE_LOCKS_REQUIRED(boo m_have_pruned)
Calculate the amount of disk space the block & undo files currently use.
ImportingNow(std::atomic< bool > &importing)
std::atomic< bool > & m_importing
The util::Expected class provides a standard way for low-level functions to return either error value...
Helper class that manages an interrupt flag, and allows a thread or signal to interrupt another threa...
The util::Unexpected class represents an unexpected value stored in util::Expected.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static bool exists(const path &p)
static std::string PathToString(const path &path)
Convert path object to a byte string.
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
is a home for simple enum and struct type definitions that can be used internally by functions in the...
#define LogDebug(category,...)
std::array< uint8_t, 4 > MessageStartChars
FILE * fopen(const fs::path &p, const char *mode)
static constexpr uint8_t DB_REINDEX_FLAG
static constexpr uint8_t DB_FLAG
static constexpr uint8_t DB_BLOCK_INDEX
static constexpr uint8_t DB_LAST_BLOCK
static constexpr uint8_t DB_BLOCK_FILES
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
static auto InitBlocksdirXorKey(const BlockManager::Options &opts)
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
static constexpr uint32_t STORAGE_HEADER_BYTES
Size of header written by WriteBlock before a serialized CBlock (8 bytes)
std::ostream & operator<<(std::ostream &os, const BlockfileType &type)
static constexpr uint32_t UNDO_DATA_DISK_OVERHEAD
Total overhead when writing undo data: header (8 bytes) plus checksum (32 bytes)
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
void ImportBlocks(ChainstateManager &chainman, std::span< const fs::path > import_paths)
bilingual_str ErrorString(const Result< T > &result)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
T SaturatingAdd(const T i, const T j) noexcept
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params ¶ms)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
static constexpr TransactionSerParams TX_WITH_WITNESS
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
uint64_t GetSerializeSize(const T &t)
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
Holds configuration for use during UTXO snapshot load and validation.
uint64_t m_chain_tx_count
Used to populate the m_chain_tx_count value, which is used during BlockManager::LoadBlockIndex().
Parameters that influence chain consensus.
bool wipe_data
If true, remove all existing data.
std::string ToString() const
An options struct for BlockManager, more ergonomically referred to as BlockManager::Options due to th...
Notifications & notifications
const fs::path blocks_dir
DBParams block_tree_db_params
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string SysErrorString(int err)
Return system error string from errno value.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
consteval auto _(util::TranslatedLiteral str)
std::string FormatISO8601Date(int64_t nTime)
bool FatalError(Notifications ¬ifications, BlockValidationState &state, const bilingual_str &message)
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES