Bitcoin ABC 0.32.4
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 <functional>
10#include <unordered_map>
11#include <vector>
12
13#include <attributes.h>
14#include <chain.h>
15#include <chainparams.h>
17#include <kernel/chain.h>
18#include <kernel/cs_main.h>
19#include <protocol.h>
20#include <sync.h>
21#include <txdb.h>
22#include <util/fs.h>
23
25class CBlock;
26class CBlockFileInfo;
27class CBlockHeader;
28class CBlockUndo;
29class CChainParams;
30class CTxUndo;
31class Chainstate;
33struct CCheckpointData;
34class Config;
35struct FlatFilePos;
36namespace Consensus {
37struct Params;
38}
39namespace avalanche {
40class Processor;
41}
42namespace util {
43class SignalInterrupt;
44} // namespace util
45
46namespace node {
47
49static constexpr unsigned int BLOCKFILE_CHUNK_SIZE = 0x1000000; // 16 MiB
51static const unsigned int UNDOFILE_CHUNK_SIZE = 0x100000; // 1 MiB
53static const unsigned int MAX_BLOCKFILE_SIZE = 0x8000000; // 128 MiB
54
56static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE =
57 CMessageHeader::MESSAGE_START_SIZE + sizeof(unsigned int);
58
59extern std::atomic_bool fReindex;
60
61// Because validation code takes pointers to the map's CBlockIndex objects, if
62// we ever switch to another associative container, we need to either use a
63// container that has stable addressing (true of all std associative
64// containers), or make the key a `std::unique_ptr<CBlockIndex>`
65using BlockMap = std::unordered_map<BlockHash, CBlockIndex, BlockHasher>;
66
69 int height_first{std::numeric_limits<int>::max()};
70};
71
73 // Values used as array indexes - do not change carelessly.
74 NORMAL = 0,
77};
78
79std::ostream &operator<<(std::ostream &os, const BlockfileType &type);
80
82 // The latest blockfile number.
83 int file_num{0};
84
85 // Track the height of the highest block in file_num whose undo
86 // data has been written. Block data is written to block files in download
87 // order, but is written to undo files in validation order, which is
88 // usually in order by height. To avoid wasting disk space, undo files will
89 // be trimmed whenever the corresponding block file is finalized and
90 // the height of the highest block written to the block file equals the
91 // height of the highest block written to the undo file. This is a
92 // heuristic and can sometimes preemptively trim undo files that will write
93 // more data later, and sometimes fail to trim undo files that can't have
94 // more data written later.
96};
97
98std::ostream &operator<<(std::ostream &os, const BlockfileCursor &cursor);
99
110
111private:
112 const CChainParams &GetParams() const { return m_opts.chainparams; }
115 }
121 bool LoadBlockIndex(const std::optional<BlockHash> &snapshot_blockhash)
123
125 [[nodiscard]] bool FlushBlockFile(int blockfile_num, bool fFinalize,
126 bool finalize_undo);
127
129 [[nodiscard]] bool FlushUndoFile(int block_file, bool finalize = false);
130
143 [[nodiscard]] FlatFilePos FindNextBlockPos(unsigned int nAddSize,
144 unsigned int nHeight,
145 uint64_t nTime);
146 [[nodiscard]] bool FlushChainstateBlockFile(int tip_height);
147 bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos,
148 unsigned int nAddSize);
149
151 FlatFileSeq UndoFileSeq() const;
152
153 FILE *OpenUndoFile(const FlatFilePos &pos, bool fReadOnly = false) const;
154
163 bool
164 WriteBlockToDisk(const CBlock &block, FlatFilePos &pos,
165 const CMessageHeader::MessageMagic &messageStart) const;
166 bool
167 UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos,
168 const BlockHash &hashBlock,
169 const CMessageHeader::MessageMagic &messageStart) const;
174 void FindFilesToPruneManual(std::set<int> &setFilesToPrune,
175 int nManualPruneHeight, const Chainstate &chain,
176 ChainstateManager &chainman);
177
201 void FindFilesToPrune(std::set<int> &setFilesToPrune, int last_prune,
202 const Chainstate &chain, ChainstateManager &chainman);
203
205 std::vector<CBlockFileInfo> m_blockfile_info;
206
218 std::array<std::optional<BlockfileCursor>, BlockfileType::NUM_TYPES>
219 m_blockfile_cursors GUARDED_BY(cs_LastBlockFile) = {{
221 std::nullopt,
222 }};
224 static const BlockfileCursor empty_cursor;
225 const auto &normal =
226 m_blockfile_cursors[BlockfileType::NORMAL].value_or(empty_cursor);
227 const auto &assumed =
228 m_blockfile_cursors[BlockfileType::ASSUMED].value_or(empty_cursor);
229 return std::max(normal.file_num, assumed.file_num);
230 }
231
238
239 const bool m_prune_mode;
240
242 std::set<CBlockIndex *> m_dirty_blockindex;
243
245 std::set<int> m_dirty_fileinfo;
246
254 std::unordered_map<std::string, PruneLockInfo>
255 m_prune_locks GUARDED_BY(::cs_main);
256
258
260
261public:
263
264 explicit BlockManager(const util::SignalInterrupt &interrupt, Options opts)
265 : m_prune_mode{opts.prune_target > 0}, m_opts{std::move(opts)},
266 m_interrupt{interrupt} {};
267
269 std::atomic<bool> m_importing{false};
270
272
285 std::optional<int> m_snapshot_height;
286
287 std::vector<CBlockIndex *> GetAllBlockIndices()
289
296
297 std::unique_ptr<CBlockTreeDB> m_block_tree_db GUARDED_BY(::cs_main);
298
299 bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
300 bool LoadBlockIndexDB(const std::optional<BlockHash> &snapshot_blockhash)
302
308 void ScanAndUnlinkAlreadyPrunedFiles() EXCLUSIVE_LOCKS_REQUIRED(::cs_main);
309
311 CBlockIndex *&best_header)
316
318 void PruneOneBlockFile(const int fileNumber)
320
323 const CBlockIndex *LookupBlockIndex(const BlockHash &hash) const
325
328
329 bool WriteUndoDataForBlock(const CBlockUndo &blockundo,
330 BlockValidationState &state, CBlockIndex &block)
332
344
355 void UpdateBlockInfo(const CBlock &block, unsigned int nHeight,
356 const FlatFilePos &pos);
357
359 [[nodiscard]] bool IsPruneMode() const { return m_prune_mode; }
360
362 [[nodiscard]] uint64_t GetPruneTarget() const {
363 return m_opts.prune_target;
364 }
365 static constexpr auto PRUNE_TARGET_MANUAL{
366 std::numeric_limits<uint64_t>::max()};
367
368 [[nodiscard]] bool LoadingBlocks() const { return m_importing || fReindex; }
369
370 [[nodiscard]] bool StopAfterBlockImport() const {
372 }
373
377 uint64_t CalculateCurrentUsage();
378
382
386 bool
387 CheckBlockDataAvailability(const CBlockIndex &upper_block LIFETIMEBOUND,
388 const CBlockIndex &lower_block LIFETIMEBOUND)
390
414 const CBlockIndex *
415 GetFirstBlock(const CBlockIndex &upper_block LIFETIMEBOUND,
416 std::function<bool(BlockStatus)> status_test,
417 const CBlockIndex *lower_block = nullptr) const
419
421 bool m_have_pruned = false;
422
425 bool IsBlockPruned(const CBlockIndex &block) const
427
429 void UpdatePruneLock(const std::string &name,
430 const PruneLockInfo &lock_info)
432
434 FILE *OpenBlockFile(const FlatFilePos &pos, bool fReadOnly = false) const;
435
437 fs::path GetBlockPosFilename(const FlatFilePos &pos) const;
438
442 void UnlinkPrunedFiles(const std::set<int> &setFilesToPrune) const;
443
445 bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos) const;
446 bool ReadBlockFromDisk(CBlock &block, const CBlockIndex &index) const;
447 bool ReadRawBlockFromDisk(std::vector<uint8_t> &block,
448 const FlatFilePos &pos) const;
449 bool UndoReadFromDisk(CBlockUndo &blockundo,
450 const CBlockIndex &index) const;
451
453 bool ReadTxFromDisk(CMutableTransaction &tx, const FlatFilePos &pos) const;
454 bool ReadTxUndoFromDisk(CTxUndo &tx, const FlatFilePos &pos) const;
455
456 void CleanupBlockRevFiles() const;
457};
458
459void ImportBlocks(ChainstateManager &chainman,
460 avalanche::Processor *const avalanche,
461 std::vector<fs::path> vImportFiles);
462} // namespace node
463
464#endif // BITCOIN_NODE_BLOCKSTORAGE_H
#define LIFETIMEBOUND
Definition: attributes.h:16
const CChainParams & Params()
Return the currently selected parameters.
Definition: chainparams.cpp:21
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:100
Undo information for a CBlock.
Definition: undo.h:73
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system.
Definition: chainparams.h:86
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:98
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:36
std::array< uint8_t, MESSAGE_START_SIZE > MessageMagic
Definition: protocol.h:47
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:734
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:1186
Definition: config.h:19
FlatFileSeq represents a sequence of numbered files storing raw data.
Definition: flatfile.h:49
Maintains a tree of blocks (stored in m_block_index) which is consulted to determine where the most-w...
Definition: blockstorage.h:107
const kernel::BlockManagerOpts m_opts
Definition: blockstorage.h:259
std::set< int > m_dirty_fileinfo
Dirty block file entries.
Definition: blockstorage.h:245
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
Write a block to disk.
FlatFileSeq UndoFileSeq() const
RecursiveMutex cs_LastBlockFile
Definition: blockstorage.h:204
const CChainParams & GetParams() const
Definition: blockstorage.h:112
bool CheckBlockDataAvailability(const CBlockIndex &upper_block LIFETIMEBOUND, const CBlockIndex &lower_block LIFETIMEBOUND) EXCLUSIVE_LOCKS_REQUIRED(const CBlockIndex *GetFirstBlock(const CBlockIndex &upper_block LIFETIMEBOUND, std::function< bool(BlockStatus)> status_test, const CBlockIndex *lower_block=nullptr) const EXCLUSIVE_LOCKS_REQUIRED(boo m_have_pruned)
Check if all blocks in the [upper_block, lower_block] range have data available.
Definition: blockstorage.h:421
bool FlushChainstateBlockFile(int tip_height)
void FindFilesToPrune(std::set< int > &setFilesToPrune, int last_prune, const Chainstate &chain, ChainstateManager &chainman)
Prune block and undo files (blk???.dat and undo???.dat) so that the disk space used is less than a us...
void UpdateBlockInfo(const CBlock &block, unsigned int nHeight, const FlatFilePos &pos)
Update blockfile info while processing a block during reindex.
FlatFileSeq BlockFileSeq() const
FILE * OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false) const
Open an undo file (rev?????.dat)
static constexpr auto PRUNE_TARGET_MANUAL
Definition: blockstorage.h:365
bool StopAfterBlockImport() const
Definition: blockstorage.h:370
bool LoadBlockIndex(const std::optional< BlockHash > &snapshot_blockhash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Load the blocktree off disk and into memory.
void PruneOneBlockFile(const int fileNumber) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Mark one block file as pruned (modify associated database entries)
BlockfileType BlockfileTypeForHeight(int height)
CBlockIndex * LookupBlockIndex(const BlockHash &hash) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
bool IsBlockPruned(const CBlockIndex &block) const 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:434
bool ReadTxFromDisk(CMutableTransaction &tx, const FlatFilePos &pos) const
Functions for disk access for txs.
const Consensus::Params & GetConsensus() const
Definition: blockstorage.h:113
BlockManager(const util::SignalInterrupt &interrupt, Options opts)
Definition: blockstorage.h:264
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos) const
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.
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 LoadingBlocks() const
Definition: blockstorage.h:368
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex &index) const
fs::path GetBlockPosFilename(const FlatFilePos &pos) const
Translation to a filesystem path.
bool FlushBlockFile(int blockfile_num, bool fFinalize, bool finalize_undo)
Return false if block file or undo file flushing fails.
uint64_t GetPruneTarget() const
Attempt to stay below this number of bytes of block files.
Definition: blockstorage.h:362
int MaxBlockfileNum() const EXCLUSIVE_LOCKS_REQUIRED(cs_LastBlockFile)
Definition: blockstorage.h:223
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune) const
Actually unlink the specified files.
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex &block) EXCLUSIVE_LOCKS_REQUIRED(FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight)
Store block on disk and update block file statistics.
Definition: blockstorage.h:343
bool WriteBlockIndexDB() EXCLUSIVE_LOCKS_REQUIRED(bool LoadBlockIndexDB(const std::optional< BlockHash > &snapshot_blockhash) EXCLUSIVE_LOCKS_REQUIRED(void ScanAndUnlinkAlreadyPrunedFiles() EXCLUSIVE_LOCKS_REQUIRED(CBlockIndex * AddToBlockIndex(const CBlockHeader &block, CBlockIndex *&best_header) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove any pruned block & undo files that are still on disk.
Definition: blockstorage.h:310
FlatFilePos FindNextBlockPos(unsigned int nAddSize, unsigned int nHeight, uint64_t nTime)
Helper function performing various preparations before a block can be saved to disk: Returns the corr...
const bool m_prune_mode
Definition: blockstorage.h:239
bool FlushUndoFile(int block_file, bool finalize=false)
Return false if undo file flushing fails.
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
const util::SignalInterrupt & m_interrupt
Definition: blockstorage.h:268
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:242
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:237
bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
bool IsPruneMode() const
Whether running in -prune mode.
Definition: blockstorage.h:359
void CleanupBlockRevFiles() const
void FindFilesToPruneManual(std::set< int > &setFilesToPrune, int nManualPruneHeight, const Chainstate &chain, ChainstateManager &chainman)
Calculate the block/rev files to delete based on height specified by user with RPC command pruneblock...
std::array< std::optional< BlockfileCursor >, BlockfileType::NUM_TYPES > m_blockfile_cursors GUARDED_BY(cs_LastBlockFile)
Since assumedvalid chainstates may be syncing a range of the chain that is very far away from the nor...
std::atomic< bool > m_importing
Definition: blockstorage.h:269
std::vector< CBlockFileInfo > m_blockfile_info
Definition: blockstorage.h:205
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
std::optional< int > m_snapshot_height
The height of the base block of an assumeutxo snapshot, if one is in use.
Definition: blockstorage.h:285
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:287
BlockMap m_block_index GUARDED_BY(cs_main)
Helper class that manages an interrupt flag, and allows a thread or signal to interrupt another threa...
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
Filesystem operations and types.
Definition: fs.h:20
Definition: init.h:31
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
Definition: blockstorage.h:51
BlockfileType
Definition: blockstorage.h:72
@ NUM_TYPES
Definition: blockstorage.h:76
@ NORMAL
Definition: blockstorage.h:74
@ ASSUMED
Definition: blockstorage.h:75
std::unordered_map< BlockHash, CBlockIndex, BlockHasher > BlockMap
Definition: blockstorage.h:65
std::ostream & operator<<(std::ostream &os, const BlockfileType &type)
static constexpr unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
Definition: blockstorage.h:49
static constexpr size_t BLOCK_SERIALIZATION_HEADER_SIZE
Size of header written by WriteBlockToDisk before a serialized CBlock.
Definition: blockstorage.h:56
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
Definition: blockstorage.h:53
std::atomic_bool fReindex
void ImportBlocks(ChainstateManager &chainman, avalanche::Processor *const avalanche, std::vector< fs::path > vImportFiles)
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:259
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:69
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:56