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