Bitcoin ABC  0.29.9
P2P Digital Currency
blockstorage.h
Go to the documentation of this file.
1 // Copyright (c) 2011-2021 The Bitcoin 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 <cstdint>
9 #include <unordered_map>
10 #include <vector>
11 
12 #include <chain.h>
13 #include <chainparams.h>
15 #include <kernel/cs_main.h>
16 #include <protocol.h> // For CMessageHeader::MessageStartChars
17 #include <sync.h>
18 #include <txdb.h>
19 #include <util/fs.h>
20 
22 class CBlock;
23 class CBlockFileInfo;
24 class CBlockHeader;
25 class CBlockUndo;
26 class CChain;
27 class CChainParams;
28 class CTxUndo;
29 class Chainstate;
30 class ChainstateManager;
31 struct CCheckpointData;
32 class Config;
33 struct FlatFilePos;
34 namespace Consensus {
35 struct Params;
36 }
37 namespace avalanche {
38 class Processor;
39 }
40 
41 namespace node {
42 
44 static constexpr unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
46 static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
48 static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
49 
51 static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE =
52  CMessageHeader::MESSAGE_START_SIZE + sizeof(unsigned int);
53 
54 extern std::atomic_bool fReindex;
55 
56 // Because validation code takes pointers to the map's CBlockIndex objects, if
57 // we ever switch to another associative container, we need to either use a
58 // container that has stable addressing (true of all std associative
59 // containers), or make the key a `std::unique_ptr<CBlockIndex>`
60 using BlockMap = std::unordered_map<BlockHash, CBlockIndex, BlockHasher>;
61 
62 struct PruneLockInfo {
64  int height_first{std::numeric_limits<int>::max()};
65 };
66 
74 class BlockManager {
75  friend Chainstate;
77 
78 private:
79  const CChainParams &GetParams() const { return m_opts.chainparams; }
82  }
89  void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false);
90  void FlushUndoFile(int block_file, bool finalize = false);
91  bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize,
92  unsigned int nHeight, CChain &active_chain,
93  uint64_t nTime, bool fKnown);
94  bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos,
95  unsigned int nAddSize);
96 
97  FlatFileSeq BlockFileSeq() const;
98  FlatFileSeq UndoFileSeq() const;
99 
100  FILE *OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false) const;
101 
102  bool
103  WriteBlockToDisk(const CBlock &block, FlatFilePos &pos,
104  const CMessageHeader::MessageMagic &messageStart) const;
105  bool
106  UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos,
107  const BlockHash &hashBlock,
108  const CMessageHeader::MessageMagic &messageStart) const;
109 
114  void FindFilesToPruneManual(std::set<int> &setFilesToPrune,
115  int nManualPruneHeight, int chain_tip_height);
116 
138  void FindFilesToPrune(std::set<int> &setFilesToPrune,
139  uint64_t nPruneAfterHeight, int chain_tip_height,
140  int prune_height, bool is_ibd);
141 
150  bool m_check_for_pruning = false;
151 
152  const bool m_prune_mode;
153 
156 
159 
167  std::unordered_map<std::string, PruneLockInfo>
168  m_prune_locks GUARDED_BY(::cs_main);
169 
170  const kernel::BlockManagerOpts m_opts;
171 
172 public:
173  using Options = kernel::BlockManagerOpts;
174 
175  explicit BlockManager(Options opts)
176  : m_prune_mode{opts.prune_target > 0}, m_opts{std::move(opts)} {};
177 
178  std::atomic<bool> m_importing{false};
179 
180  BlockMap m_block_index GUARDED_BY(cs_main);
181 
182  std::vector<CBlockIndex *> GetAllBlockIndices()
184 
191 
192  std::unique_ptr<CBlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main);
193 
194  bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
195  bool LoadBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
196 
202  void ScanAndUnlinkAlreadyPrunedFiles() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
203 
204  CBlockIndex *AddToBlockIndex(const CBlockHeader &block,
205  CBlockIndex *&best_header)
210 
212  void PruneOneBlockFile(const int fileNumber)
214 
217  const CBlockIndex *LookupBlockIndex(const BlockHash &hash) const
219 
221  CBlockFileInfo *GetBlockFileInfo(size_t n);
222 
223  bool WriteUndoDataForBlock(const CBlockUndo &blockundo,
224  BlockValidationState &state, CBlockIndex &block)
226 
232  CChain &active_chain, const FlatFilePos *dbp);
233 
235  [[nodiscard]] bool IsPruneMode() const { return m_prune_mode; }
236 
238  [[nodiscard]] uint64_t GetPruneTarget() const {
239  return m_opts.prune_target;
240  }
241  static constexpr auto PRUNE_TARGET_MANUAL{
242  std::numeric_limits<uint64_t>::max()};
243 
244  [[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; }
245 
246  [[nodiscard]] bool StopAfterBlockImport() const {
248  }
249 
253  uint64_t CalculateCurrentUsage();
254 
256  const CBlockIndex *GetLastCheckpoint(const CCheckpointData &data)
258 
260  const CBlockIndex *GetFirstStoredBlock(const CBlockIndex &start_block)
262 
264  bool m_have_pruned = false;
265 
268  bool IsBlockPruned(const CBlockIndex *pblockindex)
270 
272  void UpdatePruneLock(const std::string &name,
273  const PruneLockInfo &lock_info)
275 
277  FILE *OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false) const;
278 
280  fs::path GetBlockPosFilename(const FlatFilePos &pos) const;
281 
285  void UnlinkPrunedFiles(const std::set<int> &setFilesToPrune) const;
286 
288  bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos) const;
289  bool ReadBlockFromDisk(CBlock &block, const CBlockIndex &index) const;
290  bool UndoReadFromDisk(CBlockUndo &blockundo,
291  const CBlockIndex &index) const;
292 
294  bool ReadTxFromDisk(CMutableTransaction &tx, const FlatFilePos &pos) const;
295  bool ReadTxUndoFromDisk(CTxUndo &tx, const FlatFilePos &pos) const;
296 
297  void CleanupBlockRevFiles() const;
298 };
299 
300 void ThreadImport(ChainstateManager &chainman,
302  std::vector<fs::path> vImportFiles,
303  const fs::path &mempool_path);
304 } // namespace node
305 
306 #endif // BITCOIN_NODE_BLOCKSTORAGE_H
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:19
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:23
Definition: block.h:60
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:25
Access to the block database (blocks/index/)
Definition: txdb.h:117
Undo information for a CBlock.
Definition: undo.h:73
An in-memory indexed chain of blocks.
Definition: chain.h:134
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:80
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:92
Message header.
Definition: protocol.h:34
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:36
A mutable version of CTransaction.
Definition: transaction.h:274
Restore the UTXO in a Coin at a given COutPoint.
Definition: undo.h:62
Chainstate stores and provides an API to update our local knowledge of the current best chain.
Definition: validation.h:695
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1218
Definition: config.h:19
FlatFileSeq represents a sequence of numbered files storing raw data.
Definition: flatfile.h:49
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
Definition: blockstorage.h:74
const kernel::BlockManagerOpts m_opts
Definition: blockstorage.h:170
std::set< int > m_dirty_fileinfo
Dirty block file entries.
Definition: blockstorage.h:158
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos) const
Functions for disk access for blocks.
bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, const CMessageHeader::MessageMagic &messageStart) const
FlatFileSeq UndoFileSeq() const
RecursiveMutex cs_LastBlockFile
Definition: blockstorage.h:142
const Consensus::Params & GetConsensus() const
Definition: blockstorage.h:80
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 undo???.dat) so that the disk space used is less than a us...
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, int chain_tip_height)
Calculate the block/rev files to delete based on height specified by user with RPC command pruneblock...
FlatFileSeq BlockFileSeq() const
void FlushUndoFile(int block_file, bool finalize=false)
const CBlockIndex *GetFirstStoredBlock(const CBlockIndex &start_block) EXCLUSIVE_LOCKS_REQUIRED(bool m_have_pruned
Find the first block that is not pruned.
Definition: blockstorage.h:264
bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, CChain &active_chain, uint64_t nTime, bool fKnown)
FILE * OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false) const
Open an undo file (rev?????.dat)
static constexpr auto PRUNE_TARGET_MANUAL
Definition: blockstorage.h:241
bool StopAfterBlockImport() const
Definition: blockstorage.h:246
bool LoadBlockIndex() EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
std::unordered_map< std::string, PruneLockInfo > m_prune_locks GUARDED_BY(::cs_main)
Map from external index name to oldest block that must not be pruned.
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
CBlockIndex * LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool ReadTxFromDisk(CMutableTransaction &tx, const FlatFilePos &pos) const
Functions for disk access for txs.
CBlockIndex * InsertBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Create a new block index entry for a given block hash.
bool ReadTxUndoFromDisk(CTxUndo &tx, const FlatFilePos &pos) const
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex &block) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, CChain &active_chain, const FlatFilePos *dbp)
Store block on disk.
Definition: blockstorage.h:231
bool LoadingBlocks() const
Definition: blockstorage.h:244
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex &index) const
fs::path GetBlockPosFilename(const FlatFilePos &pos) const
Translation to a filesystem path.
uint64_t GetPruneTarget() const
Attempt to stay below this number of bytes of block files.
Definition: blockstorage.h:238
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune) const
Actually unlink the specified files.
const bool m_prune_mode
Definition: blockstorage.h:152
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, const BlockHash &hashBlock, const CMessageHeader::MessageMagic &messageStart) const
const CBlockIndex * GetLastCheckpoint(const CCheckpointData &data) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Returns last CBlockIndex* that is a checkpoint.
std::set< CBlockIndex * > m_dirty_blockindex
Dirty block index entries.
Definition: blockstorage.h:155
bool m_check_for_pruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted.
Definition: blockstorage.h:150
const CChainParams & GetParams() const
Definition: blockstorage.h:79
bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
friend ChainstateManager
Definition: blockstorage.h:76
bool IsPruneMode() const
Whether running in -prune mode.
Definition: blockstorage.h:235
void CleanupBlockRevFiles() const
std::atomic< bool > m_importing
Definition: blockstorage.h:178
std::vector< CBlockFileInfo > m_blockfile_info
Definition: blockstorage.h:143
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
bool IsBlockPruned(const CBlockIndex *pblockindex) EXCLUSIVE_LOCKS_REQUIRED(void UpdatePruneLock(const std::string &name, const PruneLockInfo &lock_info) EXCLUSIVE_LOCKS_REQUIRED(FILE OpenBlockFile)(const FlatFilePos &pos, bool fReadOnly=false) const
Check whether the block associated with this index entry is pruned or not.
Definition: blockstorage.h:277
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.
Definition: blockstorage.h:182
BlockMap m_block_index GUARDED_BY(cs_main)
void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
unsigned int nHeight
Definition: init.h:28
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
Definition: blockstorage.h:46
std::unordered_map< BlockHash, CBlockIndex, BlockHasher > BlockMap
Definition: blockstorage.h:60
void ThreadImport(ChainstateManager &chainman, avalanche::Processor *const avalanche, std::vector< fs::path > vImportFiles, const fs::path &mempool_path)
static constexpr unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
Definition: blockstorage.h:44
static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE
Size of header written by WriteBlockToDisk before a serialized CBlock.
Definition: blockstorage.h:51
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
Definition: blockstorage.h:48
std::atomic_bool fReindex
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:257
const char * name
Definition: rest.cpp:47
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
Parameters that influence chain consensus.
Definition: params.h:34
An options struct for BlockManager, more ergonomically referred to as BlockManager::Options due to th...
const CChainParams & chainparams
int height_first
Height of earliest block that should be kept and not pruned.
Definition: blockstorage.h:64
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56