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