Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251*/252void FindFilesToPrune(253std::set<int>& setFilesToPrune,254int last_prune,255const Chainstate& chain,256ChainstateManager& chainman);258//! Since assumedvalid chainstates may be syncing a range of the chain that is very259//! far away from the normal/background validation process, we should segment blockfiles260//! for assumed chainstates. Otherwise, we might have wildly different height ranges261//! mixed into the same block files, which would impair our ability to prune262//! effectively.263//!264//! This data structure maintains separate blockfile number cursors for each265//! BlockfileType. The ASSUMED state is initialized, when necessary, in FindNextBlockPos().266//!267//! The first element is the NORMAL cursor, second is ASSUMED.268std::array<std::optional<BlockfileCursor>, BlockfileType::NUM_TYPES>269m_blockfile_cursors GUARDED_BY(::cs_main) = {270BlockfileCursor{},271std::nullopt,272};273int MaxBlockfileNum() const EXCLUSIVE_LOCKS_REQUIRED(::cs_main)274{275AssertLockHeld(::cs_main);276static const BlockfileCursor empty_cursor;277const auto& normal = m_blockfile_cursors[BlockfileType::NORMAL].value_or(empty_cursor);278const auto& assumed = m_blockfile_cursors[BlockfileType::ASSUMED].value_or(empty_cursor);279return std::max(normal.file_num, assumed.file_num);280}282/** Global flag to indicate we should check to see if there are283* block/undo files that should be deleted. Set on startup284* or if we allocate more file space when we're in prune mode285*/286bool m_check_for_pruning = false;288const bool m_prune_mode;290const Obfuscation m_obfuscation;292/**293* Map from external index name to oldest block that must not be pruned.294*295* @note Internally, only blocks at height (height_first - PRUNE_LOCK_BUFFER - 1) and296* below will be pruned, but callers should avoid assuming any particular buffer size.297*/298std::unordered_map<std::string, PruneLockInfo> m_prune_locks GUARDED_BY(::cs_main);300BlockfileType BlockfileTypeForHeight(int height);302const kernel::BlockManagerOpts m_opts;304const FlatFileSeq m_block_file_seq;305const FlatFileSeq m_undo_file_seq;307protected:308std::vector<CBlockFileInfo> m_blockfile_info;310/** Dirty block index entries. */311std::set<CBlockIndex*> m_dirty_blockindex;313/** Dirty block file entries. */314std::set<int> m_dirty_fileinfo;316public:317using Options = kernel::BlockManagerOpts;318using ReadRawBlockResult = util::Expected<std::vector<std::byte>, ReadRawError>;320explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts);322const util::SignalInterrupt& m_interrupt;323std::atomic<bool> m_importing{false};325/**326* Whether all blockfiles have been added to the block tree database.327* Normally true, but set to false when a reindex is requested and the328* database is wiped. The value is persisted in the database across restarts329* and will be false until reindexing completes.330*/331std::atomic_bool m_blockfiles_indexed{true};333BlockMap m_block_index GUARDED_BY(cs_main);335/**336* The height of the base block of an assumeutxo snapshot, if one is in use.337*338* This controls how blockfiles are segmented by chainstate type to avoid339* comingling different height regions of the chain when an assumedvalid chainstate340* is in use. If heights are drastically different in the same blockfile, pruning341* suffers.342*343* This is set during ActivateSnapshot() or upon LoadBlockIndex() if a snapshot344* had been previously loaded. After the snapshot is validated, this is unset to345* restore normal LoadBlockIndex behavior.346*/347std::optional<int> m_snapshot_height;349std::vector<CBlockIndex*> GetAllBlockIndices() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);351/**352* All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.353*/354std::multimap<CBlockIndex*, CBlockIndex*> m_blocks_unlinked;355void AddUnlinkedBlock(CBlockIndex* block) EXCLUSIVE_LOCKS_REQUIRED(cs_main);357std::unique_ptr<BlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main);359void WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);360bool LoadBlockIndexDB(const std::optional<uint256>& snapshot_blockhash)361EXCLUSIVE_LOCKS_REQUIRED(::cs_main);363/**364* Remove any pruned block & undo files that are still on disk.365* This could happen on some systems if the file was still being read while unlinked,366* or if we crash before unlinking.367*/368void ScanAndUnlinkAlreadyPrunedFiles() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);370CBlockIndex* AddToBlockIndex(const CBlockHeader& block, CBlockIndex*& best_header) EXCLUSIVE_LOCKS_REQUIRED(cs_main);371/** Create a new block index entry for a given block hash */372CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);374//! Mark one block file as pruned (modify associated database entries)375void PruneOneBlockFile(int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);377CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);378const CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);380/** Get block file info entry for one block file */381CBlockFileInfo* GetBlockFileInfo(size_t n) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);383bool WriteBlockUndo(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex& block)384EXCLUSIVE_LOCKS_REQUIRED(::cs_main);386/** Store block on disk and update block file statistics.387*388* @param[in] block the block to be stored389* @param[in] nHeight the height of the block390*391* @returns in case of success, the position to which the block was written to392* in case of an error, an empty FlatFilePos393*/394FlatFilePos WriteBlock(const CBlock& block, int nHeight) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);396/** Update blockfile info while processing a block during reindex. The block must be available on disk.397*398* @param[in] block the block being processed399* @param[in] nHeight the height of the block400* @param[in] pos the position of the serialized CBlock on disk401*/402void UpdateBlockInfo(const CBlock& block, unsigned int nHeight, const FlatFilePos& pos) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);404/** Whether running in -prune mode. */405[[nodiscard]] bool IsPruneMode() const { return m_prune_mode; }407/** Attempt to stay below this number of bytes of block files. */408[[nodiscard]] uint64_t GetPruneTarget() const { return m_opts.prune_target; }409static constexpr auto PRUNE_TARGET_MANUAL{std::numeric_limits<uint64_t>::max()};411[[nodiscard]] bool LoadingBlocks() const { return m_importing || !m_blockfiles_indexed; }413/** Calculate the amount of disk space the block & undo files currently use */414uint64_t CalculateCurrentUsage() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);416//! Check if all blocks in the [upper_block, lower_block] range have data available as417//! defined by the status mask.418//! The caller is responsible for ensuring that lower_block is an ancestor of upper_block419//! (part of the same chain).420bool CheckBlockDataAvailability(const CBlockIndex& upper_block, const CBlockIndex& lower_block, BlockStatus block_status = BLOCK_HAVE_DATA) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);422/**423* @brief Returns the earliest block with specified `status_mask` flags set after424* the latest block _not_ having those flags.425*426* This function starts from `upper_block`, which must have all427* `status_mask` flags set, and iterates backwards through its ancestors. It428* continues as long as each block has all `status_mask` flags set, until429* reaching the oldest ancestor or `lower_block`.430*431* @pre `upper_block` must have all `status_mask` flags set.432* @pre `lower_block` must be null or an ancestor of `upper_block`433*434* @param upper_block The starting block for the search, which must have all435* `status_mask` flags set.436* @param status_mask Bitmask specifying required status flags.437* @param lower_block The earliest possible block to return. If null, the438* search can extend to the genesis block.439*440* @return A reference to the earliest block between `upper_block`441* and `lower_block`, inclusive, such that every block between the442* returned block and `upper_block` has `status_mask` flags set.443*/444const CBlockIndex& GetFirstBlock(445const CBlockIndex& upper_block LIFETIMEBOUND,446uint32_t status_mask,447const CBlockIndex* lower_block LIFETIMEBOUND = nullptr448) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);450/** True if any block files have ever been pruned. */451bool m_have_pruned = false;453//! Check whether the block associated with this index entry is pruned or not.454bool IsBlockPruned(const CBlockIndex& block) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);456//! Create or update a prune lock identified by its name457void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);459//! Delete a prune lock identified by its name. Returns true if the lock existed.460bool DeletePruneLock(const std::string& name) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);462/** Open a block file (blk?????.dat) */463AutoFile OpenBlockFile(const FlatFilePos& pos, bool fReadOnly) const;465/** Translation to a filesystem path */466fs::path GetBlockPosFilename(const FlatFilePos& pos) const;468/**469* Actually unlink the specified files470*/471void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const;473/** Functions for disk access for blocks */474bool ReadBlock(CBlock& block, const FlatFilePos& pos, const std::optional<uint256>& expected_hash) const;475bool ReadBlock(CBlock& block, const CBlockIndex& index) const;476ReadRawBlockResult ReadRawBlock(const FlatFilePos& pos, std::optional<std::pair<size_t, size_t>> block_part = std::nullopt) const;478bool ReadBlockUndo(CBlockUndo& blockundo, const CBlockIndex& index) const;480void CleanupBlockRevFiles() const;481};483// Calls ActivateBestChain() even if no blocks are imported.484void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_paths);485} // namespace node487#endif // BITCOIN_NODE_BLOCKSTORAGE_H