 |
Bitcoin Core
22.99.0
P2P Digital Currency
|
Go to the documentation of this file.
38 BlockMap::const_iterator it = m_block_index.find(hash);
39 return it == m_block_index.end() ? nullptr : it->second;
48 BlockMap::iterator it = m_block_index.find(hash);
49 if (it != m_block_index.end()) {
59 BlockMap::iterator mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
61 BlockMap::iterator miPrev = m_block_index.find(block.
hashPrevBlock);
62 if (miPrev != m_block_index.end()) {
63 pindexNew->
pprev = (*miPrev).second;
83 for (
const auto& entry : m_block_index) {
85 if (pindex->nFile == fileNumber) {
98 while (range.first != range.second) {
99 std::multimap<CBlockIndex*, CBlockIndex*>::iterator _it = range.first;
101 if (_it->second == pindex) {
117 if (chain_tip_height < 0) {
122 unsigned int nLastBlockWeCanPrune = std::min((
unsigned)nManualPruneHeight, chain_tip_height -
MIN_BLOCKS_TO_KEEP);
129 setFilesToPrune.insert(fileNumber);
132 LogPrintf(
"Prune (Manual): prune_height=%d removed %d blk/rev pairs\n", nLastBlockWeCanPrune,
count);
141 if ((uint64_t)chain_tip_height <= nPruneAfterHeight) {
145 unsigned int nLastBlockWeCanPrune{(unsigned)std::min(prune_height, chain_tip_height -
static_cast<int>(
MIN_BLOCKS_TO_KEEP))};
151 uint64_t nBytesToPrune;
182 setFilesToPrune.insert(fileNumber);
183 nCurrentUsage -= nBytesToPrune;
188 LogPrint(
BCLog::PRUNE,
"Prune: target=%dMiB actual=%dMiB diff=%dMiB max_prune_height=%d removed %d blk/rev pairs\n",
190 ((int64_t)
nPruneTarget - (int64_t)nCurrentUsage)/1024/1024,
191 nLastBlockWeCanPrune,
count);
203 BlockMap::iterator mi = m_block_index.find(hash);
204 if (mi != m_block_index.end()) {
210 mi = m_block_index.insert(std::make_pair(hash, pindexNew)).first;
225 std::vector<std::pair<int, CBlockIndex*>> vSortedByHeight;
226 vSortedByHeight.reserve(m_block_index.size());
227 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index) {
229 vSortedByHeight.push_back(std::make_pair(pindex->
nHeight, pindex));
231 sort(vSortedByHeight.begin(), vSortedByHeight.end());
234 int first_assumed_valid_height = std::numeric_limits<int>::max();
236 for (
const auto& [height, block] : vSortedByHeight) {
237 if (block->IsAssumedValid()) {
238 auto chainstates = chainman.
GetAll();
244 auto any_chain = [&](
auto fnc) {
return std::any_of(chainstates.cbegin(), chainstates.cend(), fnc); };
245 assert(any_chain([](
auto chainstate) {
return chainstate->reliesOnAssumedValid(); }));
246 assert(any_chain([](
auto chainstate) {
return !chainstate->reliesOnAssumedValid(); }));
248 first_assumed_valid_height = height;
253 for (
const std::pair<int, CBlockIndex*>& item : vSortedByHeight) {
263 if (pindex->
nTx > 0) {
307 if (chainstate->reliesOnAssumedValid() ||
308 pindex->
nHeight < first_assumed_valid_height) {
309 chainstate->setBlockIndexCandidates.insert(pindex);
330 for (
const BlockMap::value_type& entry : m_block_index) {
334 m_block_index.clear();
342 bool BlockManager::WriteBlockIndexDB()
345 std::vector<std::pair<int, const CBlockFileInfo*>> vFiles;
351 std::vector<const CBlockIndex*> vBlocks;
354 vBlocks.push_back(*it);
379 if (m_block_tree_db->ReadBlockFileInfo(nFile, info)) {
387 LogPrintf(
"Checking all blk files are present...\n");
388 std::set<int> setBlkDataFiles;
389 for (
const std::pair<const uint256, CBlockIndex*>& item : m_block_index) {
392 setBlkDataFiles.insert(pindex->nFile);
395 for (std::set<int>::iterator it = setBlkDataFiles.begin(); it != setBlkDataFiles.end(); it++) {
403 m_block_tree_db->ReadFlag(
"prunedblockfiles",
fHavePruned);
405 LogPrintf(
"LoadBlockIndexDB(): Block files have previously been pruned\n");
409 bool fReindexing =
false;
410 m_block_tree_db->ReadReindexing(fReindexing);
420 for (
const MapCheckpoints::value_type& i :
reverse_iterate(checkpoints)) {
421 const uint256& hash = i.second;
444 std::map<std::string, fs::path> mapBlockFiles;
449 LogPrintf(
"Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
451 for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
453 if (fs::is_regular_file(*it) &&
454 path.length() == 12 &&
455 path.substr(8,4) ==
".dat")
457 if (path.substr(0, 3) ==
"blk") {
458 mapBlockFiles[path.substr(3, 5)] = it->path();
459 }
else if (path.substr(0, 3) ==
"rev") {
469 int nContigCounter = 0;
470 for (
const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
471 if (LocaleIndependentAtoi<int>(item.first) == nContigCounter) {
491 return error(
"%s: OpenUndoFile failed", __func__);
496 fileout << messageStart << nSize;
499 long fileOutPos = ftell(fileout.
Get());
500 if (fileOutPos < 0) {
501 return error(
"%s: ftell failed", __func__);
503 pos.
nPos = (
unsigned int)fileOutPos;
504 fileout << blockundo;
520 return error(
"%s: no undo data available", __func__);
526 return error(
"%s: OpenUndoFile failed", __func__);
534 verifier >> blockundo;
535 filein >> hashChecksum;
536 }
catch (
const std::exception& e) {
537 return error(
"%s: Deserialize or I/O error - %s", __func__, e.what());
541 if (hashChecksum != verifier.
GetHash()) {
542 return error(
"%s: Checksum mismatch", __func__);
551 if (!
UndoFileSeq().Flush(undo_pos_old, finalize)) {
552 AbortNode(
"Flushing undo file to disk failed. This is likely the result of an I/O error.");
561 AbortNode(
"Flushing block file to disk failed. This is likely the result of an I/O error.");
574 retval += file.nSize + file.nUndoSize;
581 for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
624 bool finalize_undo =
false;
659 return AbortNode(
"Disk space is too low!",
_(
"Disk space is too low!"));
683 return AbortNode(state,
"Disk space is too low!",
_(
"Disk space is too low!"));
697 return error(
"WriteBlockToDisk: OpenBlockFile failed");
702 fileout << messageStart << nSize;
705 long fileOutPos = ftell(fileout.
Get());
706 if (fileOutPos < 0) {
707 return error(
"WriteBlockToDisk: ftell failed");
709 pos.
nPos = (
unsigned int)fileOutPos;
722 return error(
"ConnectBlock(): FindUndoPos failed");
725 return AbortNode(state,
"Failed to write undo data");
737 pindex->nUndoPos = _pos.
nPos;
752 return error(
"ReadBlockFromDisk: OpenBlockFile failed for %s", pos.
ToString());
758 }
catch (
const std::exception& e) {
759 return error(
"%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.
ToString());
764 return error(
"ReadBlockFromDisk: Errors in block header at %s", pos.
ToString());
769 return error(
"ReadBlockFromDisk: Errors in block solution at %s", pos.
ToString());
783 return error(
"ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
784 pindex->
ToString(), block_pos.ToString());
795 return error(
"%s: OpenBlockFile failed for %s", __func__, pos.
ToString());
800 unsigned int blk_size;
802 filein >> blk_start >> blk_size;
805 return error(
"%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.
ToString(),
811 return error(
"%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.
ToString(),
815 block.resize(blk_size);
817 }
catch (
const std::exception& e) {
818 return error(
"%s: Read from block file failed: %s for %s", __func__, e.what(), pos.
ToString());
829 if (dbp !=
nullptr) {
833 error(
"%s: FindBlockPos failed", __func__);
836 if (dbp ==
nullptr) {
879 LogPrintf(
"Reindexing block file blk%05u.dat...\n", (
unsigned int)nFile);
882 LogPrintf(
"Shutdown requested. Exit %s\n", __func__);
895 for (
const fs::path& path : vImportFiles) {
901 LogPrintf(
"Shutdown requested. Exit %s\n", __func__);
916 if (!chainstate->ActivateBestChain(state,
nullptr)) {
924 LogPrintf(
"Stopping after block import\n");
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(
Raise the validity level of this block index entry.
size_t GetSerializeSize(const T &t, int nVersion=0)
bool m_check_for_pruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted.
std::vector< CBlockFileInfo > m_blockfile_info
bool fPruneMode
True if we're running in -prune mode.
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool IsBlockPruned(const CBlockIndex *pblockindex) EXCLUSIVE_LOCKS_REQUIRED(voi CleanupBlockRevFiles)()
Check whether the block associated with this index entry is pruned or not.
static bool exists(const path &p)
bilingual_str _(const char *psz)
Translation function.
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
std::string ToString(const T &t)
Locale-independent version of std::to_string.
CBlockIndex * LookupBlockIndex(const uint256 &hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main)
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
void FlushUndoFile(int block_file, bool finalize=false)
Reads data from an underlying stream, while hashing the read data.
FILE * fopen(const fs::path &p, const char *mode)
bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, CChain &active_chain, uint64_t nTime, bool fKnown)
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
std::string ToString() const
uint64_t nPruneTarget
Number of MiB of block files that we're trying to stay below.
unsigned int nTx
Number of transactions in this block.
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos, const CMessageHeader::MessageStartChars &message_start)
bool fHavePruned
Pruning-related variables and constants.
std::set< int > m_dirty_fileinfo
Dirty block file entries.
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
void FindFilesToPrune(std::set< int > &setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, int prune_height, bool is_ibd)
Prune block and undo files (blk???.dat and rev???.dat) so that the disk space used is less than a use...
CBlockIndex * pprev
pointer to the index of the predecessor of this block
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space)
Allocate additional space in a file after the given starting position.
int nHeight
height of the entry in the chain. The genesis block has height 0
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
std::string ToString() const
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
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.
std::atomic_bool fImporting
void ThreadImport(ChainstateManager &chainman, std::vector< fs::path > vImportFiles, const ArgsManager &args)
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
MapCheckpoints mapCheckpoints
static std::string PathToString(const path &path)
Convert path object to a byte string.
static const unsigned int MIN_BLOCKS_TO_KEEP
Block files containing a block-height within MIN_BLOCKS_TO_KEEP of ActiveChain().Tip() will not be pr...
CChainState & ActiveChainstate() const
The most-work chain.
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
static FlatFileSeq BlockFileSeq()
bool IsBlockPruned(const CBlockIndex *pblockindex)
std::string ToString() const
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
Non-refcounted RAII wrapper for FILE*.
FlatFileSeq represents a sequence of numbered files storing raw data.
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
Parameters that influence chain consensus.
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePo SaveBlockToDisk)(const CBlock &block, int nHeight, CChain &active_chain, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
static FILE * OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false)
Open an undo file (rev?????.dat)
static bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, const CMessageHeader::MessageStartChars &messageStart)
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...
std::atomic_bool fReindex
FILE * Open(const FlatFilePos &pos, bool read_only=false)
Open a handle to the file at the given position.
static bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, const uint256 &hashBlock, const CMessageHeader::MessageStartChars &messageStart)
fs::path GetBlockPosFilename(const FlatFilePos &pos)
Translation to a filesystem path.
CBlockIndex * AddToBlockIndex(const CBlockHeader &block) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
CBlockIndex * m_best_invalid
bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
void LoadMempool(const ArgsManager &args)
Load the persisted mempool from disk.
CBlockIndex * pindexBestHeader
Best header we've seen so far (used for getheaders queries' starting points).
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
void SetSyscallSandboxPolicy(SyscallSandboxPolicy syscall_policy)
Force the current thread (and threads created from the current thread) into a restricted-service oper...
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
std::map< int, uint256 > MapCheckpoints
void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Clear all data members.
CChainState &InitializeChainstate(CTxMemPool *mempool, const std::optional< uint256 > &snapshot_blockhash=std::nullopt) LIFETIMEBOUND EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * GetAll)()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(bool LoadBlockIndexDB(ChainstateManager &chainman) EXCLUSIVE_LOCKS_REQUIRED(bool LoadBlockIndex(const Consensus::Params &consensus_params, ChainstateManager &chainman) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
CChainState stores and provides an API to update our local knowledge of the current best chain.
#define LogPrint(category,...)
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
uint256 GetBlockHash() const
bool IsAssumedValid() const EXCLUSIVE_LOCKS_REQUIRED(
const CMessageHeader::MessageStartChars & MessageStart() const
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
CBlockIndex * InsertBlockIndex(const uint256 &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT
An in-memory indexed chain of blocks.
static FlatFileSeq UndoFileSeq()
#define EXCLUSIVE_LOCKS_REQUIRED(...)
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
@ INITIALIZATION_LOAD_BLOCKS
void BuildSkip()
Build the skiplist pointer for this entry.
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
A writer stream (for serialization) that computes a 256-bit hash.
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
const CChainParams & Params()
Return the currently selected parameters.
arith_uint256 GetBlockProof(const CBlockIndex &block)
bool AbortNode(const std::string &strMessage, bilingual_str user_message)
Abort with a message.
void read(Span< std::byte > dst)
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
RecursiveMutex cs_LastBlockFile
bool error(const char *fmt, const Args &... args)
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
@ BLOCK_HAVE_DATA
full block available in blk*.dat
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
The block chain is a tree shaped structure starting with the genesis block at the root,...
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
std::set< CBlockIndex * > m_dirty_blockindex
Dirty block index entries.
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
Span< std::byte > MakeWritableByteSpan(V &&v) noexcept
reverse_range< T > reverse_iterate(T &x)
void StartShutdown()
Request shutdown of the application.
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(
CBlockIndex * GetLastCheckpoint(const CCheckpointData &data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Returns last CBlockIndex* that is a checkpoint.
std::multimap< CBlockIndex *, CBlockIndex * > m_blocks_unlinked
All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
Undo information for a CBlock.
node::BlockManager m_blockman
A single BlockManager instance is shared across each constructed chainstate to avoid duplicating bloc...
static const int PROTOCOL_VERSION
network protocol versioning
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
@ BLOCK_FAILED_CHILD
descends from failed block