Bitcoin Core  22.0.0
P2P Digital Currency
blockstorage.cpp
Go to the documentation of this file.
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 #include <node/blockstorage.h>
6 
7 #include <chain.h>
8 #include <chainparams.h>
9 #include <clientversion.h>
10 #include <consensus/validation.h>
11 #include <flatfile.h>
12 #include <fs.h>
13 #include <hash.h>
14 #include <pow.h>
15 #include <shutdown.h>
16 #include <signet.h>
17 #include <streams.h>
18 #include <undo.h>
19 #include <util/system.h>
20 #include <validation.h>
21 
22 std::atomic_bool fImporting(false);
23 std::atomic_bool fReindex(false);
24 bool fHavePruned = false;
25 bool fPruneMode = false;
26 uint64_t nPruneTarget = 0;
27 
28 // TODO make namespace {
30 std::vector<CBlockFileInfo> vinfoBlockFile;
36 bool fCheckForPruning = false;
37 
39 std::set<CBlockIndex*> setDirtyBlockIndex;
40 
42 std::set<int> setDirtyFileInfo;
43 // } // namespace
44 
45 static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly = false);
46 static FlatFileSeq BlockFileSeq();
47 static FlatFileSeq UndoFileSeq();
48 
49 bool IsBlockPruned(const CBlockIndex* pblockindex)
50 {
51  return (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0);
52 }
53 
54 // If we're using -prune with -reindex, then delete block files that will be ignored by the
55 // reindex. Since reindexing works by starting at block file 0 and looping until a blockfile
56 // is missing, do the same here to delete any later block files after a gap. Also delete all
57 // rev files since they'll be rewritten by the reindex anyway. This ensures that vinfoBlockFile
58 // is in sync with what's actually on disk by the time we start downloading, so that pruning
59 // works correctly.
61 {
62  std::map<std::string, fs::path> mapBlockFiles;
63 
64  // Glob all blk?????.dat and rev?????.dat files from the blocks directory.
65  // Remove the rev files immediately and insert the blk file paths into an
66  // ordered map keyed by block file index.
67  LogPrintf("Removing unusable blk?????.dat and rev?????.dat files for -reindex with -prune\n");
68  fs::path blocksdir = gArgs.GetBlocksDirPath();
69  for (fs::directory_iterator it(blocksdir); it != fs::directory_iterator(); it++) {
70  if (fs::is_regular_file(*it) &&
71  it->path().filename().string().length() == 12 &&
72  it->path().filename().string().substr(8,4) == ".dat")
73  {
74  if (it->path().filename().string().substr(0, 3) == "blk") {
75  mapBlockFiles[it->path().filename().string().substr(3, 5)] = it->path();
76  } else if (it->path().filename().string().substr(0, 3) == "rev") {
77  remove(it->path());
78  }
79  }
80  }
81 
82  // Remove all block files that aren't part of a contiguous set starting at
83  // zero by walking the ordered map (keys are block file indices) by
84  // keeping a separate counter. Once we hit a gap (or if 0 doesn't exist)
85  // start removing block files.
86  int nContigCounter = 0;
87  for (const std::pair<const std::string, fs::path>& item : mapBlockFiles) {
88  if (atoi(item.first) == nContigCounter) {
89  nContigCounter++;
90  continue;
91  }
92  remove(item.second);
93  }
94 }
95 
96 std::string CBlockFileInfo::ToString() const
97 {
98  return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
99 }
100 
102 {
104 
105  return &vinfoBlockFile.at(n);
106 }
107 
108 static bool UndoWriteToDisk(const CBlockUndo& blockundo, FlatFilePos& pos, const uint256& hashBlock, const CMessageHeader::MessageStartChars& messageStart)
109 {
110  // Open history file to append
112  if (fileout.IsNull()) {
113  return error("%s: OpenUndoFile failed", __func__);
114  }
115 
116  // Write index header
117  unsigned int nSize = GetSerializeSize(blockundo, fileout.GetVersion());
118  fileout << messageStart << nSize;
119 
120  // Write undo data
121  long fileOutPos = ftell(fileout.Get());
122  if (fileOutPos < 0) {
123  return error("%s: ftell failed", __func__);
124  }
125  pos.nPos = (unsigned int)fileOutPos;
126  fileout << blockundo;
127 
128  // calculate & write checksum
130  hasher << hashBlock;
131  hasher << blockundo;
132  fileout << hasher.GetHash();
133 
134  return true;
135 }
136 
137 bool UndoReadFromDisk(CBlockUndo& blockundo, const CBlockIndex* pindex)
138 {
139  FlatFilePos pos = pindex->GetUndoPos();
140  if (pos.IsNull()) {
141  return error("%s: no undo data available", __func__);
142  }
143 
144  // Open history file to read
145  CAutoFile filein(OpenUndoFile(pos, true), SER_DISK, CLIENT_VERSION);
146  if (filein.IsNull()) {
147  return error("%s: OpenUndoFile failed", __func__);
148  }
149 
150  // Read block
151  uint256 hashChecksum;
152  CHashVerifier<CAutoFile> verifier(&filein); // We need a CHashVerifier as reserializing may lose data
153  try {
154  verifier << pindex->pprev->GetBlockHash();
155  verifier >> blockundo;
156  filein >> hashChecksum;
157  } catch (const std::exception& e) {
158  return error("%s: Deserialize or I/O error - %s", __func__, e.what());
159  }
160 
161  // Verify checksum
162  if (hashChecksum != verifier.GetHash()) {
163  return error("%s: Checksum mismatch", __func__);
164  }
165 
166  return true;
167 }
168 
169 static void FlushUndoFile(int block_file, bool finalize = false)
170 {
171  FlatFilePos undo_pos_old(block_file, vinfoBlockFile[block_file].nUndoSize);
172  if (!UndoFileSeq().Flush(undo_pos_old, finalize)) {
173  AbortNode("Flushing undo file to disk failed. This is likely the result of an I/O error.");
174  }
175 }
176 
177 void FlushBlockFile(bool fFinalize = false, bool finalize_undo = false)
178 {
181  if (!BlockFileSeq().Flush(block_pos_old, fFinalize)) {
182  AbortNode("Flushing block file to disk failed. This is likely the result of an I/O error.");
183  }
184  // we do not always flush the undo file, as the chain tip may be lagging behind the incoming blocks,
185  // e.g. during IBD or a sync after a node going offline
186  if (!fFinalize || finalize_undo) FlushUndoFile(nLastBlockFile, finalize_undo);
187 }
188 
190 {
192 
193  uint64_t retval = 0;
194  for (const CBlockFileInfo& file : vinfoBlockFile) {
195  retval += file.nSize + file.nUndoSize;
196  }
197  return retval;
198 }
199 
200 void UnlinkPrunedFiles(const std::set<int>& setFilesToPrune)
201 {
202  for (std::set<int>::iterator it = setFilesToPrune.begin(); it != setFilesToPrune.end(); ++it) {
203  FlatFilePos pos(*it, 0);
204  fs::remove(BlockFileSeq().FileName(pos));
205  fs::remove(UndoFileSeq().FileName(pos));
206  LogPrintf("Prune: %s deleted blk/rev (%05u)\n", __func__, *it);
207  }
208 }
209 
211 {
212  return FlatFileSeq(gArgs.GetBlocksDirPath(), "blk", gArgs.GetBoolArg("-fastprune", false) ? 0x4000 /* 16kb */ : BLOCKFILE_CHUNK_SIZE);
213 }
214 
216 {
218 }
219 
220 FILE* OpenBlockFile(const FlatFilePos& pos, bool fReadOnly)
221 {
222  return BlockFileSeq().Open(pos, fReadOnly);
223 }
224 
226 static FILE* OpenUndoFile(const FlatFilePos& pos, bool fReadOnly)
227 {
228  return UndoFileSeq().Open(pos, fReadOnly);
229 }
230 
231 fs::path GetBlockPosFilename(const FlatFilePos& pos)
232 {
233  return BlockFileSeq().FileName(pos);
234 }
235 
236 bool FindBlockPos(FlatFilePos& pos, unsigned int nAddSize, unsigned int nHeight, CChain& active_chain, uint64_t nTime, bool fKnown = false)
237 {
239 
240  unsigned int nFile = fKnown ? pos.nFile : nLastBlockFile;
241  if (vinfoBlockFile.size() <= nFile) {
242  vinfoBlockFile.resize(nFile + 1);
243  }
244 
245  bool finalize_undo = false;
246  if (!fKnown) {
247  while (vinfoBlockFile[nFile].nSize + nAddSize >= (gArgs.GetBoolArg("-fastprune", false) ? 0x10000 /* 64kb */ : MAX_BLOCKFILE_SIZE)) {
248  // when the undo file is keeping up with the block file, we want to flush it explicitly
249  // when it is lagging behind (more blocks arrive than are being connected), we let the
250  // undo block write case handle it
251  finalize_undo = (vinfoBlockFile[nFile].nHeightLast == (unsigned int)active_chain.Tip()->nHeight);
252  nFile++;
253  if (vinfoBlockFile.size() <= nFile) {
254  vinfoBlockFile.resize(nFile + 1);
255  }
256  }
257  pos.nFile = nFile;
258  pos.nPos = vinfoBlockFile[nFile].nSize;
259  }
260 
261  if ((int)nFile != nLastBlockFile) {
262  if (!fKnown) {
263  LogPrint(BCLog::VALIDATION, "Leaving block file %i: %s\n", nLastBlockFile, vinfoBlockFile[nLastBlockFile].ToString());
264  }
265  FlushBlockFile(!fKnown, finalize_undo);
266  nLastBlockFile = nFile;
267  }
268 
269  vinfoBlockFile[nFile].AddBlock(nHeight, nTime);
270  if (fKnown) {
271  vinfoBlockFile[nFile].nSize = std::max(pos.nPos + nAddSize, vinfoBlockFile[nFile].nSize);
272  } else {
273  vinfoBlockFile[nFile].nSize += nAddSize;
274  }
275 
276  if (!fKnown) {
277  bool out_of_space;
278  size_t bytes_allocated = BlockFileSeq().Allocate(pos, nAddSize, out_of_space);
279  if (out_of_space) {
280  return AbortNode("Disk space is too low!", _("Disk space is too low!"));
281  }
282  if (bytes_allocated != 0 && fPruneMode) {
283  fCheckForPruning = true;
284  }
285  }
286 
287  setDirtyFileInfo.insert(nFile);
288  return true;
289 }
290 
291 static bool FindUndoPos(BlockValidationState& state, int nFile, FlatFilePos& pos, unsigned int nAddSize)
292 {
293  pos.nFile = nFile;
294 
296 
297  pos.nPos = vinfoBlockFile[nFile].nUndoSize;
298  vinfoBlockFile[nFile].nUndoSize += nAddSize;
299  setDirtyFileInfo.insert(nFile);
300 
301  bool out_of_space;
302  size_t bytes_allocated = UndoFileSeq().Allocate(pos, nAddSize, out_of_space);
303  if (out_of_space) {
304  return AbortNode(state, "Disk space is too low!", _("Disk space is too low!"));
305  }
306  if (bytes_allocated != 0 && fPruneMode) {
307  fCheckForPruning = true;
308  }
309 
310  return true;
311 }
312 
313 static bool WriteBlockToDisk(const CBlock& block, FlatFilePos& pos, const CMessageHeader::MessageStartChars& messageStart)
314 {
315  // Open history file to append
317  if (fileout.IsNull()) {
318  return error("WriteBlockToDisk: OpenBlockFile failed");
319  }
320 
321  // Write index header
322  unsigned int nSize = GetSerializeSize(block, fileout.GetVersion());
323  fileout << messageStart << nSize;
324 
325  // Write block
326  long fileOutPos = ftell(fileout.Get());
327  if (fileOutPos < 0) {
328  return error("WriteBlockToDisk: ftell failed");
329  }
330  pos.nPos = (unsigned int)fileOutPos;
331  fileout << block;
332 
333  return true;
334 }
335 
336 bool WriteUndoDataForBlock(const CBlockUndo& blockundo, BlockValidationState& state, CBlockIndex* pindex, const CChainParams& chainparams)
337 {
338  // Write undo information to disk
339  if (pindex->GetUndoPos().IsNull()) {
340  FlatFilePos _pos;
341  if (!FindUndoPos(state, pindex->nFile, _pos, ::GetSerializeSize(blockundo, CLIENT_VERSION) + 40)) {
342  return error("ConnectBlock(): FindUndoPos failed");
343  }
344  if (!UndoWriteToDisk(blockundo, _pos, pindex->pprev->GetBlockHash(), chainparams.MessageStart())) {
345  return AbortNode(state, "Failed to write undo data");
346  }
347  // rev files are written in block height order, whereas blk files are written as blocks come in (often out of order)
348  // we want to flush the rev (undo) file once we've written the last block, which is indicated by the last height
349  // in the block file info as below; note that this does not catch the case where the undo writes are keeping up
350  // with the block writes (usually when a synced up node is getting newly mined blocks) -- this case is caught in
351  // the FindBlockPos function
352  if (_pos.nFile < nLastBlockFile && static_cast<uint32_t>(pindex->nHeight) == vinfoBlockFile[_pos.nFile].nHeightLast) {
353  FlushUndoFile(_pos.nFile, true);
354  }
355 
356  // update nUndoPos in block index
357  pindex->nUndoPos = _pos.nPos;
358  pindex->nStatus |= BLOCK_HAVE_UNDO;
359  setDirtyBlockIndex.insert(pindex);
360  }
361 
362  return true;
363 }
364 
365 bool ReadBlockFromDisk(CBlock& block, const FlatFilePos& pos, const Consensus::Params& consensusParams)
366 {
367  block.SetNull();
368 
369  // Open history file to read
370  CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
371  if (filein.IsNull()) {
372  return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
373  }
374 
375  // Read block
376  try {
377  filein >> block;
378  } catch (const std::exception& e) {
379  return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
380  }
381 
382  // Check the header
383  if (!CheckProofOfWork(block.GetHash(), block.nBits, consensusParams)) {
384  return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
385  }
386 
387  // Signet only: check block solution
388  if (consensusParams.signet_blocks && !CheckSignetBlockSolution(block, consensusParams)) {
389  return error("ReadBlockFromDisk: Errors in block solution at %s", pos.ToString());
390  }
391 
392  return true;
393 }
394 
395 bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex, const Consensus::Params& consensusParams)
396 {
397  FlatFilePos blockPos;
398  {
399  LOCK(cs_main);
400  blockPos = pindex->GetBlockPos();
401  }
402 
403  if (!ReadBlockFromDisk(block, blockPos, consensusParams)) {
404  return false;
405  }
406  if (block.GetHash() != pindex->GetBlockHash()) {
407  return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
408  pindex->ToString(), pindex->GetBlockPos().ToString());
409  }
410  return true;
411 }
412 
413 bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const FlatFilePos& pos, const CMessageHeader::MessageStartChars& message_start)
414 {
415  FlatFilePos hpos = pos;
416  hpos.nPos -= 8; // Seek back 8 bytes for meta header
417  CAutoFile filein(OpenBlockFile(hpos, true), SER_DISK, CLIENT_VERSION);
418  if (filein.IsNull()) {
419  return error("%s: OpenBlockFile failed for %s", __func__, pos.ToString());
420  }
421 
422  try {
424  unsigned int blk_size;
425 
426  filein >> blk_start >> blk_size;
427 
428  if (memcmp(blk_start, message_start, CMessageHeader::MESSAGE_START_SIZE)) {
429  return error("%s: Block magic mismatch for %s: %s versus expected %s", __func__, pos.ToString(),
430  HexStr(blk_start),
431  HexStr(message_start));
432  }
433 
434  if (blk_size > MAX_SIZE) {
435  return error("%s: Block data is larger than maximum deserialization size for %s: %s versus %s", __func__, pos.ToString(),
436  blk_size, MAX_SIZE);
437  }
438 
439  block.resize(blk_size); // Zeroing of memory is intentional here
440  filein.read((char*)block.data(), blk_size);
441  } catch (const std::exception& e) {
442  return error("%s: Read from block file failed: %s for %s", __func__, e.what(), pos.ToString());
443  }
444 
445  return true;
446 }
447 
448 bool ReadRawBlockFromDisk(std::vector<uint8_t>& block, const CBlockIndex* pindex, const CMessageHeader::MessageStartChars& message_start)
449 {
450  FlatFilePos block_pos;
451  {
452  LOCK(cs_main);
453  block_pos = pindex->GetBlockPos();
454  }
455 
456  return ReadRawBlockFromDisk(block, block_pos, message_start);
457 }
458 
460 FlatFilePos SaveBlockToDisk(const CBlock& block, int nHeight, CChain& active_chain, const CChainParams& chainparams, const FlatFilePos* dbp)
461 {
462  unsigned int nBlockSize = ::GetSerializeSize(block, CLIENT_VERSION);
463  FlatFilePos blockPos;
464  if (dbp != nullptr) {
465  blockPos = *dbp;
466  }
467  if (!FindBlockPos(blockPos, nBlockSize + 8, nHeight, active_chain, block.GetBlockTime(), dbp != nullptr)) {
468  error("%s: FindBlockPos failed", __func__);
469  return FlatFilePos();
470  }
471  if (dbp == nullptr) {
472  if (!WriteBlockToDisk(block, blockPos, chainparams.MessageStart())) {
473  AbortNode("Failed to write block");
474  return FlatFilePos();
475  }
476  }
477  return blockPos;
478 }
479 
482  {
483  assert(fImporting == false);
484  fImporting = true;
485  }
486 
488  {
489  assert(fImporting == true);
490  fImporting = false;
491  }
492 };
493 
494 void ThreadImport(ChainstateManager& chainman, std::vector<fs::path> vImportFiles, const ArgsManager& args)
495 {
497 
498  {
499  CImportingNow imp;
500 
501  // -reindex
502  if (fReindex) {
503  int nFile = 0;
504  while (true) {
505  FlatFilePos pos(nFile, 0);
506  if (!fs::exists(GetBlockPosFilename(pos))) {
507  break; // No block files left to reindex
508  }
509  FILE* file = OpenBlockFile(pos, true);
510  if (!file) {
511  break; // This error is logged in OpenBlockFile
512  }
513  LogPrintf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
514  chainman.ActiveChainstate().LoadExternalBlockFile(file, &pos);
515  if (ShutdownRequested()) {
516  LogPrintf("Shutdown requested. Exit %s\n", __func__);
517  return;
518  }
519  nFile++;
520  }
521  pblocktree->WriteReindexing(false);
522  fReindex = false;
523  LogPrintf("Reindexing finished\n");
524  // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
525  chainman.ActiveChainstate().LoadGenesisBlock();
526  }
527 
528  // -loadblock=
529  for (const fs::path& path : vImportFiles) {
530  FILE* file = fsbridge::fopen(path, "rb");
531  if (file) {
532  LogPrintf("Importing blocks file %s...\n", path.string());
533  chainman.ActiveChainstate().LoadExternalBlockFile(file);
534  if (ShutdownRequested()) {
535  LogPrintf("Shutdown requested. Exit %s\n", __func__);
536  return;
537  }
538  } else {
539  LogPrintf("Warning: Could not open blocks file %s\n", path.string());
540  }
541  }
542 
543  // scan for better chains in the block chain database, that are not yet connected in the active best chain
544 
545  // We can't hold cs_main during ActivateBestChain even though we're accessing
546  // the chainman unique_ptrs since ABC requires us not to be holding cs_main, so retrieve
547  // the relevant pointers before the ABC call.
548  for (CChainState* chainstate : WITH_LOCK(::cs_main, return chainman.GetAll())) {
549  BlockValidationState state;
550  if (!chainstate->ActivateBestChain(state, nullptr)) {
551  LogPrintf("Failed to connect best block (%s)\n", state.ToString());
552  StartShutdown();
553  return;
554  }
555  }
556 
557  if (args.GetBoolArg("-stopafterblockimport", DEFAULT_STOPAFTERBLOCKIMPORT)) {
558  LogPrintf("Stopping after block import\n");
559  StartShutdown();
560  return;
561  }
562  } // End scope of CImportingNow
563  chainman.ActiveChainstate().LoadMempool(args);
564 }
std::atomic_bool fImporting(false)
static FlatFileSeq BlockFileSeq()
std::string ToString() const
Definition: chain.h:286
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition: shutdown.cpp:87
#define LogPrint(category,...)
Definition: logging.h:188
assert(!tx.IsCoinBase())
FILE * fopen(const fs::path &p, const char *mode)
Definition: fs.cpp:24
std::string FormatISO8601Date(int64_t nTime)
Definition: time.cpp:145
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:144
std::set< CBlockIndex * > setDirtyBlockIndex
Dirty block index entries.
uint32_t nStatus
Verification status of this block.
Definition: chain.h:187
std::vector< CBlockFileInfo > vinfoBlockFile
Definition: block.h:62
Provides an interface for creating and interacting with one or two chainstates: an IBD chainstate gen...
Definition: validation.h:866
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1164
static const unsigned int MAX_BLOCKFILE_SIZE
The maximum size of a blk?????.dat file (since 0.8)
Definition: blockstorage.h:36
An in-memory indexed chain of blocks.
Definition: chain.h:392
static FILE * OpenUndoFile(const FlatFilePos &pos, bool fReadOnly=false)
Open an undo file (rev?????.dat)
bool IsNull() const
Definition: flatfile.h:37
unsigned int nHeight
CChainState stores and provides an API to update our local knowledge of the current best chain...
Definition: validation.h:561
unsigned int nSize
number of used bytes of block file
Definition: chain.h:44
void FlushBlockFile(bool fFinalize=false, bool finalize_undo=false)
bool FindBlockPos(FlatFilePos &pos, unsigned int nAddSize, unsigned int nHeight, CChain &active_chain, uint64_t nTime, bool fKnown=false)
FlatFilePos GetBlockPos() const
Definition: chain.h:215
CChainParams defines various tweakable parameters of a given instance of the Bitcoin system...
Definition: chainparams.h:69
undo data available in rev*.dat
Definition: chain.h:122
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:600
int nFile
Which # file this block is stored in (blk?????.dat)
Definition: chain.h:153
bool IsBlockPruned(const CBlockIndex *pblockindex)
Check whether the block associated with this index entry is pruned or not.
int nFile
Definition: flatfile.h:16
int GetVersion() const
Definition: streams.h:615
int nLastBlockFile
unsigned int nHeightLast
highest height of block in file
Definition: chain.h:47
Reads data from an underlying stream, while hashing the read data.
Definition: hash.h:157
bool IsNull() const
Return true if the wrapped FILE* is nullptr, false otherwise.
Definition: streams.h:609
FILE * Open(const FlatFilePos &pos, bool read_only=false)
Open a handle to the file at the given position.
Definition: flatfile.cpp:33
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1080
void LoadMempool(const ArgsManager &args)
Load the persisted mempool from disk.
uint256 GetBlockHash() const
Definition: chain.h:246
bool WriteUndoDataForBlock(const CBlockUndo &blockundo, BlockValidationState &state, CBlockIndex *pindex, const CChainParams &chainparams)
RecursiveMutex cs_LastBlockFile
std::string ToString(const T &t)
Locale-independent version of std::to_string.
Definition: string.h:79
uint64_t nPruneTarget
Number of MiB of block files that we&#39;re trying to stay below.
uint64_t nTimeFirst
earliest time of block in file
Definition: chain.h:48
bool fPruneMode
True if we&#39;re running in -prune mode.
#define LOCK(cs)
Definition: sync.h:232
static bool WriteBlockToDisk(const CBlock &block, FlatFilePos &pos, const CMessageHeader::MessageStartChars &messageStart)
std::string ToString() const
Definition: validation.h:125
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:57
int atoi(const std::string &str)
static bool UndoWriteToDisk(const CBlockUndo &blockundo, FlatFilePos &pos, const uint256 &hashBlock, const CMessageHeader::MessageStartChars &messageStart)
bool signet_blocks
If true, witness commitments contain a payload equal to a Bitcoin Script solution to the signet chall...
Definition: params.h:115
std::atomic_bool fReindex(false)
bool UndoReadFromDisk(CBlockUndo &blockundo, const CBlockIndex *pindex)
fs::path GetBlockPosFilename(const FlatFilePos &pos)
Translation to a filesystem path.
unsigned int nHeightFirst
lowest height of block in file
Definition: chain.h:46
bool fCheckForPruning
Global flag to indicate we should check to see if there are block/undo files that should be deleted...
const CMessageHeader::MessageStartChars & MessageStart() const
Definition: chainparams.h:83
void read(char *pch, size_t nSize)
Definition: streams.h:617
Parameters that influence chain consensus.
Definition: params.h:70
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:74
int64_t GetBlockTime() const
Definition: block.h:55
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
Definition: sync.h:276
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
unsigned char MessageStartChars[MESSAGE_START_SIZE]
Definition: protocol.h:40
size_t Allocate(const FlatFilePos &pos, size_t add_size, bool &out_of_space)
Allocate additional space in a file after the given starting position.
Definition: flatfile.cpp:55
static constexpr size_t MESSAGE_START_SIZE
Definition: protocol.h:33
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: validation.cpp:115
unsigned int nUndoPos
Byte offset within rev?????.dat where this block&#39;s undo data is stored.
Definition: chain.h:159
uint256 GetHash()
Compute the double-SHA256 hash of all data written to this object.
Definition: hash.h:122
uint256 GetHash() const
Definition: block.cpp:11
std::string ToString() const
Definition: flatfile.cpp:23
256-bit opaque blob.
Definition: uint256.h:124
CChainState &InitializeChainstate(CTxMemPool *mempool, const std::optional< uint256 > &snapshot_blockhash=std::nullopt) EXCLUSIVE_LOCKS_REQUIRED(std::vector< CChainState * GetAll)()
Instantiate a new chainstate and assign it based upon whether it is from a snapshot.
Definition: validation.h:945
FlatFilePos SaveBlockToDisk(const CBlock &block, int nHeight, CChain &active_chain, const CChainParams &chainparams, const FlatFilePos *dbp)
Store block on disk.
FILE * Get() const
Get wrapped FILE* without transfer of ownership.
Definition: streams.h:605
void UnlinkPrunedFiles(const std::set< int > &setFilesToPrune)
Actually unlink the specified files.
fs::path FileName(const FlatFilePos &pos) const
Get the name of the file at the given position.
Definition: flatfile.cpp:28
void SetNull()
Definition: block.h:88
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:137
Undo information for a CBlock.
Definition: undo.h:63
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:12
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:403
ArgsManager gArgs
Definition: system.cpp:84
unsigned int nBlocks
number of blocks stored in file
Definition: chain.h:43
static constexpr uint64_t MAX_SIZE
The maximum size of a serialized object in bytes or number of elements (for eg vectors) when the size...
Definition: serialize.h:31
std::unique_ptr< CBlockTreeDB > pblocktree
Global variable that points to the active block tree (protected by cs_main)
Definition: validation.cpp:173
static FlatFileSeq UndoFileSeq()
std::set< int > setDirtyFileInfo
Dirty block file entries.
void StartShutdown()
Request shutdown of the application.
Definition: shutdown.cpp:56
bool ReadRawBlockFromDisk(std::vector< uint8_t > &block, const FlatFilePos &pos, const CMessageHeader::MessageStartChars &message_start)
FlatFilePos GetUndoPos() const
Definition: chain.h:224
A writer stream (for serialization) that computes a 256-bit hash.
Definition: hash.h:100
const fs::path & GetBlocksDirPath() const
Get blocks directory path.
Definition: system.cpp:397
uint64_t nTimeLast
latest time of block in file
Definition: chain.h:49
CBlockFileInfo * GetBlockFileInfo(size_t n)
Get block file info entry for one block file.
CChainState & ActiveChainstate() const
The most-work chain.
void CleanupBlockRevFiles()
static bool FindUndoPos(BlockValidationState &state, int nFile, FlatFilePos &pos, unsigned int nAddSize)
void ScheduleBatchPriority()
On platforms that support it, tell the kernel the calling thread is CPU-intensive and non-interactive...
Definition: system.cpp:1370
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:150
bool LoadGenesisBlock()
Ensures we have a genesis block in the block tree, possibly writing one to disk.
full block available in blk*.dat
Definition: chain.h:121
bool fHavePruned
Pruning-related variables and constants.
void ThreadImport(ChainstateManager &chainman, std::vector< fs::path > vImportFiles, const ArgsManager &args)
static constexpr bool DEFAULT_STOPAFTERBLOCKIMPORT
Definition: blockstorage.h:29
#define LogPrintf(...)
Definition: logging.h:184
std::string ToString() const
FlatFileSeq represents a sequence of numbered files storing raw data.
Definition: flatfile.h:46
static const int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:33
unsigned int nPos
Definition: flatfile.h:17
static const unsigned int UNDOFILE_CHUNK_SIZE
The pre-allocation chunk size for rev?????.dat files (since 0.8)
Definition: blockstorage.h:34
bool error(const char *fmt, const Args &... args)
Definition: system.h:49
FILE * OpenBlockFile(const FlatFilePos &pos, bool fReadOnly)
Open a block file (blk?????.dat)
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &consensusParams)
Functions for disk access for blocks.
uint64_t CalculateCurrentUsage()
Calculate the amount of disk space the block & undo files currently use.
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:169
Non-refcounted RAII wrapper for FILE*.
Definition: streams.h:564
bool AbortNode(const std::string &strMessage, bilingual_str user_message)
Abort with a message.
Definition: shutdown.cpp:21
uint32_t nBits
Definition: block.h:28
static void FlushUndoFile(int block_file, bool finalize=false)
bool CheckSignetBlockSolution(const CBlock &block, const Consensus::Params &consensusParams)
Extract signature and check whether a block has a valid solution.
Definition: signet.cpp:124
static const unsigned int BLOCKFILE_CHUNK_SIZE
The pre-allocation chunk size for blk?????.dat files (since 0.8)
Definition: blockstorage.h:32