40 #include <util/time.h> 42 #include <validation.h> 54 #include <system_error> 55 #include <unordered_map> 92 void 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;
199 std::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;
263 for (
auto& entry : m_block_index) {
265 if (pindex->nFile == fileNumber) {
269 pindex->nDataPos = 0;
270 pindex->nUndoPos = 0;
278 while (range.first != range.second) {
279 std::multimap<CBlockIndex*, CBlockIndex*>::iterator _it = range.first;
281 if (_it->second == pindex) {
293 std::set<int>& setFilesToPrune,
294 int nManualPruneHeight,
304 const auto [min_block_to_prune, last_block_can_prune] = chain.GetPruneRange(nManualPruneHeight);
307 for (
int fileNumber = 0; fileNumber < this->
MaxBlockfileNum(); fileNumber++) {
309 if (fileinfo.nSize == 0 || fileinfo.nHeightLast > (
unsigned)last_block_can_prune || fileinfo.nHeightFirst < (unsigned)min_block_to_prune) {
314 setFilesToPrune.insert(fileNumber);
317 LogInfo(
"[%s] Prune (Manual): prune_height=%d removed %d blk/rev pairs",
318 chain.GetRole(), last_block_can_prune,
count);
322 std::set<int>& setFilesToPrune,
336 const auto target = std::max(
338 const uint64_t target_sync_height = chainman.m_best_header->nHeight;
347 const auto [min_block_to_prune, last_block_can_prune] = chain.GetPruneRange(last_prune);
354 uint64_t nBytesToPrune;
357 if (nCurrentUsage + nBuffer >= target) {
365 static constexpr uint64_t average_block_size = 1000000;
366 const uint64_t remaining_blocks = target_sync_height - chain_tip_height;
367 nBuffer += average_block_size * remaining_blocks;
370 for (
int fileNumber = 0; fileNumber < this->
MaxBlockfileNum(); fileNumber++) {
372 nBytesToPrune = fileinfo.nSize + fileinfo.nUndoSize;
374 if (fileinfo.nSize == 0) {
378 if (nCurrentUsage + nBuffer < target) {
384 if (fileinfo.nHeightLast > (
unsigned)last_block_can_prune || fileinfo.nHeightFirst < (unsigned)min_block_to_prune) {
390 setFilesToPrune.insert(fileNumber);
391 nCurrentUsage -= nBytesToPrune;
396 LogDebug(
BCLog::PRUNE,
"[%s] target=%dMiB actual=%dMiB diff=%dMiB min_height=%d max_prune_height=%d removed %d blk/rev pairs\n",
397 chain.GetRole(), target / 1024 / 1024, nCurrentUsage / 1024 / 1024,
398 (int64_t(target) - int64_t(nCurrentUsage)) / 1024 / 1024,
399 min_block_to_prune, last_block_can_prune,
count);
402 void BlockManager::UpdatePruneLock(
const std::string&
name,
const PruneLockInfo& lock_info) {
404 m_prune_locks[
name] = lock_info;
415 const auto [mi, inserted]{m_block_index.try_emplace(hash)};
425 if (!m_block_tree_db->LoadBlockIndexGuts(
430 if (snapshot_blockhash) {
432 if (!maybe_au_data) {
444 LogInfo(
"[snapshot] set m_chain_tx_count=%d for %s", au_data.
m_chain_tx_count, snapshot_blockhash->ToString());
455 std::vector<CBlockIndex*> vSortedByHeight{GetAllBlockIndices()};
456 std::sort(vSortedByHeight.begin(), vSortedByHeight.end(),
462 if (previous_index && pindex->nHeight > previous_index->nHeight + 1) {
463 LogError(
"%s: block index is non-contiguous, index of height %d missing\n", __func__, previous_index->nHeight + 1);
466 previous_index = pindex;
467 pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) +
GetBlockProof(*pindex);
468 pindex->nTimeMax = (pindex->pprev ? std::max(pindex->pprev->nTimeMax, pindex->nTime) : pindex->nTime);
474 if (pindex->nTx > 0) {
477 pindex->GetBlockHash() == *snapshot_blockhash) {
479 Assert(pindex->m_chain_tx_count > 0);
480 }
else if (pindex->pprev->m_chain_tx_count > 0) {
481 pindex->m_chain_tx_count = pindex->pprev->m_chain_tx_count + pindex->nTx;
483 pindex->m_chain_tx_count = 0;
487 pindex->m_chain_tx_count = pindex->nTx;
510 void BlockManager::WriteBlockIndexDB()
513 std::vector<std::pair<int, const CBlockFileInfo*>> vFiles;
519 std::vector<const CBlockIndex*> vBlocks;
522 vBlocks.push_back(*it);
526 m_block_tree_db->WriteBatchSync(vFiles, max_blockfile, vBlocks);
529 bool BlockManager::LoadBlockIndexDB(
const std::optional<uint256>& snapshot_blockhash)
534 int max_blockfile_num{0};
537 m_block_tree_db->ReadLastBlockFile(max_blockfile_num);
539 LogInfo(
"Loading block index db: last block file = %i", max_blockfile_num);
540 for (
int nFile = 0; nFile <= max_blockfile_num; nFile++) {
544 for (
int nFile = max_blockfile_num + 1;
true; nFile++) {
546 if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) {
554 LogInfo(
"Checking all blk files are present...");
555 std::set<int> setBlkDataFiles;
556 for (
const auto& [
_, block_index] : m_block_index) {
558 setBlkDataFiles.insert(block_index.nFile);
561 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) {
578 m_block_tree_db->ReadFlag(
"prunedblockfiles",
m_have_pruned);
580 LogInfo(
"Loading block index db: Block files have previously been pruned");
584 bool fReindexing =
false;
585 m_block_tree_db->ReadReindexing(fReindexing);
591 void BlockManager::ScanAndUnlinkAlreadyPrunedFiles()
599 std::set<int> block_files_to_prune;
600 for (
int file_number = 0; file_number < max_blockfile; file_number++) {
602 block_files_to_prune.insert(file_number);
609 bool BlockManager::IsBlockPruned(
const CBlockIndex& block)
const 619 assert((last_block->nStatus & status_mask) == status_mask);
620 while (last_block->
pprev && ((last_block->
pprev->nStatus & status_mask) == status_mask)) {
623 if (last_block == lower_block)
return *lower_block;
628 last_block = last_block->
pprev;
630 assert(last_block !=
nullptr);
636 if (!(upper_block.nStatus & block_status))
return false;
637 const auto& first_block = GetFirstBlock(upper_block, block_status, &lower_block);
643 return first_block.pprev && first_block.pprev->nStatus &
flags;
645 return &first_block == &lower_block;
656 std::map<std::string, fs::path> mapBlockFiles;
661 LogInfo(
"Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune");
662 for (fs::directory_iterator it(
m_opts.
blocks_dir); it != fs::directory_iterator(); it++) {
664 if (fs::is_regular_file(*it) &&
665 path.length() == 12 &&
666 path.ends_with(
".dat"))
668 if (path.starts_with(
"blk")) {
669 mapBlockFiles[path.substr(3, 5)] = it->path();
670 }
else if (path.starts_with(
"rev")) {
680 int nContigCounter = 0;
681 for (
const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
682 if (LocaleIndependentAtoi<int>(item.first) == nContigCounter) {
704 LogError(
"OpenUndoFile failed for %s while reading block undo", pos.ToString());
714 verifier >> blockundo;
717 filein >> hashChecksum;
720 if (hashChecksum != verifier.GetHash()) {
721 LogError(
"Checksum mismatch at %s while reading block undo", pos.ToString());
724 }
catch (
const std::exception& e) {
725 LogError(
"Deserialize or I/O error - %s at %s while reading block undo", e.what(), pos.ToString());
763 if (!fFinalize || finalize_undo) {
799 retval += file.nSize + file.nUndoSize;
807 for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
811 if (removed_blockfile || removed_undofile) {
839 if (!m_blockfile_cursors[chain_type]) {
843 m_blockfile_cursors[chain_type] = new_cursor;
846 const int last_blockfile = m_blockfile_cursors[chain_type]->file_num;
848 int nFile = last_blockfile;
853 bool finalize_undo =
false;
858 max_blockfile_size = 0x10000;
859 if (nAddSize >= max_blockfile_size) {
861 max_blockfile_size = nAddSize + 1;
864 assert(nAddSize < max_blockfile_size);
871 Assert(m_blockfile_cursors[chain_type])->undo_height);
886 if (nFile != last_blockfile) {
899 "Failed to flush previous block file %05i (finalize=1, finalize_undo=%i) before opening new block file %05i\n",
900 last_blockfile, finalize_undo, nFile);
929 auto& cursor{m_blockfile_cursors[chain_type]};
930 if (!cursor || cursor->file_num < pos.
nFile) {
936 const int nFile = pos.
nFile;
976 const auto blockundo_size{
static_cast<uint32_t
>(
GetSerializeSize(blockundo))};
978 LogError(
"FindUndoPos failed for %s while writing block undo", pos.
ToString());
985 LogError(
"OpenUndoFile failed for %s while writing block undo", pos.
ToString());
999 fileout << blockundo << hasher.GetHash();
1005 if (file.fclose() != 0) {
1024 }
else if (pos.
nFile == cursor.file_num && block.
nHeight > cursor.undo_height) {
1025 cursor.undo_height = block.
nHeight;
1028 block.nUndoPos = pos.
nPos;
1049 }
catch (
const std::exception& e) {
1050 LogError(
"Deserialize or I/O error - %s at %s while reading block", e.what(), pos.
ToString());
1054 const auto block_hash{block.
GetHash()};
1058 LogError(
"Errors in block header at %s while reading block", pos.
ToString());
1064 LogError(
"Errors in block solution at %s while reading block", pos.
ToString());
1068 if (expected_hash && block_hash != *expected_hash) {
1069 LogError(
"GetHash() doesn't match index at %s while reading block (%s != %s)",
1070 pos.
ToString(), block_hash.ToString(), expected_hash->ToString());
1089 LogError(
"Failed for %s while reading raw block storage header", pos.
ToString());
1093 if (filein.IsNull()) {
1094 LogError(
"OpenBlockFile failed for %s while reading raw block", pos.
ToString());
1100 unsigned int blk_size;
1102 filein >> blk_start >> blk_size;
1105 LogError(
"Block magic mismatch for %s: %s versus expected %s while reading raw block",
1111 LogError(
"Block data is larger than maximum deserialization size for %s: %s versus %s while reading raw block",
1117 const auto [offset, size]{*block_part};
1121 filein.seek(offset, SEEK_CUR);
1125 std::vector<std::byte>
data(blk_size);
1128 }
catch (
const std::exception& e) {
1129 LogError(
"Read from block file failed: %s for %s while reading raw block", e.what(), pos.
ToString());
1139 LogError(
"FindNextBlockPos failed for %s while writing block", pos.
ToString());
1143 if (file.IsNull()) {
1144 LogError(
"OpenBlockFile failed for %s while writing block", pos.
ToString());
1158 if (file.fclose() != 0) {
1171 std::array<std::byte, Obfuscation::KEY_SIZE> obfuscation{};
1176 bool first_run =
true;
1177 for (
const auto& entry : fs::directory_iterator(opts.
blocks_dir)) {
1179 if (!entry.is_regular_file() || !path.starts_with(
'.')) {
1185 if (opts.
use_xor && first_run) {
1195 xor_key_file >> obfuscation;
1205 xor_key_file << obfuscation;
1206 if (xor_key_file.fclose() != 0) {
1207 throw std::runtime_error{
strprintf(
"Error closing XOR key file %s: %s",
1213 if (!opts.
use_xor && obfuscation != decltype(obfuscation){}) {
1214 throw std::runtime_error{
1215 strprintf(
"The blocksdir XOR-key can not be disabled when a random key was already stored! " 1216 "Stored key: '%s', stored path: '%s'.",
1227 m_opts{std::move(opts)},
1230 m_interrupt{interrupt}
1232 m_block_tree_db = std::make_unique<BlockTreeDB>(m_opts.block_tree_db_params);
1234 if (m_opts.block_tree_db_params.wipe_data) {
1235 m_block_tree_db->WriteReindexing(
true);
1236 m_blockfiles_indexed =
false;
1239 CleanupBlockRevFiles();
1274 std::multimap<uint256, FlatFilePos> blocks_with_unknown_parent;
1276 for (
int nFile{0}; nFile < total_files; ++nFile) {
1279 if (file.IsNull()) {
1282 LogInfo(
"Reindexing block file blk%05u.dat (%d%% complete)...", (
unsigned int)nFile, nFile * 100 / total_files);
1285 LogInfo(
"Interrupt requested. Exit reindexing.");
1291 LogInfo(
"Reindexing finished");
1297 for (
const fs::path& path : import_paths) {
1299 if (!file.IsNull()) {
1303 LogInfo(
"Interrupt requested. Exit block importing.");
1312 if (
auto result = chainman.ActivateBestChains(); !
result) {
1322 default: os.setstate(std::ios_base::failbit);
bool Exists(const K &key) const
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
uint32_t nSize
number of used bytes of block file
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
is a home for simple enum and struct type definitions that can be used internally by functions in the...
std::optional< int > m_snapshot_height
The height of the base block of an assumeutxo snapshot, if one is in use.
std::string ToString() const
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
std::set< int > m_dirty_fileinfo
Dirty block file entries.
const util::SignalInterrupt & m_interrupt
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 UpdateBlockInfo(const CBlock &block, unsigned int nHeight, const FlatFilePos &pos)
Update blockfile info while processing a block during reindex.
bool WriteBlockUndo(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex &block) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePos WriteBlock(const CBlock &block, int nHeight)
Store block on disk and update block file statistics.
bool IsPruneMode() const
Whether running in -prune mode.
FILE * fopen(const fs::path &p, const char *mode)
static constexpr uint8_t DB_FLAG
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
void CleanupBlockRevFiles() const
Unused flag that was previously set when descending from failed block.
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Batch of changes queued to be written to a CDBWrapper.
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
static constexpr uint8_t DB_BLOCK_INDEX
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
RecursiveMutex cs_LastBlockFile
Interface for managing multiple Chainstate objects, where each chainstate is associated with chainsta...
uint32_t nBlocks
number of blocks stored in file
const Consensus::Params & GetConsensus() const
All parent headers found, difficulty matches, timestamp >= median previous.
int Height() const
Return the maximal height in the chain.
AutoFile OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false) const
Open an undo file (rev?????.dat)
stage after last reached validness failed
bool FlushBlockFile(int blockfile_num, bool fFinalize, bool finalize_undo)
Return false if block file or undo file flushing fails.
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)
Check if all blocks in the [upper_block, lower_block] range have data available as defined by the sta...
std::string FormatISO8601Date(int64_t nTime)
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(AutoFile OpenBlockFile(const FlatFilePos &pos, bool fReadOnly) const
Check whether the block associated with this index entry is pruned or not.
undo data available in rev*.dat
const Obfuscation m_obfuscation
BlockManager(const util::SignalInterrupt &interrupt, Options opts)
void LoadExternalBlockFile(AutoFile &file_in, FlatFilePos *dbp=nullptr, std::multimap< uint256, FlatFilePos > *blocks_with_unknown_parent=nullptr)
Import blocks from an external file.
bool ReadFlag(const std::string &name, bool &fValue)
bool IsInitialBlockDownload() const noexcept
Check whether we are doing an initial block download (synchronizing from disk or network) ...
CChain m_chain
The current chain of blockheaders we consult and build on.
consteval auto _(util::TranslatedLiteral str)
void ImportBlocks(ChainstateManager &chainman, std::span< const fs::path > import_paths)
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune) const
Actually unlink the specified files.
Non-refcounted RAII wrapper for FILE*.
void WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo *>> &fileInfo, int nLastFile, const std::vector< const CBlockIndex *> &blockinfo)
uint32_t nHeightFirst
lowest height of block in file
void fillrand(std::span< std::byte > output) noexcept
Fill a byte span with random bytes.
static constexpr uint8_t DB_REINDEX_FLAG
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'...
const util::SignalInterrupt & m_interrupt
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.
bool ReadLastBlockFile(int &nFile)
Minimal stream for reading from an existing byte array by std::span.
std::string SysErrorString(int err)
Return system error string from errno value.
void Erase(const K &key, bool fSync=false)
std::array< uint8_t, 4 > MessageStartChars
uint256 GetBlockHash() const
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...
FlatFilePos FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime)
Helper function performing various preparations before a block can be saved to disk: Returns the corr...
int MaxBlockfileNum() const EXCLUSIVE_LOCKS_REQUIRED(cs_LastBlockFile)
uint64_t PruneAfterHeight() const
arith_uint256 GetBlockProof(const CBlockIndex &block)
Compute how much work a block index entry corresponds to.
static bool exists(const path &p)
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
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.
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...
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.
An options struct for BlockManager, more ergonomically referred to as BlockManager::Options due to th...
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
void PruneOneBlockFile(int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
Wrapper that buffers writes to an underlying stream.
void Write(const K &key, const V &value, bool fSync=false)
The util::Unexpected class represents an unexpected value stored in util::Expected.
Chainstate stores and provides an API to update our local knowledge of the current best chain...
static auto InitBlocksdirXorKey(const BlockManager::Options &opts)
bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
Wrapper that buffers reads from an underlying stream.
void WriteBatch(CDBBatch &batch, bool fSync=false)
static constexpr uint32_t UNDO_DATA_DISK_OVERHEAD
Total overhead when writing undo data: header (8 bytes) plus checksum (32 bytes)
uint64_t m_chain_tx_count
(memory only) Number of transactions in the chain up to and including this block. ...
std::optional< AssumeutxoData > AssumeutxoForBlockhash(const uint256 &blockhash) const
static constexpr uint32_t STORAGE_HEADER_BYTES
Size of header written by WriteBlock before a serialized CBlock (8 bytes)
A writer stream (for serialization) that computes a 256-bit hash.
ImportingNow(std::atomic< bool > &importing)
kernel::Notifications & GetNotifications() const
const kernel::BlockManagerOpts m_opts
const FlatFileSeq m_block_file_seq
CDBIterator * NewIterator()
uint64_t GetSerializeSize(const T &t)
BlockfileType BlockfileTypeForHeight(int height)
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
uint32_t nHeightLast
highest height of block in file
ReadRawBlockResult ReadRawBlock(const FlatFilePos &pos, std::optional< std::pair< size_t, size_t >> block_part=std::nullopt) const
void Write(const K &key, const V &value)
void BuildSkip()
Build the skiplist pointer for this entry.
std::atomic_bool m_blockfiles_indexed
Whether all blockfiles have been added to the block tree database.
Used to marshal pointers into hashes for db storage.
bool LoadBlockIndex(const std::optional< uint256 > &snapshot_blockhash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
Parameters that influence chain consensus.
Notifications & notifications
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.
CBlockIndex * LookupBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool Read(const K &key, V &value) const
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
constexpr bool IsNull() const
bool Flush(const FlatFilePos &pos, bool finalize=false) const
Commit a file to disk, and optionally truncate off extra pre-allocated bytes if final.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
std::string ToString() const
FILE * Open(const FlatFilePos &pos, bool read_only=false) const
Open a handle to the file at the given position.
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(
const FlatFileSeq m_undo_file_seq
uint64_t nTimeFirst
earliest time of block in file
const CChainParams & GetParams() const
Helper class that manages an interrupt flag, and allows a thread or signal to interrupt another threa...
int32_t nVersion
block header
const CChainParams & GetParams() const
#define LogDebug(category,...)
std::string ToString() const
void WriteReindexing(bool fReindexing)
uint256 ConstructBlockHash() const
T SaturatingAdd(const T i, const T j) noexcept
#define EXCLUSIVE_LOCKS_REQUIRED(...)
The util::Expected class provides a standard way for low-level functions to return either error value...
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
fs::path GetBlockPosFilename(const FlatFilePos &pos) const
Translation to a filesystem path.
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, const Chainstate &chain)
static constexpr uint8_t DB_LAST_BLOCK
bool FlushUndoFile(int block_file, bool finalize=false)
Return false if undo file flushing fails.
std::set< CBlockIndex * > m_dirty_blockindex
Dirty block index entries.
The block chain is a tree shaped structure starting with the genesis block at the root...
Undo information for a CBlock.
const fs::path blocks_dir
uint64_t m_chain_tx_count
Used to populate the m_chain_tx_count value, which is used during BlockManager::LoadBlockIndex().
static constexpr int32_t SEQ_ID_INIT_FROM_DISK
const MessageStartChars & MessageStart() const
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(
Raise the validity level of this block index entry.
static std::string PathToString(const path &path)
Convert path object to a byte string.
Holds configuration for use during UTXO snapshot load and validation.
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...
bool ReadBlock(CBlock &block, const FlatFilePos &pos, const std::optional< uint256 > &expected_hash) const
Functions for disk access for blocks.
bilingual_str ErrorString(const Result< T > &result)
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
bool FlushChainstateBlockFile(int tip_height)
Reads data from an underlying stream, while hashing the read data.
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
void ReadReindexing(bool &fReindexing)
bool FatalError(Notifications ¬ifications, BlockValidationState &state, const bilingual_str &message)
uint64_t nTimeLast
latest time of block in file
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
void CheckBlockDataAvailability(BlockManager &blockman, const CBlockIndex &blockindex, bool check_for_undo)
Chainstate & ActiveChainstate() const
Alternatives to CurrentChainstate() used by older code to query latest chainstate information without...
full block available in blk*.dat
static const uint64_t MIN_DISK_SPACE_FOR_BLOCK_FILES
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
Chainstate * HistoricalChainstate() const EXCLUSIVE_LOCKS_REQUIRED(GetMutex())
Return historical chainstate targeting a specific block, if any.
FlatFileSeq represents a sequence of numbered files storing raw data.
static constexpr uint8_t DB_BLOCK_FILES
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
std::atomic< bool > m_importing
uint64_t GetPruneTarget() const
Attempt to stay below this number of bytes of block files.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
std::ostream & operator<<(std::ostream &os, const BlockfileType &type)
std::string HexStr(const std::span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
unsigned int nTx
Number of transactions in this block.
bool operator()(const CBlockIndex *pa, const CBlockIndex *pb) const
std::string ToString(const T &t)
Locale-independent version of std::to_string.
#define Assert(val)
Identity function.
void WriteFlag(const std::string &name, bool fValue)
static constexpr TransactionSerParams TX_WITH_WITNESS
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
bool ReadBlockUndo(CBlockUndo &blockundo, const CBlockIndex &index) const
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
std::vector< CBlockFileInfo > m_blockfile_info