Bitcoin ABC  0.28.12
P2P Digital Currency
txdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <txdb.h>
7 
8 #include <chain.h>
9 #include <node/ui_interface.h>
10 #include <pow/pow.h>
11 #include <random.h>
12 #include <shutdown.h>
13 #include <util/system.h>
14 #include <util/translation.h>
15 #include <util/vector.h>
16 #include <version.h>
17 
18 #include <cstdint>
19 #include <memory>
20 
21 static const char DB_COIN = 'C';
22 static const char DB_COINS = 'c';
23 static const char DB_BLOCK_FILES = 'f';
24 static const char DB_BLOCK_INDEX = 'b';
25 
26 static const char DB_BEST_BLOCK = 'B';
27 static const char DB_HEAD_BLOCKS = 'H';
28 static const char DB_FLAG = 'F';
29 static const char DB_REINDEX_FLAG = 'R';
30 static const char DB_LAST_BLOCK = 'l';
31 
32 // Keys used in previous version that might still be found in the DB:
33 static constexpr uint8_t DB_TXINDEX_BLOCK{'T'};
34 // uint8_t DB_TXINDEX{'t'}
35 
37  CBlockLocator ignored{};
38  if (block_tree_db.Read(DB_TXINDEX_BLOCK, ignored)) {
39  return util::Error{
40  _("The -txindex upgrade started by a previous version can not "
41  "be completed. Restart with the previous version or run a "
42  "full -reindex.")};
43  }
44  bool txindex_legacy_flag{false};
45  block_tree_db.ReadFlag("txindex", txindex_legacy_flag);
46  if (txindex_legacy_flag) {
47  // Disable legacy txindex and warn once about occupied disk space
48  if (!block_tree_db.WriteFlag("txindex", false)) {
50  "Failed to write block index db flag 'txindex'='0'")};
51  }
52  return util::Error{
53  _("The block index db contains a legacy 'txindex'. To clear the "
54  "occupied disk space, run a full -reindex, otherwise ignore "
55  "this error. This error message will not be displayed again.")};
56  }
57  return {};
58 }
59 
60 namespace {
61 
62 struct CoinEntry {
63  COutPoint *outpoint;
64  char key;
65  explicit CoinEntry(const COutPoint *ptr)
66  : outpoint(const_cast<COutPoint *>(ptr)), key(DB_COIN) {}
67 
68  SERIALIZE_METHODS(CoinEntry, obj) {
69  TxId id = obj.outpoint->GetTxId();
70  uint32_t n = obj.outpoint->GetN();
71  READWRITE(obj.key, id, VARINT(n));
72  SER_READ(obj, *obj.outpoint = COutPoint(id, n));
73  }
74 };
75 } // namespace
76 
77 CCoinsViewDB::CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory,
78  bool fWipe)
79  : m_db(std::make_unique<CDBWrapper>(ldb_path, nCacheSize, fMemory, fWipe,
80  true)),
81  m_ldb_path(ldb_path), m_is_memory(fMemory) {}
82 
83 void CCoinsViewDB::ResizeCache(size_t new_cache_size) {
84  // We can't do this operation with an in-memory DB since we'll lose all the
85  // coins upon reset.
86  if (!m_is_memory) {
87  // Have to do a reset first to get the original `m_db` state to release
88  // its filesystem lock.
89  m_db.reset();
90  m_db = std::make_unique<CDBWrapper>(m_ldb_path, new_cache_size,
91  m_is_memory, /*fWipe*/ false,
92  /*obfuscate*/ true);
93  }
94 }
95 
96 bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
97  return m_db->Read(CoinEntry(&outpoint), coin);
98 }
99 
100 bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
101  return m_db->Exists(CoinEntry(&outpoint));
102 }
103 
105  BlockHash hashBestChain;
106  if (!m_db->Read(DB_BEST_BLOCK, hashBestChain)) {
107  return BlockHash();
108  }
109  return hashBestChain;
110 }
111 
112 std::vector<BlockHash> CCoinsViewDB::GetHeadBlocks() const {
113  std::vector<BlockHash> vhashHeadBlocks;
114  if (!m_db->Read(DB_HEAD_BLOCKS, vhashHeadBlocks)) {
115  return std::vector<BlockHash>();
116  }
117  return vhashHeadBlocks;
118 }
119 
120 bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const BlockHash &hashBlock) {
121  CDBBatch batch(*m_db);
122  size_t count = 0;
123  size_t changed = 0;
124  size_t batch_size =
125  (size_t)gArgs.GetIntArg("-dbbatchsize", DEFAULT_DB_BATCH_SIZE);
126  int crash_simulate = gArgs.GetIntArg("-dbcrashratio", 0);
127  assert(!hashBlock.IsNull());
128 
129  BlockHash old_tip = GetBestBlock();
130  if (old_tip.IsNull()) {
131  // We may be in the middle of replaying.
132  std::vector<BlockHash> old_heads = GetHeadBlocks();
133  if (old_heads.size() == 2) {
134  assert(old_heads[0] == hashBlock);
135  old_tip = old_heads[1];
136  }
137  }
138 
139  // In the first batch, mark the database as being in the middle of a
140  // transition from old_tip to hashBlock.
141  // A vector is used for future extensibility, as we may want to support
142  // interrupting after partial writes from multiple independent reorgs.
143  batch.Erase(DB_BEST_BLOCK);
144  batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip));
145 
146  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
147  if (it->second.flags & CCoinsCacheEntry::DIRTY) {
148  CoinEntry entry(&it->first);
149  if (it->second.coin.IsSpent()) {
150  batch.Erase(entry);
151  } else {
152  batch.Write(entry, it->second.coin);
153  }
154  changed++;
155  }
156  count++;
157  CCoinsMap::iterator itOld = it++;
158  mapCoins.erase(itOld);
159  if (batch.SizeEstimate() > batch_size) {
160  LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n",
161  batch.SizeEstimate() * (1.0 / 1048576.0));
162  m_db->WriteBatch(batch);
163  batch.Clear();
164  if (crash_simulate) {
165  static FastRandomContext rng;
166  if (rng.randrange(crash_simulate) == 0) {
167  LogPrintf("Simulating a crash. Goodbye.\n");
168  _Exit(0);
169  }
170  }
171  }
172  }
173 
174  // In the last batch, mark the database as consistent with hashBlock again.
175  batch.Erase(DB_HEAD_BLOCKS);
176  batch.Write(DB_BEST_BLOCK, hashBlock);
177 
178  LogPrint(BCLog::COINDB, "Writing final batch of %.2f MiB\n",
179  batch.SizeEstimate() * (1.0 / 1048576.0));
180  bool ret = m_db->WriteBatch(batch);
182  "Committed %u changed transaction outputs (out of "
183  "%u) to coin database...\n",
184  (unsigned int)changed, (unsigned int)count);
185  return ret;
186 }
187 
189  return m_db->EstimateSize(DB_COIN, char(DB_COIN + 1));
190 }
191 
192 CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe)
193  : CDBWrapper(gArgs.GetDataDirNet() / "blocks" / "index", nCacheSize,
194  fMemory, fWipe) {}
195 
197  return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
198 }
199 
200 bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
201  if (fReindexing) {
202  return Write(DB_REINDEX_FLAG, '1');
203  } else {
204  return Erase(DB_REINDEX_FLAG);
205  }
206 }
207 
209  return Exists(DB_REINDEX_FLAG);
210 }
211 
213  return Read(DB_LAST_BLOCK, nFile);
214 }
215 
218  const_cast<CDBWrapper &>(*m_db).NewIterator(), GetBestBlock());
224  i->pcursor->Seek(DB_COIN);
225  // Cache key of first record
226  if (i->pcursor->Valid()) {
227  CoinEntry entry(&i->keyTmp.second);
228  i->pcursor->GetKey(entry);
229  i->keyTmp.first = entry.key;
230  } else {
231  // Make sure Valid() and GetKey() return false
232  i->keyTmp.first = 0;
233  }
234  return i;
235 }
236 
238  // Return cached key
239  if (keyTmp.first == DB_COIN) {
240  key = keyTmp.second;
241  return true;
242  }
243  return false;
244 }
245 
247  return pcursor->GetValue(coin);
248 }
249 
250 unsigned int CCoinsViewDBCursor::GetValueSize() const {
251  return pcursor->GetValueSize();
252 }
253 
255  return keyTmp.first == DB_COIN;
256 }
257 
259  pcursor->Next();
260  CoinEntry entry(&keyTmp.second);
261  if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
262  // Invalidate cached key after last record so that Valid() and GetKey()
263  // return false
264  keyTmp.first = 0;
265  } else {
266  keyTmp.first = entry.key;
267  }
268 }
269 
271  const std::vector<std::pair<int, const CBlockFileInfo *>> &fileInfo,
272  int nLastFile, const std::vector<const CBlockIndex *> &blockinfo) {
273  CDBBatch batch(*this);
274  for (std::vector<std::pair<int, const CBlockFileInfo *>>::const_iterator
275  it = fileInfo.begin();
276  it != fileInfo.end(); it++) {
277  batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
278  }
279  batch.Write(DB_LAST_BLOCK, nLastFile);
280  for (std::vector<const CBlockIndex *>::const_iterator it =
281  blockinfo.begin();
282  it != blockinfo.end(); it++) {
283  batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()),
284  CDiskBlockIndex(*it));
285  }
286  return WriteBatch(batch, true);
287 }
288 
289 bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
290  return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
291 }
292 
293 bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
294  char ch;
295  if (!Read(std::make_pair(DB_FLAG, name), ch)) {
296  return false;
297  }
298  fValue = ch == '1';
299  return true;
300 }
301 
303  const Consensus::Params &params,
304  std::function<CBlockIndex *(const BlockHash &)> insertBlockIndex) {
306  std::unique_ptr<CDBIterator> pcursor(NewIterator());
307 
308  uint64_t version = 0;
309  pcursor->Seek("version");
310  if (pcursor->Valid()) {
311  pcursor->GetValue(version);
312  }
313 
314  if (version != CLIENT_VERSION) {
315  return error("%s: Invalid block index database version: %s", __func__,
316  version);
317  }
318 
319  pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
320 
321  // Load m_block_index
322  while (pcursor->Valid()) {
323  if (ShutdownRequested()) {
324  return false;
325  }
326  std::pair<char, uint256> key;
327  if (!pcursor->GetKey(key) || key.first != DB_BLOCK_INDEX) {
328  break;
329  }
330 
331  CDiskBlockIndex diskindex;
332  if (!pcursor->GetValue(diskindex)) {
333  return error("%s : failed to read value", __func__);
334  }
335 
336  // Construct block index object
337  CBlockIndex *pindexNew = insertBlockIndex(diskindex.GetBlockHash());
338  pindexNew->pprev = insertBlockIndex(diskindex.hashPrev);
339  pindexNew->nHeight = diskindex.nHeight;
340  pindexNew->nFile = diskindex.nFile;
341  pindexNew->nDataPos = diskindex.nDataPos;
342  pindexNew->nUndoPos = diskindex.nUndoPos;
343  pindexNew->nVersion = diskindex.nVersion;
344  pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
345  pindexNew->nTime = diskindex.nTime;
346  pindexNew->nBits = diskindex.nBits;
347  pindexNew->nNonce = diskindex.nNonce;
348  pindexNew->nStatus = diskindex.nStatus;
349  pindexNew->nTx = diskindex.nTx;
350 
351  if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits,
352  params)) {
353  return error("%s: CheckProofOfWork failed: %s", __func__,
354  pindexNew->ToString());
355  }
356 
357  pcursor->Next();
358  }
359 
360  return true;
361 }
362 
363 namespace {
365 class CCoins {
366 public:
368  bool fCoinBase;
369 
372  std::vector<CTxOut> vout;
373 
375  int nHeight;
376 
378  CCoins() : fCoinBase(false), vout(0), nHeight(0) {}
379 
380  template <typename Stream> void Unserialize(Stream &s) {
381  uint32_t nCode = 0;
382  // version
383  unsigned int nVersionDummy = 0;
384  ::Unserialize(s, VARINT(nVersionDummy));
385  // header code
386  ::Unserialize(s, VARINT(nCode));
387  fCoinBase = nCode & 1;
388  std::vector<bool> vAvail(2, false);
389  vAvail[0] = (nCode & 2) != 0;
390  vAvail[1] = (nCode & 4) != 0;
391  uint32_t nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
392  // spentness bitmask
393  while (nMaskCode > 0) {
394  uint8_t chAvail = 0;
395  ::Unserialize(s, chAvail);
396  for (unsigned int p = 0; p < 8; p++) {
397  bool f = (chAvail & (1 << p)) != 0;
398  vAvail.push_back(f);
399  }
400  if (chAvail != 0) {
401  nMaskCode--;
402  }
403  }
404  // txouts themself
405  vout.assign(vAvail.size(), CTxOut());
406  for (size_t i = 0; i < vAvail.size(); i++) {
407  if (vAvail[i]) {
408  ::Unserialize(s, Using<TxOutCompression>(vout[i]));
409  }
410  }
411  // coinbase height
413  }
414 };
415 } // namespace
416 
423  std::unique_ptr<CDBIterator> pcursor(m_db->NewIterator());
424  pcursor->Seek(std::make_pair(DB_COINS, uint256()));
425  if (!pcursor->Valid()) {
426  return true;
427  }
428 
429  int64_t count = 0;
430  LogPrintf("Upgrading utxo-set database...\n");
431  size_t batch_size = 1 << 24;
432  CDBBatch batch(*m_db);
433  int reportDone = -1;
434  std::pair<uint8_t, uint256> key;
435  std::pair<uint8_t, uint256> prev_key = {DB_COINS, uint256()};
436  while (pcursor->Valid()) {
437  if (ShutdownRequested()) {
438  break;
439  }
440 
441  if (!pcursor->GetKey(key) || key.first != DB_COINS) {
442  break;
443  }
444 
445  if (count++ % 256 == 0) {
446  uint32_t high =
447  0x100 * *key.second.begin() + *(key.second.begin() + 1);
448  int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
449  uiInterface.ShowProgress(_("Upgrading UTXO database").translated,
450  percentageDone, true);
451  if (reportDone < percentageDone / 10) {
452  // report max. every 10% step
453  LogPrintfToBeContinued("[%d%%]...", percentageDone);
454  reportDone = percentageDone / 10;
455  }
456  }
457 
458  CCoins old_coins;
459  if (!pcursor->GetValue(old_coins)) {
460  return error("%s: cannot parse CCoins record", __func__);
461  }
462 
463  const TxId id(key.second);
464  for (size_t i = 0; i < old_coins.vout.size(); ++i) {
465  if (!old_coins.vout[i].IsNull() &&
466  !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
467  Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight,
468  old_coins.fCoinBase);
469  COutPoint outpoint(id, i);
470  CoinEntry entry(&outpoint);
471  batch.Write(entry, newcoin);
472  }
473  }
474 
475  batch.Erase(key);
476  if (batch.SizeEstimate() > batch_size) {
477  m_db->WriteBatch(batch);
478  batch.Clear();
479  m_db->CompactRange(prev_key, key);
480  prev_key = key;
481  }
482 
483  pcursor->Next();
484  }
485 
486  m_db->WriteBatch(batch);
487  m_db->CompactRange({DB_COINS, uint256()}, key);
488  uiInterface.ShowProgress("", 100, false);
489  LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
490  return !ShutdownRequested();
491 }
492 
494  // This method used to add the block size to pre-0.22.8 block index
495  // databases. This is no longer supported as of 0.25.5, but the method is
496  // kept to update the version number in the database.
497  std::unique_ptr<CDBIterator> pcursor(NewIterator());
498 
499  uint64_t version = 0;
500  pcursor->Seek("version");
501  if (pcursor->Valid()) {
502  pcursor->GetValue(version);
503  }
504 
505  if (version >= CLIENT_VERSION) {
506  // The DB is already up to date.
507  return true;
508  }
509 
510  pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
511 
512  // The DB is not empty, and the version is either non-existent or too old.
513  // The node requires a reindex.
514  if (pcursor->Valid() && version < CDiskBlockIndex::TRACK_SIZE_VERSION) {
515  LogPrintf(
516  "\nThe database is too old. The block index cannot be upgraded "
517  "and reindexing is required.\n");
518  return false;
519  }
520 
521  // The DB is empty or recent enough.
522  // Just write the new version number and consider the upgrade done.
523  CDBBatch batch(*this);
524  LogPrintf("Updating the block index database version to %d\n",
526  batch.Write("version", uint64_t(CLIENT_VERSION));
527  return WriteBatch(batch);
528 }
int64_t GetIntArg(const std::string &strArg, int64_t nDefault) const
Return integer argument or default value.
Definition: system.cpp:635
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:26
uint256 hashMerkleRoot
Definition: blockindex.h:92
std::string ToString() const
Definition: blockindex.h:205
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:33
uint32_t nTime
Definition: blockindex.h:93
uint32_t nNonce
Definition: blockindex.h:95
uint32_t nBits
Definition: blockindex.h:94
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:61
int32_t nVersion
block header
Definition: blockindex.h:91
BlockHash GetBlockHash() const
Definition: blockindex.h:147
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:39
Access to the block database (blocks/index/)
Definition: txdb.h:112
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
Definition: txdb.cpp:196
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * >> &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
Definition: txdb.cpp:270
CBlockTreeDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:192
bool Upgrade()
Attempt to update from an older database format.
Definition: txdb.cpp:493
bool WriteReindexing(bool fReindexing)
Definition: txdb.cpp:200
bool IsReindexing() const
Definition: txdb.cpp:208
bool ReadFlag(const std::string &name, bool &fValue)
Definition: txdb.cpp:293
bool ReadLastBlockFile(int &nFile)
Definition: txdb.cpp:212
bool LoadBlockIndexGuts(const Consensus::Params &params, std::function< CBlockIndex *(const BlockHash &)> insertBlockIndex) EXCLUSIVE_LOCKS_REQUIRED(
Definition: txdb.h:126
bool WriteFlag(const std::string &name, bool fValue)
Definition: txdb.cpp:289
Cursor for iterating over CoinsView state.
Definition: coins.h:127
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
Definition: txdb.h:91
std::unique_ptr< CDBIterator > pcursor
Definition: txdb.h:105
bool GetKey(COutPoint &key) const override
Definition: txdb.cpp:237
bool GetValue(Coin &coin) const override
Definition: txdb.cpp:246
bool Valid() const override
Definition: txdb.cpp:254
unsigned int GetValueSize() const override
Definition: txdb.cpp:250
void Next() override
Definition: txdb.cpp:258
std::pair< char, COutPoint > keyTmp
Definition: txdb.h:106
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: txdb.cpp:104
std::vector< BlockHash > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: txdb.cpp:112
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txdb.cpp:96
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: txdb.cpp:100
bool m_is_memory
Definition: txdb.h:60
std::unique_ptr< CDBWrapper > m_db
Definition: txdb.h:58
bool Upgrade()
Attempt to update from an older database format.
Definition: txdb.cpp:422
bool BatchWrite(CCoinsMap &mapCoins, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: txdb.cpp:120
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: txdb.cpp:216
CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory, bool fWipe)
Definition: txdb.cpp:77
fs::path m_ldb_path
Definition: txdb.h:59
void ResizeCache(size_t new_cache_size) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Dynamically alter the underlying leveldb cache size.
Definition: txdb.cpp:83
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: txdb.cpp:188
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:54
void Erase(const K &key)
Definition: dbwrapper.h:103
size_t SizeEstimate() const
Definition: dbwrapper.h:118
void Write(const K &key, const V &value)
Definition: dbwrapper.h:79
void Clear()
Definition: dbwrapper.h:74
CDBIterator * NewIterator()
Definition: dbwrapper.h:307
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:195
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:241
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:296
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:266
bool Exists(const K &key) const
Definition: dbwrapper.h:280
Used to marshal pointers into hashes for db storage.
Definition: chain.h:70
BlockHash GetBlockHash() const
Definition: chain.h:117
BlockHash hashPrev
Definition: chain.h:74
static constexpr int TRACK_SIZE_VERSION
Definition: chain.h:72
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:20
An output of a transaction.
Definition: transaction.h:128
A UTXO entry.
Definition: coins.h:27
Fast randomness source.
Definition: random.h:156
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:231
uint8_t * begin()
Definition: uint256.h:83
bool IsNull() const
Definition: uint256.h:30
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:30
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:38
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher > CCoinsMap
Definition: coins.h:124
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:7
#define LogPrint(category,...)
Definition: logging.h:210
#define LogPrintfToBeContinued
These are aliases used to explicitly state that the message should not end with a newline character.
Definition: logging.h:222
#define LogPrintf(...)
Definition: logging.h:206
unsigned int nHeight
@ COINDB
Definition: logging.h:58
Implement std::hash so RCUPtr can be used as a key for maps or sets.
Definition: rcu.h:257
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:91
const char * name
Definition: rest.cpp:48
#define VARINT(obj)
Definition: serialize.h:597
#define VARINT_MODE(obj, mode)
Definition: serialize.h:596
@ NONNEGATIVE_SIGNED
#define SERIALIZE_METHODS(cls, obj)
Implement the Serialize and Unserialize methods by delegating to a single templated static method tha...
Definition: serialize.h:227
void Unserialize(Stream &s, char &a)
Definition: serialize.h:294
#define SER_READ(obj, code)
Definition: serialize.h:183
#define READWRITE(...)
Definition: serialize.h:180
bool ShutdownRequested()
Returns true if a shutdown is requested, false otherwise.
Definition: shutdown.cpp:85
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:105
@ DIRTY
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache.
Definition: coins.h:103
Parameters that influence chain consensus.
Definition: params.h:34
A TxId is the identifier of a transaction.
Definition: txid.h:14
std::string translated
Definition: translation.h:19
ArgsManager gArgs
Definition: system.cpp:80
bool error(const char *fmt, const Args &...args)
Definition: system.h:45
static int count
Definition: tests.c:31
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:68
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:36
static constexpr uint8_t DB_TXINDEX_BLOCK
Definition: txdb.cpp:33
static const char DB_BLOCK_FILES
Definition: txdb.cpp:23
static const char DB_REINDEX_FLAG
Definition: txdb.cpp:29
static const char DB_COINS
Definition: txdb.cpp:22
static const char DB_HEAD_BLOCKS
Definition: txdb.cpp:27
util::Result< void > CheckLegacyTxindex(CBlockTreeDB &block_tree_db)
Definition: txdb.cpp:36
static const char DB_LAST_BLOCK
Definition: txdb.cpp:30
static const char DB_BLOCK_INDEX
Definition: txdb.cpp:24
static const char DB_COIN
Definition: txdb.cpp:21
static const char DB_FLAG
Definition: txdb.cpp:28
static const char DB_BEST_BLOCK
Definition: txdb.cpp:26
static constexpr int64_t DEFAULT_DB_BATCH_SIZE
-dbbatchsize default (bytes)
Definition: txdb.h:42
CClientUIInterface uiInterface
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())
std::vector< typename std::common_type< Args... >::type > Vector(Args &&...args)
Construct a vector with the specified elements.
Definition: vector.h:21