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