LCOV - code coverage report
Current view: top level - src/node - blockstorage.h (source / functions) Coverage Total Hit
Test: test_bitcoin_coverage.info Lines: 100.0 % 13 13
Test Date: 2024-11-04 04:45:35 Functions: 100.0 % 2 2
Branches: 31.2 % 64 20

             Branch data     Line data    Source code
       1                 :             : // Copyright (c) 2011-2022 The Bitcoin Core developers
       2                 :             : // Distributed under the MIT software license, see the accompanying
       3                 :             : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
       4                 :             : 
       5                 :             : #ifndef BITCOIN_NODE_BLOCKSTORAGE_H
       6                 :             : #define BITCOIN_NODE_BLOCKSTORAGE_H
       7                 :             : 
       8                 :             : #include <attributes.h>
       9                 :             : #include <chain.h>
      10                 :             : #include <dbwrapper.h>
      11                 :             : #include <flatfile.h>
      12                 :             : #include <kernel/blockmanager_opts.h>
      13                 :             : #include <kernel/chainparams.h>
      14                 :             : #include <kernel/cs_main.h>
      15                 :             : #include <kernel/messagestartchars.h>
      16                 :             : #include <primitives/block.h>
      17                 :             : #include <streams.h>
      18                 :             : #include <sync.h>
      19                 :             : #include <uint256.h>
      20                 :             : #include <util/fs.h>
      21                 :             : #include <util/hasher.h>
      22                 :             : 
      23                 :             : #include <array>
      24                 :             : #include <atomic>
      25                 :             : #include <cstdint>
      26                 :             : #include <functional>
      27                 :             : #include <limits>
      28                 :             : #include <map>
      29                 :             : #include <memory>
      30                 :             : #include <optional>
      31                 :             : #include <set>
      32                 :             : #include <span>
      33                 :             : #include <string>
      34                 :             : #include <unordered_map>
      35                 :             : #include <utility>
      36                 :             : #include <vector>
      37                 :             : 
      38                 :             : class BlockValidationState;
      39                 :             : class CBlockUndo;
      40                 :             : class Chainstate;
      41                 :             : class ChainstateManager;
      42                 :             : namespace Consensus {
      43                 :             : struct Params;
      44                 :             : }
      45                 :             : namespace util {
      46                 :             : class SignalInterrupt;
      47                 :             : } // namespace util
      48                 :             : 
      49                 :             : namespace kernel {
      50                 :             : /** Access to the block database (blocks/index/) */
      51                 :         338 : class BlockTreeDB : public CDBWrapper
      52                 :             : {
      53                 :             : public:
      54         [ +  - ]:         338 :     using CDBWrapper::CDBWrapper;
      55                 :             :     bool WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*>>& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo);
      56                 :             :     bool ReadBlockFileInfo(int nFile, CBlockFileInfo& info);
      57                 :             :     bool ReadLastBlockFile(int& nFile);
      58                 :             :     bool WriteReindexing(bool fReindexing);
      59                 :             :     void ReadReindexing(bool& fReindexing);
      60                 :             :     bool WriteFlag(const std::string& name, bool fValue);
      61                 :             :     bool ReadFlag(const std::string& name, bool& fValue);
      62                 :             :     bool LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex, const util::SignalInterrupt& interrupt)
      63                 :             :         EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
      64                 :             : };
      65                 :             : } // namespace kernel
      66                 :             : 
      67                 :             : namespace node {
      68                 :             : using kernel::BlockTreeDB;
      69                 :             : 
      70                 :             : /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
      71                 :             : static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
      72                 :             : /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
      73                 :             : static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
      74                 :             : /** The maximum size of a blk?????.dat file (since 0.8) */
      75                 :             : static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
      76                 :             : 
      77                 :             : /** Size of header written by WriteBlockToDisk before a serialized CBlock */
      78                 :             : static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE = std::tuple_size_v<MessageStartChars> + sizeof(unsigned int);
      79                 :             : 
      80                 :             : // Because validation code takes pointers to the map's CBlockIndex objects, if
      81                 :             : // we ever switch to another associative container, we need to either use a
      82                 :             : // container that has stable addressing (true of all std associative
      83                 :             : // containers), or make the key a `std::unique_ptr<CBlockIndex>`
      84                 :             : using BlockMap = std::unordered_map<uint256, CBlockIndex, BlockHasher>;
      85                 :             : 
      86                 :             : struct CBlockIndexWorkComparator {
      87                 :             :     bool operator()(const CBlockIndex* pa, const CBlockIndex* pb) const;
      88                 :             : };
      89                 :             : 
      90                 :             : struct CBlockIndexHeightOnlyComparator {
      91                 :             :     /* Only compares the height of two block indices, doesn't try to tie-break */
      92                 :             :     bool operator()(const CBlockIndex* pa, const CBlockIndex* pb) const;
      93                 :             : };
      94                 :             : 
      95                 :           3 : struct PruneLockInfo {
      96                 :             :     int height_first{std::numeric_limits<int>::max()}; //! Height of earliest block that should be kept and not pruned
      97                 :             : };
      98                 :             : 
      99                 :             : enum BlockfileType {
     100                 :             :     // Values used as array indexes - do not change carelessly.
     101                 :             :     NORMAL = 0,
     102                 :             :     ASSUMED = 1,
     103                 :             :     NUM_TYPES = 2,
     104                 :             : };
     105                 :             : 
     106                 :             : std::ostream& operator<<(std::ostream& os, const BlockfileType& type);
     107                 :             : 
     108                 :             : struct BlockfileCursor {
     109                 :             :     // The latest blockfile number.
     110                 :             :     int file_num{0};
     111                 :             : 
     112                 :             :     // Track the height of the highest block in file_num whose undo
     113                 :             :     // data has been written. Block data is written to block files in download
     114                 :             :     // order, but is written to undo files in validation order, which is
     115                 :             :     // usually in order by height. To avoid wasting disk space, undo files will
     116                 :             :     // be trimmed whenever the corresponding block file is finalized and
     117                 :             :     // the height of the highest block written to the block file equals the
     118                 :             :     // height of the highest block written to the undo file. This is a
     119                 :             :     // heuristic and can sometimes preemptively trim undo files that will write
     120                 :             :     // more data later, and sometimes fail to trim undo files that can't have
     121                 :             :     // more data written later.
     122                 :             :     int undo_height{0};
     123                 :             : };
     124                 :             : 
     125                 :             : std::ostream& operator<<(std::ostream& os, const BlockfileCursor& cursor);
     126                 :             : 
     127                 :             : 
     128                 :             : /**
     129                 :             :  * Maintains a tree of blocks (stored in `m_block_index`) which is consulted
     130                 :             :  * to determine where the most-work tip is.
     131                 :             :  *
     132                 :             :  * This data is used mostly in `Chainstate` - information about, e.g.,
     133                 :             :  * candidate tips is not maintained here.
     134                 :             :  */
     135                 :             : class BlockManager
     136                 :             : {
     137                 :             :     friend Chainstate;
     138                 :             :     friend ChainstateManager;
     139                 :             : 
     140                 :             : private:
     141   [ -  -  +  -  :       14455 :     const CChainParams& GetParams() const { return m_opts.chainparams; }
                   +  - ]
     142   [ +  -  -  +  :        4288 :     const Consensus::Params& GetConsensus() const { return m_opts.chainparams.GetConsensus(); }
             -  -  +  - ]
     143                 :             :     /**
     144                 :             :      * Load the blocktree off disk and into memory. Populate certain metadata
     145                 :             :      * per index entry (nStatus, nChainWork, nTimeMax, etc.) as well as peripheral
     146                 :             :      * collections like m_dirty_blockindex.
     147                 :             :      */
     148                 :             :     bool LoadBlockIndex(const std::optional<uint256>& snapshot_blockhash)
     149                 :             :         EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     150                 :             : 
     151                 :             :     /** Return false if block file or undo file flushing fails. */
     152                 :             :     [[nodiscard]] bool FlushBlockFile(int blockfile_num, bool fFinalize, bool finalize_undo);
     153                 :             : 
     154                 :             :     /** Return false if undo file flushing fails. */
     155                 :             :     [[nodiscard]] bool FlushUndoFile(int block_file, bool finalize = false);
     156                 :             : 
     157                 :             :     /**
     158                 :             :      * Helper function performing various preparations before a block can be saved to disk:
     159                 :             :      * Returns the correct position for the block to be saved, which may be in the current or a new
     160                 :             :      * block file depending on nAddSize. May flush the previous blockfile to disk if full, updates
     161                 :             :      * blockfile info, and checks if there is enough disk space to save the block.
     162                 :             :      *
     163                 :             :      * The nAddSize argument passed to this function should include not just the size of the serialized CBlock, but also the size of
     164                 :             :      * separator fields which are written before it by WriteBlockToDisk (BLOCK_SERIALIZATION_HEADER_SIZE).
     165                 :             :      */
     166                 :             :     [[nodiscard]] FlatFilePos FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime);
     167                 :             :     [[nodiscard]] bool FlushChainstateBlockFile(int tip_height);
     168                 :             :     bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize);
     169                 :             : 
     170                 :             :     AutoFile OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false) const;
     171                 :             : 
     172                 :             :     /**
     173                 :             :      * Write a block to disk. The pos argument passed to this function is modified by this call. Before this call, it should
     174                 :             :      * point to an unused file location where separator fields will be written, followed by the serialized CBlock data.
     175                 :             :      * After this call, it will point to the beginning of the serialized CBlock data, after the separator fields
     176                 :             :      * (BLOCK_SERIALIZATION_HEADER_SIZE)
     177                 :             :      */
     178                 :             :     bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos) const;
     179                 :             :     bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock) const;
     180                 :             : 
     181                 :             :     /* Calculate the block/rev files to delete based on height specified by user with RPC command pruneblockchain */
     182                 :             :     void FindFilesToPruneManual(
     183                 :             :         std::set<int>& setFilesToPrune,
     184                 :             :         int nManualPruneHeight,
     185                 :             :         const Chainstate& chain,
     186                 :             :         ChainstateManager& chainman);
     187                 :             : 
     188                 :             :     /**
     189                 :             :      * Prune block and undo files (blk???.dat and rev???.dat) so that the disk space used is less than a user-defined target.
     190                 :             :      * The user sets the target (in MB) on the command line or in config file.  This will be run on startup and whenever new
     191                 :             :      * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex
     192                 :             :      * (which in this case means the blockchain must be re-downloaded.)
     193                 :             :      *
     194                 :             :      * Pruning functions are called from FlushStateToDisk when the m_check_for_pruning flag has been set.
     195                 :             :      * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
     196                 :             :      * Pruning cannot take place until the longest chain is at least a certain length (CChainParams::nPruneAfterHeight).
     197                 :             :      * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
     198                 :             :      * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
     199                 :             :      * A db flag records the fact that at least some block files have been pruned.
     200                 :             :      *
     201                 :             :      * @param[out]   setFilesToPrune   The set of file indices that can be unlinked will be returned
     202                 :             :      * @param        last_prune        The last height we're able to prune, according to the prune locks
     203                 :             :      */
     204                 :             :     void FindFilesToPrune(
     205                 :             :         std::set<int>& setFilesToPrune,
     206                 :             :         int last_prune,
     207                 :             :         const Chainstate& chain,
     208                 :             :         ChainstateManager& chainman);
     209                 :             : 
     210                 :             :     RecursiveMutex cs_LastBlockFile;
     211                 :             :     std::vector<CBlockFileInfo> m_blockfile_info;
     212                 :             : 
     213                 :             :     //! Since assumedvalid chainstates may be syncing a range of the chain that is very
     214                 :             :     //! far away from the normal/background validation process, we should segment blockfiles
     215                 :             :     //! for assumed chainstates. Otherwise, we might have wildly different height ranges
     216                 :             :     //! mixed into the same block files, which would impair our ability to prune
     217                 :             :     //! effectively.
     218                 :             :     //!
     219                 :             :     //! This data structure maintains separate blockfile number cursors for each
     220                 :             :     //! BlockfileType. The ASSUMED state is initialized, when necessary, in FindNextBlockPos().
     221                 :             :     //!
     222                 :             :     //! The first element is the NORMAL cursor, second is ASSUMED.
     223                 :             :     std::array<std::optional<BlockfileCursor>, BlockfileType::NUM_TYPES>
     224                 :             :         m_blockfile_cursors GUARDED_BY(cs_LastBlockFile) = {
     225                 :             :             BlockfileCursor{},
     226                 :             :             std::nullopt,
     227                 :             :     };
     228                 :         251 :     int MaxBlockfileNum() const EXCLUSIVE_LOCKS_REQUIRED(cs_LastBlockFile)
     229                 :             :     {
     230                 :         251 :         static const BlockfileCursor empty_cursor;
     231         [ +  - ]:         251 :         const auto& normal = m_blockfile_cursors[BlockfileType::NORMAL].value_or(empty_cursor);
     232         [ +  + ]:         251 :         const auto& assumed = m_blockfile_cursors[BlockfileType::ASSUMED].value_or(empty_cursor);
     233         [ +  + ]:         251 :         return std::max(normal.file_num, assumed.file_num);
     234                 :             :     }
     235                 :             : 
     236                 :             :     /** Global flag to indicate we should check to see if there are
     237                 :             :      *  block/undo files that should be deleted.  Set on startup
     238                 :             :      *  or if we allocate more file space when we're in prune mode
     239                 :             :      */
     240                 :             :     bool m_check_for_pruning = false;
     241                 :             : 
     242                 :             :     const bool m_prune_mode;
     243                 :             : 
     244                 :             :     const std::vector<std::byte> m_xor_key;
     245                 :             : 
     246                 :             :     /** Dirty block index entries. */
     247                 :             :     std::set<CBlockIndex*> m_dirty_blockindex;
     248                 :             : 
     249                 :             :     /** Dirty block file entries. */
     250                 :             :     std::set<int> m_dirty_fileinfo;
     251                 :             : 
     252                 :             :     /**
     253                 :             :      * Map from external index name to oldest block that must not be pruned.
     254                 :             :      *
     255                 :             :      * @note Internally, only blocks at height (height_first - PRUNE_LOCK_BUFFER - 1) and
     256                 :             :      * below will be pruned, but callers should avoid assuming any particular buffer size.
     257                 :             :      */
     258                 :             :     std::unordered_map<std::string, PruneLockInfo> m_prune_locks GUARDED_BY(::cs_main);
     259                 :             : 
     260                 :             :     BlockfileType BlockfileTypeForHeight(int height);
     261                 :             : 
     262                 :             :     const kernel::BlockManagerOpts m_opts;
     263                 :             : 
     264                 :             :     const FlatFileSeq m_block_file_seq;
     265                 :             :     const FlatFileSeq m_undo_file_seq;
     266                 :             : 
     267                 :             : public:
     268                 :             :     using Options = kernel::BlockManagerOpts;
     269                 :             : 
     270                 :             :     explicit BlockManager(const util::SignalInterrupt& interrupt, Options opts);
     271                 :             : 
     272                 :             :     const util::SignalInterrupt& m_interrupt;
     273                 :             :     std::atomic<bool> m_importing{false};
     274                 :             : 
     275                 :             :     /**
     276                 :             :      * Whether all blockfiles have been added to the block tree database.
     277                 :             :      * Normally true, but set to false when a reindex is requested and the
     278                 :             :      * database is wiped. The value is persisted in the database across restarts
     279                 :             :      * and will be false until reindexing completes.
     280                 :             :      */
     281                 :             :     std::atomic_bool m_blockfiles_indexed{true};
     282                 :             : 
     283                 :             :     BlockMap m_block_index GUARDED_BY(cs_main);
     284                 :             : 
     285                 :             :     /**
     286                 :             :      * The height of the base block of an assumeutxo snapshot, if one is in use.
     287                 :             :      *
     288                 :             :      * This controls how blockfiles are segmented by chainstate type to avoid
     289                 :             :      * comingling different height regions of the chain when an assumedvalid chainstate
     290                 :             :      * is in use. If heights are drastically different in the same blockfile, pruning
     291                 :             :      * suffers.
     292                 :             :      *
     293                 :             :      * This is set during ActivateSnapshot() or upon LoadBlockIndex() if a snapshot
     294                 :             :      * had been previously loaded. After the snapshot is validated, this is unset to
     295                 :             :      * restore normal LoadBlockIndex behavior.
     296                 :             :      */
     297                 :             :     std::optional<int> m_snapshot_height;
     298                 :             : 
     299                 :             :     std::vector<CBlockIndex*> GetAllBlockIndices() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     300                 :             : 
     301                 :             :     /**
     302                 :             :      * All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
     303                 :             :      * Pruned nodes may have entries where B is missing data.
     304                 :             :      */
     305                 :             :     std::multimap<CBlockIndex*, CBlockIndex*> m_blocks_unlinked;
     306                 :             : 
     307                 :             :     std::unique_ptr<BlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main);
     308                 :             : 
     309                 :             :     bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     310                 :             :     bool LoadBlockIndexDB(const std::optional<uint256>& snapshot_blockhash)
     311                 :             :         EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     312                 :             : 
     313                 :             :     /**
     314                 :             :      * Remove any pruned block & undo files that are still on disk.
     315                 :             :      * This could happen on some systems if the file was still being read while unlinked,
     316                 :             :      * or if we crash before unlinking.
     317                 :             :      */
     318                 :             :     void ScanAndUnlinkAlreadyPrunedFiles() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     319                 :             : 
     320                 :             :     CBlockIndex* AddToBlockIndex(const CBlockHeader& block, CBlockIndex*& best_header) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     321                 :             :     /** Create a new block index entry for a given block hash */
     322                 :             :     CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     323                 :             : 
     324                 :             :     //! Mark one block file as pruned (modify associated database entries)
     325                 :             :     void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     326                 :             : 
     327                 :             :     CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     328                 :             :     const CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     329                 :             : 
     330                 :             :     /** Get block file info entry for one block file */
     331                 :             :     CBlockFileInfo* GetBlockFileInfo(size_t n);
     332                 :             : 
     333                 :             :     bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex& block)
     334                 :             :         EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     335                 :             : 
     336                 :             :     /** Store block on disk and update block file statistics.
     337                 :             :      *
     338                 :             :      * @param[in]  block        the block to be stored
     339                 :             :      * @param[in]  nHeight      the height of the block
     340                 :             :      *
     341                 :             :      * @returns in case of success, the position to which the block was written to
     342                 :             :      *          in case of an error, an empty FlatFilePos
     343                 :             :      */
     344                 :             :     FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight);
     345                 :             : 
     346                 :             :     /** Update blockfile info while processing a block during reindex. The block must be available on disk.
     347                 :             :      *
     348                 :             :      * @param[in]  block        the block being processed
     349                 :             :      * @param[in]  nHeight      the height of the block
     350                 :             :      * @param[in]  pos          the position of the serialized CBlock on disk. This is the position returned
     351                 :             :      *                          by WriteBlockToDisk pointing at the CBlock, not the separator fields before it
     352                 :             :      */
     353                 :             :     void UpdateBlockInfo(const CBlock& block, unsigned int nHeight, const FlatFilePos& pos);
     354                 :             : 
     355                 :             :     /** Whether running in -prune mode. */
     356   [ +  +  #  #  :       22476 :     [[nodiscard]] bool IsPruneMode() const { return m_prune_mode; }
           #  # ][ -  +  
             +  +  -  + ]
           [ #  #  #  #  
          #  #  #  #  #  
           # ][ #  #  #  
          #  #  #  #  #  
                   #  # ]
     357                 :             : 
     358                 :             :     /** Attempt to stay below this number of bytes of block files. */
     359         [ -  + ]:         168 :     [[nodiscard]] uint64_t GetPruneTarget() const { return m_opts.prune_target; }
           [ #  #  #  # ]
     360                 :             :     static constexpr auto PRUNE_TARGET_MANUAL{std::numeric_limits<uint64_t>::max()};
     361                 :             : 
     362   [ +  -  -  + ]:       18690 :     [[nodiscard]] bool LoadingBlocks() const { return m_importing || !m_blockfiles_indexed; }
     363                 :             : 
     364                 :             :     /** Calculate the amount of disk space the block & undo files currently use */
     365                 :             :     uint64_t CalculateCurrentUsage();
     366                 :             : 
     367                 :             :     //! Returns last CBlockIndex* that is a checkpoint
     368                 :             :     const CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
     369                 :             : 
     370                 :             :     //! Check if all blocks in the [upper_block, lower_block] range have data available.
     371                 :             :     //! The caller is responsible for ensuring that lower_block is an ancestor of upper_block
     372                 :             :     //! (part of the same chain).
     373                 :             :     bool CheckBlockDataAvailability(const CBlockIndex& upper_block LIFETIMEBOUND, const CBlockIndex& lower_block LIFETIMEBOUND) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     374                 :             : 
     375                 :             :     /**
     376                 :             :      * @brief Returns the earliest block with specified `status_mask` flags set after
     377                 :             :      * the latest block _not_ having those flags.
     378                 :             :      *
     379                 :             :      * This function starts from `upper_block`, which must have all
     380                 :             :      * `status_mask` flags set, and iterates backwards through its ancestors. It
     381                 :             :      * continues as long as each block has all `status_mask` flags set, until
     382                 :             :      * reaching the oldest ancestor or `lower_block`.
     383                 :             :      *
     384                 :             :      * @pre `upper_block` must have all `status_mask` flags set.
     385                 :             :      * @pre `lower_block` must be null or an ancestor of `upper_block`
     386                 :             :      *
     387                 :             :      * @param upper_block The starting block for the search, which must have all
     388                 :             :      *                    `status_mask` flags set.
     389                 :             :      * @param status_mask Bitmask specifying required status flags.
     390                 :             :      * @param lower_block The earliest possible block to return. If null, the
     391                 :             :      *                    search can extend to the genesis block.
     392                 :             :      *
     393                 :             :      * @return A non-null pointer to the earliest block between `upper_block`
     394                 :             :      *         and `lower_block`, inclusive, such that every block between the
     395                 :             :      *         returned block and `upper_block` has `status_mask` flags set.
     396                 :             :      */
     397                 :             :     const CBlockIndex* GetFirstBlock(
     398                 :             :         const CBlockIndex& upper_block LIFETIMEBOUND,
     399                 :             :         uint32_t status_mask,
     400                 :             :         const CBlockIndex* lower_block = nullptr
     401                 :             :     ) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     402                 :             : 
     403                 :             :     /** True if any block files have ever been pruned. */
     404                 :             :     bool m_have_pruned = false;
     405                 :             : 
     406                 :             :     //! Check whether the block associated with this index entry is pruned or not.
     407                 :             :     bool IsBlockPruned(const CBlockIndex& block) const EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     408                 :             : 
     409                 :             :     //! Create or update a prune lock identified by its name
     410                 :             :     void UpdatePruneLock(const std::string& name, const PruneLockInfo& lock_info) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
     411                 :             : 
     412                 :             :     /** Open a block file (blk?????.dat) */
     413                 :             :     AutoFile OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false) const;
     414                 :             : 
     415                 :             :     /** Translation to a filesystem path */
     416                 :             :     fs::path GetBlockPosFilename(const FlatFilePos& pos) const;
     417                 :             : 
     418                 :             :     /**
     419                 :             :      *  Actually unlink the specified files
     420                 :             :      */
     421                 :             :     void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune) const;
     422                 :             : 
     423                 :             :     /** Functions for disk access for blocks */
     424                 :             :     bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos) const;
     425                 :             :     bool ReadBlockFromDisk(CBlock& block, const CBlockIndex& index) const;
     426                 :             :     bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos) const;
     427                 :             : 
     428                 :             :     bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex& index) const;
     429                 :             : 
     430                 :             :     void CleanupBlockRevFiles() const;
     431                 :             : };
     432                 :             : 
     433                 :             : void ImportBlocks(ChainstateManager& chainman, std::span<const fs::path> import_paths);
     434                 :             : } // namespace node
     435                 :             : 
     436                 :             : #endif // BITCOIN_NODE_BLOCKSTORAGE_H
        

Generated by: LCOV version 2.0-1