Branch data Line data Source code
# 1 : : // Copyright (c) 2011-2021 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 <chain.h>
# 9 : : #include <fs.h>
# 10 : : #include <protocol.h> // For CMessageHeader::MessageStartChars
# 11 : : #include <sync.h>
# 12 : : #include <txdb.h>
# 13 : :
# 14 : : #include <atomic>
# 15 : : #include <cstdint>
# 16 : : #include <vector>
# 17 : :
# 18 : : extern RecursiveMutex cs_main;
# 19 : :
# 20 : : class ArgsManager;
# 21 : : class BlockValidationState;
# 22 : : class CBlock;
# 23 : : class CBlockFileInfo;
# 24 : : class CBlockUndo;
# 25 : : class CChain;
# 26 : : class CChainParams;
# 27 : : class CChainState;
# 28 : : class ChainstateManager;
# 29 : : struct CCheckpointData;
# 30 : : struct FlatFilePos;
# 31 : : namespace Consensus {
# 32 : : struct Params;
# 33 : : }
# 34 : :
# 35 : : namespace node {
# 36 : : static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT{false};
# 37 : :
# 38 : : /** The pre-allocation chunk size for blk?????.dat files (since 0.8) */
# 39 : : static const unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
# 40 : : /** The pre-allocation chunk size for rev?????.dat files (since 0.8) */
# 41 : : static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
# 42 : : /** The maximum size of a blk?????.dat file (since 0.8) */
# 43 : : static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
# 44 : :
# 45 : : extern std::atomic_bool fImporting;
# 46 : : extern std::atomic_bool fReindex;
# 47 : : /** Pruning-related variables and constants */
# 48 : : /** True if any block files have ever been pruned. */
# 49 : : extern bool fHavePruned;
# 50 : : /** True if we're running in -prune mode. */
# 51 : : extern bool fPruneMode;
# 52 : : /** Number of MiB of block files that we're trying to stay below. */
# 53 : : extern uint64_t nPruneTarget;
# 54 : :
# 55 : : // Because validation code takes pointers to the map's CBlockIndex objects, if
# 56 : : // we ever switch to another associative container, we need to either use a
# 57 : : // container that has stable addressing (true of all std associative
# 58 : : // containers), or make the key a `std::unique_ptr<CBlockIndex>`
# 59 : : using BlockMap = std::unordered_map<uint256, CBlockIndex, BlockHasher>;
# 60 : :
# 61 : : struct CBlockIndexWorkComparator {
# 62 : : bool operator()(const CBlockIndex* pa, const CBlockIndex* pb) const;
# 63 : : };
# 64 : :
# 65 : : struct CBlockIndexHeightOnlyComparator {
# 66 : : /* Only compares the height of two block indices, doesn't try to tie-break */
# 67 : : bool operator()(const CBlockIndex* pa, const CBlockIndex* pb) const;
# 68 : : };
# 69 : :
# 70 : : /**
# 71 : : * Maintains a tree of blocks (stored in `m_block_index`) which is consulted
# 72 : : * to determine where the most-work tip is.
# 73 : : *
# 74 : : * This data is used mostly in `CChainState` - information about, e.g.,
# 75 : : * candidate tips is not maintained here.
# 76 : : */
# 77 : : class BlockManager
# 78 : : {
# 79 : : friend CChainState;
# 80 : : friend ChainstateManager;
# 81 : :
# 82 : : private:
# 83 : : void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
# 84 : : void FlushUndoFile(int block_file, bool finalize = false);
# 85 : : bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown);
# 86 : : bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize);
# 87 : :
# 88 : : /* Calculate the block/rev files to delete based on height specified by user with RPC command pruneblockchain */
# 89 : : void FindFilesToPruneManual(std::set<int>& setFilesToPrune, int nManualPruneHeight, int chain_tip_height);
# 90 : :
# 91 : : /**
# 92 : : * Prune block and undo files (blk???.dat and rev???.dat) so that the disk space used is less than a user-defined target.
# 93 : : * The user sets the target (in MB) on the command line or in config file. This will be run on startup and whenever new
# 94 : : * space is allocated in a block or undo file, staying below the target. Changing back to unpruned requires a reindex
# 95 : : * (which in this case means the blockchain must be re-downloaded.)
# 96 : : *
# 97 : : * Pruning functions are called from FlushStateToDisk when the m_check_for_pruning flag has been set.
# 98 : : * Block and undo files are deleted in lock-step (when blk00003.dat is deleted, so is rev00003.dat.)
# 99 : : * Pruning cannot take place until the longest chain is at least a certain length (CChainParams::nPruneAfterHeight).
# 100 : : * Pruning will never delete a block within a defined distance (currently 288) from the active chain's tip.
# 101 : : * The block index is updated by unsetting HAVE_DATA and HAVE_UNDO for any blocks that were stored in the deleted files.
# 102 : : * A db flag records the fact that at least some block files have been pruned.
# 103 : : *
# 104 : : * @param[out] setFilesToPrune The set of file indices that can be unlinked will be returned
# 105 : : */
# 106 : : void FindFilesToPrune(std::set<int>& setFilesToPrune, uint64_t nPruneAfterHeight, int chain_tip_height, int prune_height, bool is_ibd);
# 107 : :
# 108 : : RecursiveMutex cs_LastBlockFile;
# 109 : : std::vector<CBlockFileInfo> m_blockfile_info;
# 110 : : int m_last_blockfile = 0;
# 111 : : /** Global flag to indicate we should check to see if there are
# 112 : : * block/undo files that should be deleted. Set on startup
# 113 : : * or if we allocate more file space when we're in prune mode
# 114 : : */
# 115 : : bool m_check_for_pruning = false;
# 116 : :
# 117 : : /** Dirty block index entries. */
# 118 : : std::set<CBlockIndex*> m_dirty_blockindex;
# 119 : :
# 120 : : /** Dirty block file entries. */
# 121 : : std::set<int> m_dirty_fileinfo;
# 122 : :
# 123 : : public:
# 124 : : BlockMap m_block_index GUARDED_BY(cs_main);
# 125 : :
# 126 : : std::vector<CBlockIndex*> GetAllBlockIndices() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
# 127 : :
# 128 : : /**
# 129 : : * All pairs A->B, where A (or one of its ancestors) misses transactions, but B has transactions.
# 130 : : * Pruned nodes may have entries where B is missing data.
# 131 : : */
# 132 : : std::multimap<CBlockIndex*, CBlockIndex*> m_blocks_unlinked;
# 133 : :
# 134 : : std::unique_ptr<CBlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main);
# 135 : :
# 136 : : bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
# 137 : : bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
# 138 : :
# 139 : : /**
# 140 : : * Load the blocktree off disk and into memory. Populate certain metadata
# 141 : : * per index entry (nStatus, nChainWork, nTimeMax, etc.) as well as peripheral
# 142 : : * collections like m_dirty_blockindex.
# 143 : : */
# 144 : : bool LoadBlockIndex(const Consensus::Params& consensus_params)
# 145 : : EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 146 : :
# 147 : : /** Clear all data members. */
# 148 : : void Unload() EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 149 : :
# 150 : : CBlockIndex* AddToBlockIndex(const CBlockHeader& block) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 151 : : /** Create a new block index entry for a given block hash */
# 152 : : CBlockIndex* InsertBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 153 : :
# 154 : : //! Mark one block file as pruned (modify associated database entries)
# 155 : : void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 156 : :
# 157 : : CBlockIndex* LookupBlockIndex(const uint256& hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 158 : : const CBlockIndex* LookupBlockIndex(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 159 : :
# 160 : : /** Get block file info entry for one block file */
# 161 : : CBlockFileInfo* GetBlockFileInfo(size_t n);
# 162 : :
# 163 : : bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams)
# 164 : : EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
# 165 : :
# 166 : : FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp);
# 167 : :
# 168 : : /** Calculate the amount of disk space the block & undo files currently use */
# 169 : : uint64_t CalculateCurrentUsage();
# 170 : :
# 171 : : //! Returns last CBlockIndex* that is a checkpoint
# 172 : : const CBlockIndex* GetLastCheckpoint(const CCheckpointData& data) EXCLUSIVE_LOCKS_REQUIRED(cs_main);
# 173 : :
# 174 : : ~BlockManager()
# 175 : 963 : {
# 176 : 963 : Unload();
# 177 : 963 : }
# 178 : : };
# 179 : :
# 180 : : //! Check whether the block associated with this index entry is pruned or not.
# 181 : : bool IsBlockPruned(const CBlockIndex* pblockindex) EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
# 182 : :
# 183 : : void CleanupBlockRevFiles();
# 184 : :
# 185 : : /** Open a block file (blk?????.dat) */
# 186 : : FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly = false);
# 187 : : /** Translation to a filesystem path */
# 188 : : fs::path GetBlockPosFilename(const FlatFilePos& pos);
# 189 : :
# 190 : : /**
# 191 : : * Actually unlink the specified files
# 192 : : */
# 193 : : void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune);
# 194 : :
# 195 : : /** Functions for disk access for blocks */
# 196 : : bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams);
# 197 : : bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams);
# 198 : : bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start);
# 199 : :
# 200 : : bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex);
# 201 : :
# 202 : : void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args);
# 203 : : } // namespace node
# 204 : :
# 205 : : #endif // BITCOIN_NODE_BLOCKSTORAGE_H
|