Dash Core Source Documentation (0.16.0.1)

Find detailed information regarding the Dash Core source code.

txdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2015 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 <chainparams.h>
9 #include <hash.h>
10 #include <random.h>
11 #include <pow.h>
12 #include <uint256.h>
13 #include <util.h>
14 #include <ui_interface.h>
15 #include <init.h>
16 
17 #include <stdint.h>
18 
19 #include <boost/thread.hpp>
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_TXINDEX = 't';
25 static const char DB_ADDRESSINDEX = 'a';
26 static const char DB_ADDRESSUNSPENTINDEX = 'u';
27 static const char DB_TIMESTAMPINDEX = 's';
28 static const char DB_SPENTINDEX = 'p';
29 static const char DB_BLOCK_INDEX = 'b';
30 
31 static const char DB_BEST_BLOCK = 'B';
32 static const char DB_HEAD_BLOCKS = 'H';
33 static const char DB_FLAG = 'F';
34 static const char DB_REINDEX_FLAG = 'R';
35 static const char DB_LAST_BLOCK = 'l';
36 
37 namespace {
38 
39 struct CoinEntry {
40  COutPoint* outpoint;
41  char key;
42  explicit CoinEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {}
43 
44  template<typename Stream>
45  void Serialize(Stream &s) const {
46  s << key;
47  s << outpoint->hash;
48  s << VARINT(outpoint->n);
49  }
50 
51  template<typename Stream>
52  void Unserialize(Stream& s) {
53  s >> key;
54  s >> outpoint->hash;
55  s >> VARINT(outpoint->n);
56  }
57 };
58 
59 }
60 
61 CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe, true)
62 {
63 }
64 
65 bool CCoinsViewDB::GetCoin(const COutPoint &outpoint, Coin &coin) const {
66  return db.Read(CoinEntry(&outpoint), coin);
67 }
68 
69 bool CCoinsViewDB::HaveCoin(const COutPoint &outpoint) const {
70  return db.Exists(CoinEntry(&outpoint));
71 }
72 
74  uint256 hashBestChain;
75  if (!db.Read(DB_BEST_BLOCK, hashBestChain))
76  return uint256();
77  return hashBestChain;
78 }
79 
80 std::vector<uint256> CCoinsViewDB::GetHeadBlocks() const {
81  std::vector<uint256> vhashHeadBlocks;
82  if (!db.Read(DB_HEAD_BLOCKS, vhashHeadBlocks)) {
83  return std::vector<uint256>();
84  }
85  return vhashHeadBlocks;
86 }
87 
88 bool CCoinsViewDB::BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) {
89  CDBBatch batch(db);
90  size_t count = 0;
91  size_t changed = 0;
92  size_t batch_size = (size_t)gArgs.GetArg("-dbbatchsize", nDefaultDbBatchSize);
93  int crash_simulate = gArgs.GetArg("-dbcrashratio", 0);
94  assert(!hashBlock.IsNull());
95 
96  uint256 old_tip = GetBestBlock();
97  if (old_tip.IsNull()) {
98  // We may be in the middle of replaying.
99  std::vector<uint256> 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, std::vector<uint256>{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  changed++;
121  }
122  count++;
123  CCoinsMap::iterator itOld = it++;
124  mapCoins.erase(itOld);
125  if (batch.SizeEstimate() > batch_size) {
126  LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
127  db.WriteBatch(batch);
128  batch.Clear();
129  if (crash_simulate) {
130  static FastRandomContext rng;
131  if (rng.randrange(crash_simulate) == 0) {
132  LogPrintf("Simulating a crash. Goodbye.\n");
133  _Exit(0);
134  }
135  }
136  }
137  }
138 
139  // In the last batch, mark the database as consistent with hashBlock again.
140  batch.Erase(DB_HEAD_BLOCKS);
141  batch.Write(DB_BEST_BLOCK, hashBlock);
142 
143  LogPrint(BCLog::COINDB, "Writing final batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
144  bool ret = db.WriteBatch(batch);
145  LogPrint(BCLog::COINDB, "Committed %u changed transaction outputs (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
146  return ret;
147 }
148 
150 {
151  return db.EstimateSize(DB_COIN, (char)(DB_COIN+1));
152 }
153 
154 CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe), mapHasTxIndexCache(10000, 20000) {
155 }
156 
158  return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
159 }
160 
161 bool CBlockTreeDB::WriteReindexing(bool fReindexing) {
162  if (fReindexing)
163  return Write(DB_REINDEX_FLAG, '1');
164  else
165  return Erase(DB_REINDEX_FLAG);
166 }
167 
168 bool CBlockTreeDB::ReadReindexing(bool &fReindexing) {
169  fReindexing = Exists(DB_REINDEX_FLAG);
170  return true;
171 }
172 
174  return Read(DB_LAST_BLOCK, nFile);
175 }
176 
178 {
179  CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast<CDBWrapper&>(db).NewIterator(), GetBestBlock());
180  /* It seems that there are no "const iterators" for LevelDB. Since we
181  only need read operations on it, use a const-cast to get around
182  that restriction. */
183  i->pcursor->Seek(DB_COIN);
184  // Cache key of first record
185  if (i->pcursor->Valid()) {
186  CoinEntry entry(&i->keyTmp.second);
187  i->pcursor->GetKey(entry);
188  i->keyTmp.first = entry.key;
189  } else {
190  i->keyTmp.first = 0; // Make sure Valid() and GetKey() return false
191  }
192  return i;
193 }
194 
196 {
197  // Return cached key
198  if (keyTmp.first == DB_COIN) {
199  key = keyTmp.second;
200  return true;
201  }
202  return false;
203 }
204 
206 {
207  return pcursor->GetValue(coin);
208 }
209 
211 {
212  return pcursor->GetValueSize();
213 }
214 
216 {
217  return keyTmp.first == DB_COIN;
218 }
219 
221 {
222  pcursor->Next();
223  CoinEntry entry(&keyTmp.second);
224  if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
225  keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false
226  } else {
227  keyTmp.first = entry.key;
228  }
229 }
230 
231 bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
232  CDBBatch batch(*this);
233  for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
234  batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
235  }
236  batch.Write(DB_LAST_BLOCK, nLastFile);
237  for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
238  batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
239  }
240  return WriteBatch(batch, true);
241 }
242 
244  {
245  LOCK(cs);
246  auto it = mapHasTxIndexCache.find(txid);
247  if (it != mapHasTxIndexCache.end()) {
248  return it->second;
249  }
250  }
251  bool r = Exists(std::make_pair(DB_TXINDEX, txid));
252  LOCK(cs);
253  mapHasTxIndexCache.insert(std::make_pair(txid, r));
254  return r;
255 }
256 
258  bool r = Read(std::make_pair(DB_TXINDEX, txid), pos);
259  LOCK(cs);
260  mapHasTxIndexCache.insert_or_update(std::make_pair(txid, r));
261  return r;
262 }
263 
264 bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >&vect) {
265  CDBBatch batch(*this);
266  for (std::vector<std::pair<uint256,CDiskTxPos> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
267  batch.Write(std::make_pair(DB_TXINDEX, it->first), it->second);
268  bool ret = WriteBatch(batch);
269  LOCK(cs);
270  for (auto& p : vect) {
271  mapHasTxIndexCache.insert_or_update(std::make_pair(p.first, true));
272  }
273  return ret;
274 }
275 
277  return Read(std::make_pair(DB_SPENTINDEX, key), value);
278 }
279 
280 bool CBlockTreeDB::UpdateSpentIndex(const std::vector<std::pair<CSpentIndexKey, CSpentIndexValue> >&vect) {
281  CDBBatch batch(*this);
282  for (std::vector<std::pair<CSpentIndexKey,CSpentIndexValue> >::const_iterator it=vect.begin(); it!=vect.end(); it++) {
283  if (it->second.IsNull()) {
284  batch.Erase(std::make_pair(DB_SPENTINDEX, it->first));
285  } else {
286  batch.Write(std::make_pair(DB_SPENTINDEX, it->first), it->second);
287  }
288  }
289  return WriteBatch(batch);
290 }
291 
292 bool CBlockTreeDB::UpdateAddressUnspentIndex(const std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue > >&vect) {
293  CDBBatch batch(*this);
294  for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=vect.begin(); it!=vect.end(); it++) {
295  if (it->second.IsNull()) {
296  batch.Erase(std::make_pair(DB_ADDRESSUNSPENTINDEX, it->first));
297  } else {
298  batch.Write(std::make_pair(DB_ADDRESSUNSPENTINDEX, it->first), it->second);
299  }
300  }
301  return WriteBatch(batch);
302 }
303 
305  std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > &unspentOutputs) {
306 
307  std::unique_ptr<CDBIterator> pcursor(NewIterator());
308 
309  pcursor->Seek(std::make_pair(DB_ADDRESSUNSPENTINDEX, CAddressIndexIteratorKey(type, addressHash)));
310 
311  while (pcursor->Valid()) {
312  boost::this_thread::interruption_point();
313  std::pair<char,CAddressUnspentKey> key;
314  if (pcursor->GetKey(key) && key.first == DB_ADDRESSUNSPENTINDEX && key.second.hashBytes == addressHash) {
315  CAddressUnspentValue nValue;
316  if (pcursor->GetValue(nValue)) {
317  unspentOutputs.push_back(std::make_pair(key.second, nValue));
318  pcursor->Next();
319  } else {
320  return error("failed to get address unspent value");
321  }
322  } else {
323  break;
324  }
325  }
326 
327  return true;
328 }
329 
330 bool CBlockTreeDB::WriteAddressIndex(const std::vector<std::pair<CAddressIndexKey, CAmount > >&vect) {
331  CDBBatch batch(*this);
332  for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
333  batch.Write(std::make_pair(DB_ADDRESSINDEX, it->first), it->second);
334  return WriteBatch(batch);
335 }
336 
337 bool CBlockTreeDB::EraseAddressIndex(const std::vector<std::pair<CAddressIndexKey, CAmount > >&vect) {
338  CDBBatch batch(*this);
339  for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=vect.begin(); it!=vect.end(); it++)
340  batch.Erase(std::make_pair(DB_ADDRESSINDEX, it->first));
341  return WriteBatch(batch);
342 }
343 
344 bool CBlockTreeDB::ReadAddressIndex(uint160 addressHash, int type,
345  std::vector<std::pair<CAddressIndexKey, CAmount> > &addressIndex,
346  int start, int end) {
347 
348  std::unique_ptr<CDBIterator> pcursor(NewIterator());
349 
350  if (start > 0 && end > 0) {
351  pcursor->Seek(std::make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorHeightKey(type, addressHash, start)));
352  } else {
353  pcursor->Seek(std::make_pair(DB_ADDRESSINDEX, CAddressIndexIteratorKey(type, addressHash)));
354  }
355 
356  while (pcursor->Valid()) {
357  boost::this_thread::interruption_point();
358  std::pair<char,CAddressIndexKey> key;
359  if (pcursor->GetKey(key) && key.first == DB_ADDRESSINDEX && key.second.hashBytes == addressHash) {
360  if (end > 0 && key.second.blockHeight > end) {
361  break;
362  }
363  CAmount nValue;
364  if (pcursor->GetValue(nValue)) {
365  addressIndex.push_back(std::make_pair(key.second, nValue));
366  pcursor->Next();
367  } else {
368  return error("failed to get address index value");
369  }
370  } else {
371  break;
372  }
373  }
374 
375  return true;
376 }
377 
379  CDBBatch batch(*this);
380  batch.Write(std::make_pair(DB_TIMESTAMPINDEX, timestampIndex), 0);
381  return WriteBatch(batch);
382 }
383 
384 bool CBlockTreeDB::ReadTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector<uint256> &hashes) {
385 
386  std::unique_ptr<CDBIterator> pcursor(NewIterator());
387 
388  pcursor->Seek(std::make_pair(DB_TIMESTAMPINDEX, CTimestampIndexIteratorKey(low)));
389 
390  while (pcursor->Valid()) {
391  boost::this_thread::interruption_point();
392  std::pair<char, CTimestampIndexKey> key;
393  if (pcursor->GetKey(key) && key.first == DB_TIMESTAMPINDEX && key.second.timestamp <= high) {
394  hashes.push_back(key.second.blockHash);
395  pcursor->Next();
396  } else {
397  break;
398  }
399  }
400 
401  return true;
402 }
403 
404 bool CBlockTreeDB::WriteFlag(const std::string &name, bool fValue) {
405  return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
406 }
407 
408 bool CBlockTreeDB::ReadFlag(const std::string &name, bool &fValue) {
409  char ch;
410  if (!Read(std::make_pair(DB_FLAG, name), ch))
411  return false;
412  fValue = ch == '1';
413  return true;
414 }
415 
416 bool CBlockTreeDB::LoadBlockIndexGuts(const Consensus::Params& consensusParams, std::function<CBlockIndex*(const uint256&)> insertBlockIndex)
417 {
418  std::unique_ptr<CDBIterator> pcursor(NewIterator());
419 
420  pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, uint256()));
421 
422  // Load mapBlockIndex
423  while (pcursor->Valid()) {
424  boost::this_thread::interruption_point();
425  std::pair<char, uint256> key;
426  if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) {
427  CDiskBlockIndex diskindex;
428  if (pcursor->GetValue(diskindex)) {
429  // Construct block index object
430  CBlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash());
431  pindexNew->pprev = insertBlockIndex(diskindex.hashPrev);
432  pindexNew->nHeight = diskindex.nHeight;
433  pindexNew->nFile = diskindex.nFile;
434  pindexNew->nDataPos = diskindex.nDataPos;
435  pindexNew->nUndoPos = diskindex.nUndoPos;
436  pindexNew->nVersion = diskindex.nVersion;
437  pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
438  pindexNew->nTime = diskindex.nTime;
439  pindexNew->nBits = diskindex.nBits;
440  pindexNew->nNonce = diskindex.nNonce;
441  pindexNew->nStatus = diskindex.nStatus;
442  pindexNew->nTx = diskindex.nTx;
443 
444  if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits, consensusParams))
445  return error("%s: CheckProofOfWork failed: %s", __func__, pindexNew->ToString());
446 
447  pcursor->Next();
448  } else {
449  return error("%s: failed to read value", __func__);
450  }
451  } else {
452  break;
453  }
454  }
455 
456  return true;
457 }
458 
459 namespace {
460 
462 class CCoins
463 {
464 public:
466  bool fCoinBase;
467 
469  std::vector<CTxOut> vout;
470 
472  int nHeight;
473 
475  CCoins() : fCoinBase(false), vout(0), nHeight(0) { }
476 
477  template<typename Stream>
478  void Unserialize(Stream &s) {
479  unsigned int nCode = 0;
480  // version
481  int nVersionDummy;
482  ::Unserialize(s, VARINT(nVersionDummy));
483  // header code
484  ::Unserialize(s, VARINT(nCode));
485  fCoinBase = nCode & 1;
486  std::vector<bool> vAvail(2, false);
487  vAvail[0] = (nCode & 2) != 0;
488  vAvail[1] = (nCode & 4) != 0;
489  unsigned int nMaskCode = (nCode / 8) + ((nCode & 6) != 0 ? 0 : 1);
490  // spentness bitmask
491  while (nMaskCode > 0) {
492  unsigned char chAvail = 0;
493  ::Unserialize(s, chAvail);
494  for (unsigned int p = 0; p < 8; p++) {
495  bool f = (chAvail & (1 << p)) != 0;
496  vAvail.push_back(f);
497  }
498  if (chAvail != 0)
499  nMaskCode--;
500  }
501  // txouts themself
502  vout.assign(vAvail.size(), CTxOut());
503  for (unsigned int i = 0; i < vAvail.size(); i++) {
504  if (vAvail[i])
505  ::Unserialize(s, REF(CTxOutCompressor(vout[i])));
506  }
507  // coinbase height
508  ::Unserialize(s, VARINT(nHeight));
509  }
510 };
511 
512 }
513 
519  std::unique_ptr<CDBIterator> pcursor(db.NewIterator());
520  pcursor->Seek(std::make_pair(DB_COINS, uint256()));
521  if (!pcursor->Valid()) {
522  return true;
523  }
524 
525  int64_t count = 0;
526  LogPrintf("Upgrading utxo-set database...\n");
527  LogPrintf("[0%%]...");
528  uiInterface.ShowProgress(_("Upgrading UTXO database"), 0, true);
529  size_t batch_size = 1 << 24;
530  CDBBatch batch(db);
531  int reportDone = 0;
532  std::pair<unsigned char, uint256> key;
533  std::pair<unsigned char, uint256> prev_key = {DB_COINS, uint256()};
534  while (pcursor->Valid()) {
535  boost::this_thread::interruption_point();
536  if (ShutdownRequested()) {
537  break;
538  }
539  if (pcursor->GetKey(key) && key.first == DB_COINS) {
540  if (count++ % 256 == 0) {
541  uint32_t high = 0x100 * *key.second.begin() + *(key.second.begin() + 1);
542  int percentageDone = (int)(high * 100.0 / 65536.0 + 0.5);
543  uiInterface.ShowProgress(_("Upgrading UTXO database"), percentageDone, true);
544  if (reportDone < percentageDone/10) {
545  // report max. every 10% step
546  LogPrintf("[%d%%]...", percentageDone);
547  reportDone = percentageDone/10;
548  }
549  }
550  CCoins old_coins;
551  if (!pcursor->GetValue(old_coins)) {
552  return error("%s: cannot parse CCoins record", __func__);
553  }
554  COutPoint outpoint(key.second, 0);
555  for (size_t i = 0; i < old_coins.vout.size(); ++i) {
556  if (!old_coins.vout[i].IsNull() && !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
557  Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight, old_coins.fCoinBase);
558  outpoint.n = i;
559  CoinEntry entry(&outpoint);
560  batch.Write(entry, newcoin);
561  }
562  }
563  batch.Erase(key);
564  if (batch.SizeEstimate() > batch_size) {
565  db.WriteBatch(batch);
566  batch.Clear();
567  db.CompactRange(prev_key, key);
568  prev_key = key;
569  }
570  pcursor->Next();
571  } else {
572  break;
573  }
574  }
575  db.WriteBatch(batch);
576  db.CompactRange({DB_COINS, uint256()}, key);
577  uiInterface.ShowProgress("", 100, false);
578  LogPrintf("[%s].\n", ShutdownRequested() ? "CANCELLED" : "DONE");
579  return !ShutdownRequested();
580 }
bool Exists(const K &key) const
Definition: dbwrapper.h:306
bool GetValue(Coin &coin) const override
Definition: txdb.cpp:205
static const char DB_LAST_BLOCK
Definition: txdb.cpp:35
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txdb.cpp:65
#define VARINT(obj)
Definition: serialize.h:375
std::string ToString() const
Definition: chain.h:323
void Clear()
Definition: dbwrapper.h:68
bool Upgrade()
Attempt to update from an older database format. Returns whether an error occurred.
Definition: txdb.cpp:518
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
Definition: txdb.h:92
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:177
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:49
static const char DB_TIMESTAMPINDEX
Definition: txdb.cpp:27
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
Definition: chain.h:207
A UTXO entry.
Definition: coins.h:29
static const char DB_BEST_BLOCK
Definition: txdb.cpp:31
bool ShutdownRequested()
Definition: init.cpp:179
bool ReadLastBlockFile(int &nFile)
Definition: txdb.cpp:173
wrapper for CTxOut that provides a more compact serialization
Definition: compressor.h:93
bool ReadTimestampIndex(const unsigned int &high, const unsigned int &low, std::vector< uint256 > &vect)
Definition: txdb.cpp:384
void Erase(const K &key)
Definition: dbwrapper.h:104
std::unique_ptr< CDBIterator > pcursor
Definition: txdb.h:107
uint64_t randrange(uint64_t range)
Generate a random integer in the range [0..range).
Definition: random.h:107
static const char DB_COIN
Definition: txdb.cpp:21
sph_u32 high
Definition: keccak.c:370
static const char DB_ADDRESSUNSPENTINDEX
Definition: txdb.cpp:26
false true true true
Definition: bls_dkg.cpp:176
uint32_t nTime
Definition: chain.h:212
int nFile
Which # file this block is stored in (blk?????.dat)
Definition: chain.h:186
bool ReadAddressIndex(uint160 addressHash, int type, std::vector< std::pair< CAddressIndexKey, CAmount > > &addressIndex, int start=0, int end=0)
Definition: txdb.cpp:344
void insert(const value_type &x)
Definition: limitedmap.h:51
bool GetKey(COutPoint &key) const override
Definition: txdb.cpp:195
bool ReadSpentIndex(CSpentIndexKey &key, CSpentIndexValue &value)
Definition: txdb.cpp:276
bool IsNull() const
Definition: uint256.h:33
bool WriteReindexing(bool fReindexing)
Definition: txdb.cpp:161
CDBIterator * NewIterator()
Definition: dbwrapper.h:351
static const char DB_ADDRESSINDEX
Definition: txdb.cpp:25
Definition: coins.h:109
void Serialize(Stream &s, char a)
Definition: serialize.h:184
bool ReadReindexing(bool &fReindexing)
Definition: txdb.cpp:168
int64_t CAmount
Amount in satoshis (Can be negative)
Definition: amount.h:12
uint256 GetBlockHash() const
Definition: chain.h:292
static const char DB_BLOCK_FILES
Definition: txdb.cpp:23
false
Definition: bls_dkg.cpp:168
bool EraseAddressIndex(const std::vector< std::pair< CAddressIndexKey, CAmount > > &vect)
Definition: txdb.cpp:337
std::size_t size_t
Definition: bits.hpp:21
bool UpdateAddressUnspentIndex(const std::vector< std::pair< CAddressUnspentKey, CAddressUnspentValue > > &vect)
Definition: txdb.cpp:292
#define LogPrintf(...)
Definition: util.h:203
bool ReadAddressUnspentIndex(uint160 addressHash, int type, std::vector< std::pair< CAddressUnspentKey, CAddressUnspentValue > > &vect)
Definition: txdb.cpp:304
const_iterator end() const
Definition: limitedmap.h:46
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:330
uint32_t nNonce
Definition: chain.h:214
static const char DB_FLAG
Definition: txdb.cpp:33
unsigned int nDataPos
Byte offset within blk?????.dat where this block&#39;s data is stored.
Definition: chain.h:189
#define LOCK(cs)
Definition: sync.h:178
const char * name
Definition: rest.cpp:36
Fast randomness source.
Definition: random.h:48
bool WriteTimestampIndex(const CTimestampIndexKey &timestampIndex)
Definition: txdb.cpp:378
uint32_t n
Definition: transaction.h:30
CDBWrapper db
Definition: txdb.h:74
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher > CCoinsMap
Definition: coins.h:122
uint256 hashMerkleRoot
Definition: chain.h:211
void Write(const K &key, const V &value)
Definition: dbwrapper.h:75
size_t SizeEstimate() const
Definition: dbwrapper.h:123
An output of a transaction.
Definition: transaction.h:144
Used to marshal pointers into hashes for db storage.
Definition: chain.h:370
static const int64_t nDefaultDbBatchSize
-dbbatchsize default (bytes)
Definition: txdb.h:31
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: txdb.cpp:149
Parameters that influence chain consensus.
Definition: params.h:130
bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params &params)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:233
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:26
std::pair< char, COutPoint > keyTmp
Definition: txdb.h:108
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:273
bool WriteAddressIndex(const std::vector< std::pair< CAddressIndexKey, CAmount > > &vect)
Definition: txdb.cpp:330
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether a given outpoint is unspent.
Definition: txdb.cpp:69
bool ReadFlag(const std::string &name, bool &fValue)
Definition: txdb.cpp:408
CBlockTreeDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:154
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo *> > &fileInfo, int nLastFile, const std::vector< const CBlockIndex *> &blockinfo)
Definition: txdb.cpp:231
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
Definition: txdb.cpp:157
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos)
Definition: txdb.cpp:257
CCriticalSection cs
Definition: txdb.h:117
CCoinsViewDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:61
unsigned int nUndoPos
Byte offset within rev?????.dat where this block&#39;s undo data is stored.
Definition: chain.h:192
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: txdb.cpp:73
#define LogPrint(category,...)
Definition: util.h:214
int32_t nVersion
block header
Definition: chain.h:210
256-bit opaque blob.
Definition: uint256.h:123
uint256 hashPrev
Definition: chain.h:374
static const char DB_BLOCK_INDEX
Definition: txdb.cpp:29
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:298
ArgsManager gArgs
Definition: util.cpp:108
void CompactRange(const K &key_begin, const K &key_end) const
Compact a certain range of keys in the database.
Definition: dbwrapper.h:381
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:170
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: util.cpp:808
sph_u32 low
Definition: keccak.c:370
160-bit opaque blob.
Definition: uint256.h:112
static int count
Definition: tests.c:45
void Unserialize(Stream &s, char &a)
Definition: serialize.h:196
bool error(const char *fmt, const Args &... args)
Definition: util.h:222
bool LoadBlockIndexGuts(const Consensus::Params &consensusParams, std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
Definition: txdb.cpp:416
bool WriteFlag(const std::string &name, bool fValue)
Definition: txdb.cpp:404
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: txdb.cpp:88
void Next() override
Definition: txdb.cpp:220
const fs::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:928
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: txdb.cpp:177
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:157
bool Valid() const override
Definition: txdb.cpp:215
CClientUIInterface uiInterface
Definition: ui_interface.cpp:8
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:183
void insert_or_update(const value_type &x)
Definition: limitedmap.h:57
uint256 GetBlockHash() const
Definition: chain.h:415
bool HasTxIndex(const uint256 &txid)
Definition: txdb.cpp:243
static const char DB_TXINDEX
Definition: txdb.cpp:24
static const char DB_REINDEX_FLAG
Definition: txdb.cpp:34
unsigned int GetValueSize() const override
Definition: txdb.cpp:210
static const char DB_COINS
Definition: txdb.cpp:22
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:362
unordered_limitedmap< uint256, bool > mapHasTxIndexCache
Definition: txdb.h:118
bool UpdateSpentIndex(const std::vector< std::pair< CSpentIndexKey, CSpentIndexValue > > &vect)
Definition: txdb.cpp:280
T & REF(const T &val)
Used to bypass the rule against non-const reference to temporary where it makes sense with wrappers s...
Definition: serialize.h:50
boost::signals2::signal< void(const std::string &title, int nProgress, bool resume_possible)> ShowProgress
Show progress e.g.
Definition: ui_interface.h:102
static const char DB_HEAD_BLOCKS
Definition: txdb.cpp:32
std::vector< uint256 > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: txdb.cpp:80
uint32_t nBits
Definition: chain.h:213
bool WriteTxIndex(const std::vector< std::pair< uint256, CDiskTxPos > > &vect)
Definition: txdb.cpp:264
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:199
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a boost::optional result...
Definition: util.h:92
const_iterator find(const key_type &k) const
Definition: limitedmap.h:49
static const char DB_SPENTINDEX
Definition: txdb.cpp:28
uint256 hash
Definition: transaction.h:29
Cursor for iterating over CoinsView state.
Definition: coins.h:125
Released under the MIT license