Bitcoin ABC  0.22.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 <blockdb.h>
9 #include <chain.h>
10 #include <node/ui_interface.h>
11 #include <pow/pow.h>
12 #include <random.h>
13 #include <shutdown.h>
14 #include <util/system.h>
15 #include <util/translation.h>
16 #include <util/vector.h>
17 #include <version.h>
18 
19 #include <boost/thread.hpp> // boost::this_thread::interruption_point() (mingw)
20 
21 #include <cstdint>
22 
23 static const char DB_COIN = 'C';
24 static const char DB_COINS = 'c';
25 static const char DB_BLOCK_FILES = 'f';
26 static const char DB_BLOCK_INDEX = 'b';
27 
28 static const char DB_BEST_BLOCK = 'B';
29 static const char DB_HEAD_BLOCKS = 'H';
30 static const char DB_FLAG = 'F';
31 static const char DB_REINDEX_FLAG = 'R';
32 static const char DB_LAST_BLOCK = 'l';
33 
34 namespace {
35 
36 struct CoinEntry {
37  COutPoint *outpoint;
38  char key;
39  explicit CoinEntry(const COutPoint *ptr)
40  : outpoint(const_cast<COutPoint *>(ptr)), key(DB_COIN) {}
41 
42  template <typename Stream> void Serialize(Stream &s) const {
43  s << key;
44  s << outpoint->GetTxId();
45  s << VARINT(outpoint->GetN());
46  }
47 
48  template <typename Stream> void Unserialize(Stream &s) {
49  s >> key;
50  TxId id;
51  s >> id;
52  uint32_t n = 0;
53  s >> VARINT(n);
54  *outpoint = COutPoint(id, n);
55  }
56 };
57 } // namespace
58 
59 CCoinsViewDB::CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory,
60  bool fWipe)
61  : db(ldb_path, nCacheSize, fMemory, fWipe, true) {}
62 
63 bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
64  return db.Read(CoinEntry(&outpoint), coin);
65 }
66 
67 bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
68  return db.Exists(CoinEntry(&outpoint));
69 }
70 
72  BlockHash hashBestChain;
73  if (!db.Read(DB_BEST_BLOCK, hashBestChain)) {
74  return BlockHash();
75  }
76  return hashBestChain;
77 }
78 
79 std::vector<BlockHash> CCoinsViewDB::GetHeadBlocks() const {
80  std::vector<BlockHash> vhashHeadBlocks;
81  if (!db.Read(DB_HEAD_BLOCKS, vhashHeadBlocks)) {
82  return std::vector<BlockHash>();
83  }
84  return vhashHeadBlocks;
85 }
86 
87 bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const BlockHash &hashBlock) {
88  CDBBatch batch(db);
89  size_t count = 0;
90  size_t changed = 0;
91  size_t batch_size =
92  (size_t)gArgs.GetArg("-dbbatchsize", DEFAULT_DB_BATCH_SIZE);
93  int crash_simulate = gArgs.GetArg("-dbcrashratio", 0);
94  assert(!hashBlock.IsNull());
95 
96  BlockHash old_tip = GetBestBlock();
97  if (old_tip.IsNull()) {
98  // We may be in the middle of replaying.
99  std::vector<BlockHash> old_heads = GetHeadBlocks();
100  if (old_heads.size() == 2) {
101  assert(old_heads[0] == hashBlock);
102  old_tip = old_heads[1];
103  }
104  }
105 
106  // In the first batch, mark the database as being in the middle of a
107  // transition from old_tip to hashBlock.
108  // A vector is used for future extensibility, as we may want to support
109  // interrupting after partial writes from multiple independent reorgs.
110  batch.Erase(DB_BEST_BLOCK);
111  batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip));
112 
113  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
114  if (it->second.flags & CCoinsCacheEntry::DIRTY) {
115  CoinEntry entry(&it->first);
116  if (it->second.coin.IsSpent()) {
117  batch.Erase(entry);
118  } else {
119  batch.Write(entry, it->second.coin);
120  }
121  changed++;
122  }
123  count++;
124  CCoinsMap::iterator itOld = it++;
125  mapCoins.erase(itOld);
126  if (batch.SizeEstimate() > batch_size) {
127  LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n",
128  batch.SizeEstimate() * (1.0 / 1048576.0));
129  db.WriteBatch(batch);
130  batch.Clear();
131  if (crash_simulate) {
132  static FastRandomContext rng;
133  if (rng.randrange(crash_simulate) == 0) {
134  LogPrintf("Simulating a crash. Goodbye.\n");
135  _Exit(0);
136  }
137  }
138  }
139  }
140 
141  // In the last batch, mark the database as consistent with hashBlock again.
142  batch.Erase(DB_HEAD_BLOCKS);
143  batch.Write(DB_BEST_BLOCK, hashBlock);
144 
145  LogPrint(BCLog::COINDB, "Writing final batch of %.2f MiB\n",
146  batch.SizeEstimate() * (1.0 / 1048576.0));
147  bool ret = db.WriteBatch(batch);
149  "Committed %u changed transaction outputs (out of "
150  "%u) to coin database...\n",
151  (unsigned int)changed, (unsigned int)count);
152  return ret;
153 }
154 
156  return db.EstimateSize(DB_COIN, char(DB_COIN + 1));
157 }
158 
159 CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe)
160  : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory,
161  fWipe) {}
162 
164  return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
165 }
166 
167 bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
168  if (fReindexing) {
169  return Write(DB_REINDEX_FLAG, '1');
170  } else {
171  return Erase(DB_REINDEX_FLAG);
172  }
173 }
174 
176  return Exists(DB_REINDEX_FLAG);
177 }
178 
180  return Read(DB_LAST_BLOCK, nFile);
181 }
182 
185  const_cast<CDBWrapper &>(db).NewIterator(), GetBestBlock());
191  i->pcursor->Seek(DB_COIN);
192  // Cache key of first record
193  if (i->pcursor->Valid()) {
194  CoinEntry entry(&i->keyTmp.second);
195  i->pcursor->GetKey(entry);
196  i->keyTmp.first = entry.key;
197  } else {
198  // Make sure Valid() and GetKey() return false
199  i->keyTmp.first = 0;
200  }
201  return i;
202 }
203 
205  // Return cached key
206  if (keyTmp.first == DB_COIN) {
207  key = keyTmp.second;
208  return true;
209  }
210  return false;
211 }
212 
214  return pcursor->GetValue(coin);
215 }
216 
217 unsigned int CCoinsViewDBCursor::GetValueSize() const {
218  return pcursor->GetValueSize();
219 }
220 
222  return keyTmp.first == DB_COIN;
223 }
224 
226  pcursor->Next();
227  CoinEntry entry(&keyTmp.second);
228  if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
229  // Invalidate cached key after last record so that Valid() and GetKey()
230  // return false
231  keyTmp.first = 0;
232  } else {
233  keyTmp.first = entry.key;
234  }
235 }
236 
238  const std::vector<std::pair<int, const CBlockFileInfo *>> &fileInfo,
239  int nLastFile, const std::vector<const CBlockIndex *> &blockinfo) {
240  CDBBatch batch(*this);
241  for (std::vector<std::pair<int, const CBlockFileInfo *>>::const_iterator
242  it = fileInfo.begin();
243  it != fileInfo.end(); it++) {
244  batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
245  }
246  batch.Write(DB_LAST_BLOCK, nLastFile);
247  for (std::vector<const CBlockIndex *>::const_iterator it =
248  blockinfo.begin();
249  it != blockinfo.end(); it++) {
250  batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()),
251  CDiskBlockIndex(*it));
252  }
253  return WriteBatch(batch, true);
254 }
255 
256 bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
257  return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
258 }
259 
260 bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
261  char ch;
262  if (!Read(std::make_pair(DB_FLAG, name), ch)) {
263  return false;
264  }
265  fValue = ch == '1';
266  return true;
267 }
268 
270  const Consensus::Params &params,
271  std::function<CBlockIndex *(const BlockHash &)> insertBlockIndex) {
272  std::unique_ptr<CDBIterator> pcursor(NewIterator());
273 
274  uint64_t version = 0;
275  pcursor->Seek("version");
276  if (pcursor->Valid()) {
277  pcursor->GetValue(version);
278  }
279 
280  if (version != CLIENT_VERSION) {
281  return error("%s: Invalid block index database version: %s", __func__,
282  version);
283  }
284 
285  pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
286 
287  // Load m_block_index
288  while (pcursor->Valid()) {
289  boost::this_thread::interruption_point();
290  if (ShutdownRequested()) {
291  return false;
292  }
293  std::pair<char, uint256> key;
294  if (!pcursor->GetKey(key) || key.first != DB_BLOCK_INDEX) {
295  break;
296  }
297 
298  CDiskBlockIndex diskindex;
299  if (!pcursor->GetValue(diskindex)) {
300  return error("%s : failed to read value", __func__);
301  }
302 
303  // Construct block index object
304  CBlockIndex *pindexNew = insertBlockIndex(diskindex.GetBlockHash());
305  pindexNew->pprev = insertBlockIndex(diskindex.hashPrev);
306  pindexNew->nHeight = diskindex.nHeight;
307  pindexNew->nFile = diskindex.nFile;
308  pindexNew->nDataPos = diskindex.nDataPos;
309  pindexNew->nUndoPos = diskindex.nUndoPos;
310  pindexNew->nVersion = diskindex.nVersion;
311  pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
312  pindexNew->nTime = diskindex.nTime;
313  pindexNew->nBits = diskindex.nBits;
314  pindexNew->nNonce = diskindex.nNonce;
315  pindexNew->nStatus = diskindex.nStatus;
316  pindexNew->nTx = diskindex.nTx;
317 
318  if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits,
319  params)) {
320  return error("%s: CheckProofOfWork failed: %s", __func__,
321  pindexNew->ToString());
322  }
323 
324  pcursor->Next();
325  }
326 
327  return true;
328 }
329 
330 namespace {
332 class CCoins {
333 public:
335  bool fCoinBase;
336 
339  std::vector<CTxOut> vout;
340 
342  int nHeight;
343 
345  CCoins() : fCoinBase(false), vout(0), nHeight(0) {}
346 
347  template <typename Stream> void Unserialize(Stream &s) {
348  uint32_t nCode = 0;
349  // version
350  unsigned int nVersionDummy = 0;
351  ::Unserialize(s, VARINT(nVersionDummy));
352  // header code
353  ::Unserialize(s, VARINT(nCode));
354  fCoinBase = nCode & 1;
355  std::vector<bool> vAvail(2, false);
356  vAvail[0] = (nCode & 2) != 0;
357  vAvail[1] = (nCode & 4) != 0;
358  uint32_t nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
359  // spentness bitmask
360  while (nMaskCode > 0) {
361  uint8_t chAvail = 0;
362  ::Unserialize(s, chAvail);
363  for (unsigned int p = 0; p < 8; p++) {
364  bool f = (chAvail & (1 << p)) != 0;
365  vAvail.push_back(f);
366  }
367  if (chAvail != 0) {
368  nMaskCode--;
369  }
370  }
371  // txouts themself
372  vout.assign(vAvail.size(), CTxOut());
373  for (size_t i = 0; i < vAvail.size(); i++) {
374  if (vAvail[i]) {
375  ::Unserialize(s, Using<TxOutCompression>(vout[i]));
376  }
377  }
378  // coinbase height
380  }
381 };
382 } // namespace
383 
390  std::unique_ptr<CDBIterator> pcursor(db.NewIterator());
391  pcursor->Seek(std::make_pair(DB_COINS, uint256()));
392  if (!pcursor->Valid()) {
393  return true;
394  }
395 
396  int64_t count = 0;
397  LogPrintf("Upgrading utxo-set database...\n");
398  size_t batch_size = 1 << 24;
399  CDBBatch batch(db);
400  int reportDone = -1;
401  std::pair<uint8_t, uint256> key;
402  std::pair<uint8_t, uint256> prev_key = {DB_COINS, uint256()};
403  while (pcursor->Valid()) {
404  boost::this_thread::interruption_point();
405  if (ShutdownRequested()) {
406  break;
407  }
408 
409  if (!pcursor->GetKey(key) || key.first != DB_COINS) {
410  break;
411  }
412 
413  if (count++ % 256 == 0) {
414  uint32_t high =
415  0x100 * *key.second.begin() + *(key.second.begin() + 1);
416  int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
417  uiInterface.ShowProgress(_("Upgrading UTXO database").translated,
418  percentageDone, true);
419  if (reportDone < percentageDone / 10) {
420  // report max. every 10% step
421  LogPrintfToBeContinued("[%d%%]...", percentageDone);
422  reportDone = percentageDone / 10;
423  }
424  }
425 
426  CCoins old_coins;
427  if (!pcursor->GetValue(old_coins)) {
428  return error("%s: cannot parse CCoins record", __func__);
429  }
430 
431  const TxId id(key.second);
432  for (size_t i = 0; i < old_coins.vout.size(); ++i) {
433  if (!old_coins.vout[i].IsNull() &&
434  !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
435  Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight,
436  old_coins.fCoinBase);
437  COutPoint outpoint(id, i);
438  CoinEntry entry(&outpoint);
439  batch.Write(entry, newcoin);
440  }
441  }
442 
443  batch.Erase(key);
444  if (batch.SizeEstimate() > batch_size) {
445  db.WriteBatch(batch);
446  batch.Clear();
447  db.CompactRange(prev_key, key);
448  prev_key = key;
449  }
450 
451  pcursor->Next();
452  }
453 
454  db.WriteBatch(batch);
455  db.CompactRange({DB_COINS, uint256()}, key);
456  uiInterface.ShowProgress("", 100, false);
457  LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
458  return !ShutdownRequested();
459 }
460 
462  std::unique_ptr<CDBIterator> pcursor(NewIterator());
463 
464  uint64_t version = 0;
465  pcursor->Seek("version");
466  if (pcursor->Valid()) {
467  pcursor->GetValue(version);
468  }
469 
470  if (version >= CLIENT_VERSION) {
471  // The DB is already up to date.
472  return true;
473  }
474 
475  CDBBatch batch(*this);
476 
477  pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
478  if (!pcursor->Valid()) {
479  // The DB is empty, so just write the version number and consider the
480  // upgrade done.
481  batch.Write("version", uint64_t(CLIENT_VERSION));
482  WriteBatch(batch);
483  return true;
484  }
485 
486  int64_t count = 0;
487  LogPrintf("Upgrading block index database...\n");
488  int reportDone = -1;
489  std::pair<uint8_t, uint256> key = {DB_BLOCK_INDEX, uint256()};
490  while (pcursor->Valid()) {
491  boost::this_thread::interruption_point();
492  if (ShutdownRequested()) {
493  break;
494  }
495 
496  if (!pcursor->GetKey(key) || key.first != DB_BLOCK_INDEX) {
497  break;
498  }
499 
500  if (count++ % 256 == 0) {
501  uint32_t high =
502  0x100 * *key.second.begin() + *(key.second.begin() + 1);
503  int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
504  uiInterface.ShowProgress(
505  _("Upgrading block index database").translated, percentageDone,
506  true);
507  if (reportDone < percentageDone / 10) {
508  // report max. every 10% step
509  LogPrintfToBeContinued("[%d%%]...", percentageDone);
510  reportDone = percentageDone / 10;
511  }
512  }
513 
514  // Read the block index entry and update it.
515  CDiskBlockIndex diskindex;
516  if (!pcursor->GetValue(diskindex)) {
517  return error("%s: cannot parse CDiskBlockIndex record", __func__);
518  }
519 
520  // The block hash needs to be usable.
521  BlockHash blockhash = diskindex.GetBlockHash();
522  diskindex.phashBlock = &blockhash;
523 
524  bool mustUpdate = false;
525 
526  // We must update the block index to add the size.
529  diskindex.nTx > 0 && diskindex.nSize == 0) {
530  if (!diskindex.nStatus.hasData()) {
531  // The block was pruned, we need a full reindex.
532  LogPrintf("\nThe block %s is pruned. The block index cannot be "
533  "upgraded and reindexing is required.\n",
534  blockhash.GetHex());
535  return false;
536  }
537 
538  CBlock block;
539  if (!ReadBlockFromDisk(block, &diskindex, params)) {
540  // Failed to read the block from disk, even though it is marked
541  // that we have data for this block.
542  return false;
543  }
544 
545  mustUpdate = true;
546  diskindex.nSize = ::GetSerializeSize(block, PROTOCOL_VERSION);
547  }
548 
549  if (mustUpdate) {
550  batch.Write(std::make_pair(DB_BLOCK_INDEX, blockhash), diskindex);
551  }
552 
553  pcursor->Next();
554  }
555 
556  // Upgrade is done, now let's update the version number.
557  batch.Write("version", uint64_t(CLIENT_VERSION));
558 
559  WriteBatch(batch);
561  uiInterface.ShowProgress("", 100, false);
562  LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
563  return !ShutdownRequested();
564 }
uint32_t GetN() const
Definition: transaction.h:44
bool Exists(const K &key) const
Definition: dbwrapper.h:262
bool GetValue(Coin &coin) const override
Definition: txdb.cpp:213
static const char DB_LAST_BLOCK
Definition: txdb.cpp:32
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txdb.cpp:63
#define VARINT(obj)
Definition: serialize.h:608
BlockHash GetBlockHash() const
Definition: chain.h:129
std::string ToString() const
Definition: blockindex.h:187
void Clear()
Definition: dbwrapper.h:68
bool ShutdownRequested()
Definition: shutdown.cpp:18
bool ReadBlockFromDisk(CBlock &block, const FlatFilePos &pos, const Consensus::Params &params)
Functions for disk access for blocks.
Definition: blockdb.cpp:33
#define LogPrintfToBeContinued
These are aliases used to explicitly state that the message should not end with a newline character...
Definition: logging.h:201
bool Upgrade()
Attempt to update from an older database format.
Definition: txdb.cpp:389
#define LogPrint(category,...)
Definition: logging.h:189
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
Definition: txdb.h:75
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:30
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:48
const BlockHash * phashBlock
pointer to the hash of the block, if any.
Definition: blockindex.h:27
BlockHash hashPrev
Definition: chain.h:87
A UTXO entry.
Definition: coins.h:27
Definition: block.h:62
static const char DB_BEST_BLOCK
Definition: txdb.cpp:28
bool IsReindexing() const
Definition: txdb.cpp:175
bool ReadLastBlockFile(int &nFile)
Definition: txdb.cpp:179
CCoinsViewDB(fs::path ldb_path, size_t nCacheSize, bool fMemory, bool fWipe)
Definition: txdb.cpp:59
BlockStatus nStatus
Verification status of this block. See enum BlockStatus.
Definition: blockindex.h:76
std::vector< BlockHash > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: txdb.cpp:79
unsigned int nHeight
bool hasData() const
Definition: blockstatus.h:54
void Erase(const K &key)
Definition: dbwrapper.h:97
std::unique_ptr< CDBIterator > pcursor
Definition: txdb.h:89
static const char DB_COIN
Definition: txdb.cpp:23
static constexpr int TRACK_SIZE_VERSION
Definition: chain.h:85
static void LogPrintf(const char *fmt, const Args &... args)
Definition: logging.h:171
const TxId & GetTxId() const
Definition: transaction.h:43
bool Upgrade(const Consensus::Params &params)
Attempt to update from an older database format.
Definition: txdb.cpp:461
uint32_t nTime
Definition: blockindex.h:81
int nFile
Which # file this block is stored in (blk?????.dat)
Definition: blockindex.h:39
bool GetKey(COutPoint &key) const override
Definition: txdb.cpp:204
bool IsNull() const
Definition: uint256.h:26
bool WriteReindexing(bool fReindexing)
Definition: txdb.cpp:167
CDBIterator * NewIterator()
Definition: dbwrapper.h:297
size_t GetSerializeSize(const T &t, int nVersion=0)
Definition: serialize.h:1193
DIRTY means the CCoinsCacheEntry is potentially different from the version in the parent cache...
Definition: coins.h:133
void Serialize(Stream &s, char a)
Definition: serialize.h:261
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:21
BlockHash GetBlockHash() const
Definition: blockindex.h:133
static const char DB_BLOCK_FILES
Definition: txdb.cpp:25
#define VARINT_MODE(obj, mode)
Definition: serialize.h:607
bool LoadBlockIndexGuts(const Consensus::Params &params, std::function< CBlockIndex *(const BlockHash &)> insertBlockIndex)
Definition: txdb.cpp:269
BlockHash GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: txdb.cpp:71
static constexpr int64_t DEFAULT_DB_BATCH_SIZE
-dbbatchsize default (bytes)
Definition: txdb.h:35
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:278
uint32_t nNonce
Definition: blockindex.h:83
static const char DB_FLAG
Definition: txdb.cpp:30
unsigned int nDataPos
Byte offset within blk?????.dat where this block&#39;s data is stored.
Definition: blockindex.h:42
const char * name
Definition: rest.cpp:43
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:55
Fast randomness source.
Definition: random.h:111
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:760
CDBWrapper db
Definition: txdb.h:51
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher > CCoinsMap
Definition: coins.h:152
uint256 hashMerkleRoot
Definition: blockindex.h:80
void Write(const K &key, const V &value)
Definition: dbwrapper.h:73
size_t SizeEstimate() const
Definition: dbwrapper.h:112
An output of a transaction.
Definition: transaction.h:141
Used to marshal pointers into hashes for db storage.
Definition: chain.h:83
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: txdb.cpp:155
Parameters that influence chain consensus.
Definition: params.h:59
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:22
std::pair< char, COutPoint > keyTmp
Definition: txdb.h:90
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:230
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: txdb.cpp:67
unsigned int nSize
Size of this block.
Definition: blockindex.h:59
bool ReadFlag(const std::string &name, bool &fValue)
Definition: txdb.cpp:260
CBlockTreeDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:159
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
Definition: txdb.cpp:163
unsigned int nUndoPos
Byte offset within rev?????.dat where this block&#39;s undo data is stored.
Definition: blockindex.h:45
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
int32_t nVersion
block header
Definition: blockindex.h:79
256-bit opaque blob.
Definition: uint256.h:120
static const char DB_BLOCK_INDEX
Definition: txdb.cpp:26
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:256
void CompactRange(const K &key_begin, const K &key_end) const
Compact a certain range of keys in the database.
Definition: dbwrapper.h:326
static constexpr int CLIENT_VERSION
bitcoind-res.rc includes this file, but it cannot cope with real c++ code.
Definition: clientversion.h:44
A BlockHash is a unqiue identifier for a block.
Definition: blockhash.h:13
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: blockindex.h:23
bool BatchWrite(CCoinsMap &mapCoins, const BlockHash &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: txdb.cpp:87
A TxId is the identifier of a transaction.
Definition: txid.h:14
static const int PROTOCOL_VERSION
network protocol versioning
Definition: version.h:11
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:479
std::string GetHex() const
Definition: uint256.cpp:16
ArgsManager gArgs
Definition: system.cpp:76
static int count
Definition: tests.c:35
void Unserialize(Stream &s, char &a)
Definition: serialize.h:313
bool WriteFlag(const std::string &name, bool fValue)
Definition: txdb.cpp:256
void Next() override
Definition: txdb.cpp:225
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: txdb.cpp:183
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:186
bool Valid() const override
Definition: txdb.cpp:221
CClientUIInterface uiInterface
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:36
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo *>> &fileInfo, int nLastFile, const std::vector< const CBlockIndex *> &blockinfo)
Definition: txdb.cpp:237
static const char DB_REINDEX_FLAG
Definition: txdb.cpp:31
unsigned int GetValueSize() const override
Definition: txdb.cpp:217
static const char DB_COINS
Definition: txdb.cpp:24
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:307
static const char DB_HEAD_BLOCKS
Definition: txdb.cpp:29
bool error(const char *fmt, const Args &... args)
Definition: system.h:47
uint32_t nBits
Definition: blockindex.h:82
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:186
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:54
CAddrDb db
Definition: main.cpp:167
Cursor for iterating over CoinsView state.
Definition: coins.h:155