PIVX Core  5.6.99
P2P Digital Currency
txdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 The Bitcoin developers
3 // Copyright (c) 2016-2022 The PIVX Core developers
4 // Distributed under the MIT/X11 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 "clientversion.h"
10 #include "pow.h"
11 #include "random.h"
12 #include "uint256.h"
13 #include "util/system.h"
14 #include "util/vector.h"
15 
16 #include <stdint.h>
17 
18 #include <boost/thread.hpp>
19 
20 static const char DB_COIN = 'C';
21 static const char DB_COINS = 'c';
22 static const char DB_BLOCK_FILES = 'f';
23 static const char DB_TXINDEX = 't';
24 static const char DB_BLOCK_INDEX = 'b';
25 
26 static const char DB_BEST_BLOCK = 'B';
27 static const char DB_HEAD_BLOCKS = 'H';
28 static const char DB_FLAG = 'F';
29 static const char DB_REINDEX_FLAG = 'R';
30 static const char DB_LAST_BLOCK = 'l';
31 // static const char DB_MONEY_SUPPLY = 'M';
32 
33 namespace {
34 
35 struct CoinEntry
36 {
37  COutPoint* outpoint;
38  char key;
39  explicit CoinEntry(const COutPoint* ptr) : outpoint(const_cast<COutPoint*>(ptr)), key(DB_COIN) {}
40 
41  SERIALIZE_METHODS(CoinEntry, obj) { READWRITE(obj.key, obj.outpoint->hash, VARINT(obj.outpoint->n)); }
42 };
43 
44 }
45 
46 
47 CCoinsViewDB::CCoinsViewDB(size_t nCacheSize, bool fMemory, bool fWipe) : db(GetDataDir() / "chainstate", nCacheSize, fMemory, fWipe)
48 {
49 }
50 
51 bool CCoinsViewDB::GetCoin(const COutPoint& outpoint, Coin& coin) const
52 {
53  return db.Read(CoinEntry(&outpoint), coin);
54 }
55 
56 bool CCoinsViewDB::HaveCoin(const COutPoint& outpoint) const
57 {
58  return db.Exists(CoinEntry(&outpoint));
59 }
60 
62 {
63  uint256 hashBestChain;
64  if (!db.Read(DB_BEST_BLOCK, hashBestChain))
65  return UINT256_ZERO;
66  return hashBestChain;
67 }
68 
69 std::vector<uint256> CCoinsViewDB::GetHeadBlocks() const {
70  std::vector<uint256> vhashHeadBlocks;
71  if (!db.Read(DB_HEAD_BLOCKS, vhashHeadBlocks)) {
72  return std::vector<uint256>();
73  }
74  return vhashHeadBlocks;
75 }
76 
78  const uint256& hashBlock,
79  const uint256& hashSaplingAnchor,
80  CAnchorsSaplingMap& mapSaplingAnchors,
81  CNullifiersMap& mapSaplingNullifiers)
82 {
83  CDBBatch batch(CLIENT_VERSION);
84  size_t count = 0;
85  size_t changed = 0;
86  size_t batch_size = (size_t) gArgs.GetArg("-dbbatchsize", nDefaultDbBatchSize);
87  int crash_simulate = gArgs.GetArg("-dbcrashratio", 0);
88  assert(!hashBlock.IsNull());
89 
90  uint256 old_tip = GetBestBlock();
91  if (old_tip.IsNull()) {
92  // We may be in the middle of replaying.
93  std::vector<uint256> old_heads = GetHeadBlocks();
94  if (old_heads.size() == 2) {
95  assert(old_heads[0] == hashBlock);
96  old_tip = old_heads[1];
97  }
98  }
99 
100  // In the first batch, mark the database as being in the middle of a
101  // transition from old_tip to hashBlock.
102  // A vector is used for future extensibility, as we may want to support
103  // interrupting after partial writes from multiple independent reorgs.
104  batch.Erase(DB_BEST_BLOCK);
105  batch.Write(DB_HEAD_BLOCKS, Vector(hashBlock, old_tip));
106 
107  for (CCoinsMap::iterator it = mapCoins.begin(); it != mapCoins.end();) {
108  if (it->second.flags & CCoinsCacheEntry::DIRTY) {
109  CoinEntry entry(&it->first);
110  if (it->second.coin.IsSpent())
111  batch.Erase(entry);
112  else
113  batch.Write(entry, it->second.coin);
114  changed++;
115  }
116  count++;
117  CCoinsMap::iterator itOld = it++;
118  mapCoins.erase(itOld);
119  if (batch.SizeEstimate() > batch_size) {
120  LogPrint(BCLog::COINDB, "Writing partial batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
121  db.WriteBatch(batch);
122  batch.Clear();
123  if (crash_simulate) {
124  static FastRandomContext rng;
125  if (rng.randrange(crash_simulate) == 0) {
126  LogPrintf("Simulating a crash. Goodbye.\n");
127  _Exit(0);
128  }
129  }
130  }
131  }
132 
133  // Write Sapling
134  BatchWriteSapling(hashSaplingAnchor, mapSaplingAnchors, mapSaplingNullifiers, batch);
135 
136  // In the last batch, mark the database as consistent with hashBlock again.
137  batch.Erase(DB_HEAD_BLOCKS);
138  batch.Write(DB_BEST_BLOCK, hashBlock);
139 
140  LogPrint(BCLog::COINDB, "Writing final batch of %.2f MiB\n", batch.SizeEstimate() * (1.0 / 1048576.0));
141  bool ret = db.WriteBatch(batch);
142  LogPrint(BCLog::COINDB, "Committed %u changed transaction outputs (out of %u) to coin database...\n", (unsigned int)changed, (unsigned int)count);
143  return ret;
144 }
145 
147 {
148  return db.EstimateSize(DB_COIN, (char)(DB_COIN+1));
149 }
150 
151 CBlockTreeDB::CBlockTreeDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "blocks" / "index", nCacheSize, fMemory, fWipe)
152 {
153 }
154 
156 {
157  return Write(std::make_pair(DB_BLOCK_INDEX, blockindex.GetBlockHash()), blockindex);
158 }
159 
161 {
162  return Read(std::make_pair(DB_BLOCK_FILES, nFile), info);
163 }
164 
165 bool CBlockTreeDB::WriteReindexing(bool fReindexing)
166 {
167  if (fReindexing)
168  return Write(DB_REINDEX_FLAG, '1');
169  else
170  return Erase(DB_REINDEX_FLAG);
171 }
172 
173 bool CBlockTreeDB::ReadReindexing(bool& fReindexing)
174 {
175  fReindexing = Exists(DB_REINDEX_FLAG);
176  return true;
177 }
178 
180 {
181  return Read(DB_LAST_BLOCK, nFile);
182 }
183 
185 {
186  CCoinsViewDBCursor *i = new CCoinsViewDBCursor(const_cast<CDBWrapper&>(db).NewIterator(), GetBestBlock());
187  /* It seems that there are no "const iterators" for LevelDB. Since we
188  only need read operations on it, use a const-cast to get around
189  that restriction. */
190  i->pcursor->Seek(DB_COIN);
191  // Cache key of first record
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  i->keyTmp.first = 0; // Make sure Valid() and GetKey() return false
199  }
200  return i;
201 }
202 
204 {
205  // Return cached key
206  if (keyTmp.first == DB_COIN) {
207  key = keyTmp.second;
208  return true;
209  }
210  return false;
211 }
212 
214 {
215  return pcursor->GetValue(coin);
216 }
217 
219 {
220  return pcursor->GetValueSize();
221 }
222 
224 {
225  return keyTmp.first == DB_COIN;
226 }
227 
229 {
230  pcursor->Next();
231  CoinEntry entry(&keyTmp.second);
232  if (!pcursor->Valid() || !pcursor->GetKey(entry)) {
233  keyTmp.first = 0; // Invalidate cached key after last record so that Valid() and GetKey() return false
234  } else {
235  keyTmp.first = entry.key;
236  }
237 }
238 
239 bool CBlockTreeDB::WriteBatchSync(const std::vector<std::pair<int, const CBlockFileInfo*> >& fileInfo, int nLastFile, const std::vector<const CBlockIndex*>& blockinfo) {
240  CDBBatch batch(CLIENT_VERSION);
241  for (std::vector<std::pair<int, const CBlockFileInfo*> >::const_iterator it=fileInfo.begin(); it != fileInfo.end(); it++) {
242  batch.Write(std::make_pair(DB_BLOCK_FILES, it->first), *it->second);
243  }
244  batch.Write(DB_LAST_BLOCK, nLastFile);
245  for (std::vector<const CBlockIndex*>::const_iterator it=blockinfo.begin(); it != blockinfo.end(); it++) {
246  batch.Write(std::make_pair(DB_BLOCK_INDEX, (*it)->GetBlockHash()), CDiskBlockIndex(*it));
247  }
248  return WriteBatch(batch, true);
249 }
250 
252 {
253  return Read(std::make_pair(DB_TXINDEX, txid), pos);
254 }
255 
256 bool CBlockTreeDB::WriteTxIndex(const std::vector<std::pair<uint256, CDiskTxPos> >& vect)
257 {
258  CDBBatch batch(CLIENT_VERSION);
259  for (std::vector<std::pair<uint256, CDiskTxPos> >::const_iterator it = vect.begin(); it != vect.end(); it++)
260  batch.Write(std::make_pair(DB_TXINDEX, it->first), it->second);
261  return WriteBatch(batch);
262 }
263 
264 bool CBlockTreeDB::WriteFlag(const std::string& name, bool fValue)
265 {
266  return Write(std::make_pair(DB_FLAG, name), fValue ? '1' : '0');
267 }
268 
269 bool CBlockTreeDB::ReadFlag(const std::string& name, bool& fValue)
270 {
271  char ch;
272  if (!Read(std::make_pair(DB_FLAG, name), ch))
273  return false;
274  fValue = ch == '1';
275  return true;
276 }
277 
278 bool CBlockTreeDB::WriteInt(const std::string& name, int nValue)
279 {
280  return Write(std::make_pair('I', name), nValue);
281 }
282 
283 bool CBlockTreeDB::ReadInt(const std::string& name, int& nValue)
284 {
285  return Read(std::make_pair('I', name), nValue);
286 }
287 
288 bool CBlockTreeDB::LoadBlockIndexGuts(std::function<CBlockIndex*(const uint256&)> insertBlockIndex)
289 {
290  std::unique_ptr<CDBIterator> pcursor(NewIterator());
291 
292  pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, UINT256_ZERO));
293 
294  // Load mapBlockIndex
295  while (pcursor->Valid()) {
296  boost::this_thread::interruption_point();
297  std::pair<char, uint256> key;
298  if (pcursor->GetKey(key) && key.first == DB_BLOCK_INDEX) {
299  CDiskBlockIndex diskindex;
300  if (pcursor->GetValue(diskindex)) {
301  // Construct block index object
302  CBlockIndex* pindexNew = insertBlockIndex(diskindex.GetBlockHash());
303  pindexNew->pprev = insertBlockIndex(diskindex.hashPrev);
304  pindexNew->nHeight = diskindex.nHeight;
305  pindexNew->nFile = diskindex.nFile;
306  pindexNew->nDataPos = diskindex.nDataPos;
307  pindexNew->nUndoPos = diskindex.nUndoPos;
308  pindexNew->nVersion = diskindex.nVersion;
309  pindexNew->hashMerkleRoot = diskindex.hashMerkleRoot;
310  pindexNew->nTime = diskindex.nTime;
311  pindexNew->nBits = diskindex.nBits;
312  pindexNew->nNonce = diskindex.nNonce;
313  pindexNew->nStatus = diskindex.nStatus;
314  pindexNew->nTx = diskindex.nTx;
315 
316  // sapling
317  pindexNew->nSaplingValue = diskindex.nSaplingValue;
318  pindexNew->hashFinalSaplingRoot = diskindex.hashFinalSaplingRoot;
319 
320  //zerocoin
321  pindexNew->nAccumulatorCheckpoint = diskindex.nAccumulatorCheckpoint;
322 
323  //Proof Of Stake
324  pindexNew->nFlags = diskindex.nFlags;
325  pindexNew->vStakeModifier = diskindex.vStakeModifier;
326 
327  if (!Params().GetConsensus().NetworkUpgradeActive(pindexNew->nHeight, Consensus::UPGRADE_POS)) {
328  if (!CheckProofOfWork(pindexNew->GetBlockHash(), pindexNew->nBits))
329  return error("%s : CheckProofOfWork failed: %s", __func__, pindexNew->ToString());
330  }
331 
332  pcursor->Next();
333  } else {
334  return error("%s : failed to read value", __func__);
335  }
336  } else {
337  break;
338  }
339  }
340 
341  return true;
342 }
343 
344 CZerocoinDB::CZerocoinDB(size_t nCacheSize, bool fMemory, bool fWipe) : CDBWrapper(GetDataDir() / "zerocoin", nCacheSize, fMemory, fWipe)
345 {
346 }
347 
348 bool CZerocoinDB::WriteCoinSpendBatch(const std::vector<std::pair<CBigNum, uint256> >& spendInfo)
349 {
350  CDBBatch batch(CLIENT_VERSION);
351  size_t count = 0;
352  for (std::vector<std::pair<CBigNum, uint256> >::const_iterator it=spendInfo.begin(); it != spendInfo.end(); it++) {
353  CBigNum bnSerial = it->first;
354  CDataStream ss(SER_GETHASH, 0);
355  ss << bnSerial;
356  uint256 hash = Hash(ss.begin(), ss.end());
357  batch.Write(std::make_pair('s', hash), it->second);
358  ++count;
359  }
360 
361  LogPrint(BCLog::COINDB, "Writing %u coin spends to db.\n", (unsigned int)count);
362  return WriteBatch(batch, true);
363 }
364 
365 bool CZerocoinDB::ReadCoinSpend(const CBigNum& bnSerial, uint256& txHash)
366 {
367  CDataStream ss(SER_GETHASH, 0);
368  ss << bnSerial;
369  uint256 hash = Hash(ss.begin(), ss.end());
370 
371  return Read(std::make_pair('s', hash), txHash);
372 }
373 
375 {
376  CDataStream ss(SER_GETHASH, 0);
377  ss << bnSerial;
378  uint256 hash = Hash(ss.begin(), ss.end());
379 
380  return Erase(std::make_pair('s', hash));
381 }
382 
383 // Legacy Zerocoin Database
384 static const char LZC_ACCUMCS = 'A';
385 //static const char LZC_MAPSUPPLY = 'M'; // TODO: add removal for LZC_MAPSUPPLY key-value if is found in db
386 
387 bool CZerocoinDB::WriteAccChecksum(const uint32_t nChecksum, const libzerocoin::CoinDenomination denom, const int nHeight)
388 {
389  return Write(std::make_pair(LZC_ACCUMCS, std::make_pair(nChecksum, denom)), nHeight);
390 }
391 
392 bool CZerocoinDB::ReadAccChecksum(const uint32_t nChecksum, const libzerocoin::CoinDenomination denom, int& nHeightRet)
393 {
394  return Read(std::make_pair(LZC_ACCUMCS, std::make_pair(nChecksum, denom)), nHeightRet);
395 }
396 
397 bool CZerocoinDB::EraseAccChecksum(const uint32_t nChecksum, const libzerocoin::CoinDenomination denom)
398 {
399  return Erase(std::make_pair(LZC_ACCUMCS, std::make_pair(nChecksum, denom)));
400 }
401 
402 bool CZerocoinDB::ReadAll(std::map<std::pair<uint32_t, libzerocoin::CoinDenomination>, int>& mapCheckpoints)
403 {
404  std::unique_ptr<CDBIterator> pcursor(NewIterator());
405  pcursor->Seek(std::make_pair(LZC_ACCUMCS, std::make_pair((uint32_t) 0, libzerocoin::CoinDenomination::ZQ_ERROR)));
406  while (pcursor->Valid()) {
407  boost::this_thread::interruption_point();
408  std::pair<char, std::pair<uint32_t, libzerocoin::CoinDenomination>> key;
409  if (pcursor->GetKey(key) && key.first == LZC_ACCUMCS) {
410  int height;
411  if (pcursor->GetValue(height)) {
412  mapCheckpoints[key.second] = height;
413  pcursor->Next();
414  } else {
415  return error("%s : failed to read value", __func__);
416  }
417  } else {
418  break;
419  }
420  }
421 
422  LogPrintf("%s: Total acc checksum records: %d\n", __func__, mapCheckpoints.size());
423  return true;
424 }
425 
427 {
428  std::unique_ptr<CDBIterator> pcursor(NewIterator());
429  pcursor->Seek(std::make_pair(LZC_ACCUMCS, std::make_pair((uint32_t) 0, libzerocoin::CoinDenomination::ZQ_ERROR)));
430  std::set<std::pair<char, std::pair<uint32_t, libzerocoin::CoinDenomination>>> setDelete;
431  while (pcursor->Valid()) {
432  boost::this_thread::interruption_point();
433  std::pair<char, std::pair<uint32_t, libzerocoin::CoinDenomination>> key;
434  if (pcursor->GetKey(key) && key.first == LZC_ACCUMCS) {
435  setDelete.insert(key);
436  } else {
437  break;
438  }
439  pcursor->Next();
440  }
441 
442  int deleted = 0;
443  for (const auto& k : setDelete) {
444  if (!Erase(k)) {
445  LogPrintf("%s: failed to delete acc checksum %d-%d\n", __func__, k.second.first, k.second.second);
446  } else {
447  deleted++;
448  }
449  }
450 
451  LogPrintf("%s: %d entries to delete. %d entries deleted\n", __func__, setDelete.size(), deleted);
452 }
453 
454 namespace {
455 
457 class CCoins
458 {
459 public:
461  bool fCoinBase;
462  bool fCoinStake;
463 
465  std::vector<CTxOut> vout;
466 
468  int nHeight;
469 
470  template <typename Stream>
471  void Unserialize(Stream& s)
472  {
473  unsigned int nCode = 0;
474  // version
475  unsigned int nVersionDummy;
476  ::Unserialize(s, VARINT(nVersionDummy));
477  // header code
478  ::Unserialize(s, VARINT(nCode));
479  fCoinBase = nCode & 1; //0001 - means coinbase
480  fCoinStake = (nCode & 2) != 0; //0010 coinstake
481  std::vector<bool> vAvail(2, false);
482  vAvail[0] = (nCode & 4) != 0; // 0100
483  vAvail[1] = (nCode & 8) != 0; // 1000
484  unsigned int nMaskCode = (nCode / 16) + ((nCode & 12) != 0 ? 0 : 1);
485  // spentness bitmask
486  while (nMaskCode > 0) {
487  unsigned char chAvail = 0;
488  ::Unserialize(s, chAvail);
489  for (unsigned int p = 0; p < 8; p++) {
490  bool f = (chAvail & (1 << p)) != 0;
491  vAvail.push_back(f);
492  }
493  if (chAvail != 0)
494  nMaskCode--;
495  }
496  // txouts themself
497  vout.assign(vAvail.size(), CTxOut());
498  for (unsigned int i = 0; i < vAvail.size(); i++) {
499  if (vAvail[i])
500  ::Unserialize(s, Using<TxOutCompression>(vout[i]));
501  }
502  // coinbase height
504  }
505 };
506 
507 }
508 
515  std::unique_ptr<CDBIterator> pcursor(db.NewIterator());
516  pcursor->Seek(std::make_pair(DB_COINS, uint256()));
517  if (!pcursor->Valid()) {
518  return true;
519  }
520 
521  LogPrintf("Upgrading database...\n");
522  size_t batch_size = 1 << 24;
523  CDBBatch batch(CLIENT_VERSION);
524  while (pcursor->Valid()) {
525  boost::this_thread::interruption_point();
526  std::pair<unsigned char, uint256> key;
527  if (pcursor->GetKey(key) && key.first == DB_COINS) {
528  CCoins old_coins;
529  if (!pcursor->GetValue(old_coins)) {
530  return error("%s: cannot parse CCoins record", __func__);
531  }
532  COutPoint outpoint(key.second, 0);
533  for (size_t i = 0; i < old_coins.vout.size(); ++i) {
534  if (!old_coins.vout[i].IsNull() && !old_coins.vout[i].scriptPubKey.IsUnspendable()) {
535  Coin newcoin(std::move(old_coins.vout[i]), old_coins.nHeight, old_coins.fCoinBase, old_coins.fCoinStake);
536  outpoint.n = i;
537  CoinEntry entry(&outpoint);
538  batch.Write(entry, newcoin);
539  }
540  }
541  batch.Erase(key);
542  if (batch.SizeEstimate() > batch_size) {
543  db.WriteBatch(batch);
544  batch.Clear();
545  }
546  pcursor->Next();
547  } else {
548  break;
549  }
550  }
551  db.WriteBatch(batch);
552  return true;
553 }
554 
556 {
557  const auto& p = std::make_pair(checksum, denom);
558 
559  // First check the map in-memory.
560  const auto it = mapCheckpoints.find(p);
561  if (it != mapCheckpoints.end()) {
562  return Optional<int>(it->second);
563  }
564 
565  // Not found. Check disk.
566  int checksum_height = 0;
567  if (db->ReadAccChecksum(checksum, denom, checksum_height)) {
568  // save in memory and return
569  mapCheckpoints[p] = checksum_height;
570  return Optional<int>(checksum_height);
571  }
572 
573  // Not found. Scan the chain.
574  return nullopt;
575 }
576 
577 void AccumulatorCache::Set(uint32_t checksum, libzerocoin::CoinDenomination denom, int height)
578 {
579  // Update memory cache
580  mapCheckpoints[std::make_pair(checksum, denom)] = height;
581 }
582 
584 {
585  // Update memory cache and database
586  mapCheckpoints.erase(std::make_pair(checksum, denom));
587  db->EraseAccChecksum(checksum, denom);
588 }
589 
591 {
592  for (const auto& it : mapCheckpoints) {
593  // Write to disk
594  db->WriteAccChecksum(it.first.first, it.first.second, it.second);
595  }
596 }
597 
599 {
600  mapCheckpoints.clear();
601  db->WipeAccChecksums();
602 }
const CChainParams & Params()
Return the currently selected parameters.
void Erase(uint32_t checksum, libzerocoin::CoinDenomination denom)
Definition: txdb.cpp:583
CZerocoinDB * db
Definition: txdb.h:180
void Wipe()
Definition: txdb.cpp:598
Optional< int > Get(uint32_t checksum, libzerocoin::CoinDenomination denom)
Definition: txdb.cpp:555
std::map< std::pair< uint32_t, libzerocoin::CoinDenomination >, int > mapCheckpoints
Definition: txdb.h:182
void Set(uint32_t checksum, libzerocoin::CoinDenomination denom, int height)
Definition: txdb.cpp:577
void Flush()
Definition: txdb.cpp:590
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:449
uint32_t n
Definition: transaction.h:36
const_iterator end() const
Definition: streams.h:163
const_iterator begin() const
Definition: streams.h:161
C++ wrapper for BIGNUM.
Definition: bignum.h:35
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:139
unsigned int nFlags
Definition: chain.h:181
uint256 hashMerkleRoot
Definition: chain.h:194
std::string ToString() const
Definition: chain.cpp:138
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:145
std::vector< unsigned char > vStakeModifier
Definition: chain.h:180
int nFile
Which # file this block is stored in (blk?????.dat)
Definition: chain.h:154
uint32_t nTime
Definition: chain.h:196
uint32_t nNonce
Definition: chain.h:198
unsigned int nUndoPos
Byte offset within rev?????.dat where this block's undo data is stored.
Definition: chain.h:160
uint256 nAccumulatorCheckpoint
Definition: chain.h:199
uint256 GetBlockHash() const
Definition: chain.h:215
CAmount nSaplingValue
Change in value held by the Sapling circuit over this block.
Definition: chain.h:186
uint32_t nBits
Definition: chain.h:197
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:167
uint256 hashFinalSaplingRoot
Definition: chain.h:195
int32_t nVersion
block header
Definition: chain.h:193
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:151
uint32_t nStatus
Verification status of this block. See enum BlockStatus.
Definition: chain.h:175
unsigned int nDataPos
Byte offset within blk?????.dat where this block's data is stored.
Definition: chain.h:157
bool WriteTxIndex(const std::vector< std::pair< uint256, CDiskTxPos > > &vect)
Definition: txdb.cpp:256
bool ReadInt(const std::string &name, int &nValue)
Definition: txdb.cpp:283
bool LoadBlockIndexGuts(std::function< CBlockIndex *(const uint256 &)> insertBlockIndex)
Definition: txdb.cpp:288
bool ReadBlockFileInfo(int nFile, CBlockFileInfo &info)
Definition: txdb.cpp:160
CBlockTreeDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:151
bool WriteReindexing(bool fReindexing)
Definition: txdb.cpp:165
bool WriteBlockIndex(const CDiskBlockIndex &blockindex)
Definition: txdb.cpp:155
bool ReadTxIndex(const uint256 &txid, CDiskTxPos &pos)
Definition: txdb.cpp:251
bool WriteInt(const std::string &name, int nValue)
Definition: txdb.cpp:278
bool WriteBatchSync(const std::vector< std::pair< int, const CBlockFileInfo * > > &fileInfo, int nLastFile, const std::vector< const CBlockIndex * > &blockinfo)
Definition: txdb.cpp:239
bool ReadFlag(const std::string &name, bool &fValue)
Definition: txdb.cpp:269
bool ReadReindexing(bool &fReindexing)
Definition: txdb.cpp:173
bool ReadLastBlockFile(int &nFile)
Definition: txdb.cpp:179
bool WriteFlag(const std::string &name, bool fValue)
Definition: txdb.cpp:264
Cursor for iterating over CoinsView state.
Definition: coins.h:181
Specialization of CCoinsViewCursor to iterate over a CCoinsViewDB.
Definition: txdb.h:106
std::unique_ptr< CDBIterator > pcursor
Definition: txdb.h:120
bool Valid() const
Definition: txdb.cpp:223
bool GetKey(COutPoint &key) const
Definition: txdb.cpp:203
unsigned int GetValueSize() const
Definition: txdb.cpp:218
std::pair< char, COutPoint > keyTmp
Definition: txdb.h:121
bool GetValue(Coin &coin) const
Definition: txdb.cpp:213
CCoinsViewDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:47
bool GetCoin(const COutPoint &outpoint, Coin &coin) const override
Retrieve the Coin (unspent transaction output) for a given outpoint.
Definition: txdb.cpp:51
CDBWrapper db
Definition: txdb.h:73
bool HaveCoin(const COutPoint &outpoint) const override
Just check whether we have data for a given outpoint.
Definition: txdb.cpp:56
bool Upgrade()
Attempt to update from an older database format. Returns whether an error occurred.
Definition: txdb.cpp:514
CCoinsViewCursor * Cursor() const override
Get a cursor to iterate over the whole state.
Definition: txdb.cpp:184
uint256 GetBestBlock() const override
Retrieve the block hash whose state this CCoinsView currently represents.
Definition: txdb.cpp:61
bool BatchWriteSapling(const uint256 &hashSaplingAnchor, CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSaplingNullifiers, CDBBatch &batch)
bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock, const uint256 &hashSaplingAnchor, CAnchorsSaplingMap &mapSaplingAnchors, CNullifiersMap &mapSaplingNullifiers) override
Do a bulk modification (multiple Coin changes + BestBlock change).
Definition: txdb.cpp:77
std::vector< uint256 > GetHeadBlocks() const override
Retrieve the range of blocks that may have been only partially written.
Definition: txdb.cpp:69
size_t EstimateSize() const override
Estimate database size (0 if not implemented)
Definition: txdb.cpp:146
Batch of changes queued to be written to a CDBWrapper.
Definition: dbwrapper.h:46
void Erase(const K &key)
Definition: dbwrapper.h:100
size_t SizeEstimate() const
Definition: dbwrapper.h:122
void Write(const K &key, const V &value)
Definition: dbwrapper.h:69
void Clear()
Definition: dbwrapper.h:62
CDBIterator * NewIterator()
Definition: dbwrapper.h:338
bool WriteBatch(CDBBatch &batch, bool fSync=false)
Definition: dbwrapper.cpp:94
bool Read(const K &key, V &value) const
Definition: dbwrapper.h:260
bool Erase(const K &key, bool fSync=false)
Definition: dbwrapper.h:316
bool Write(const K &key, const V &value, bool fSync=false)
Definition: dbwrapper.h:284
bool Exists(const K &key) const
Definition: dbwrapper.h:292
size_t EstimateSize(const K &key_begin, const K &key_end) const
Definition: dbwrapper.h:349
uint256 hashPrev
Definition: chain.h:266
uint256 GetBlockHash() const
Definition: chain.h:365
An outpoint - a combination of a transaction hash and an index n into its vout.
Definition: transaction.h:72
An output of a transaction.
Definition: transaction.h:137
bool WriteAccChecksum(const uint32_t nChecksum, const libzerocoin::CoinDenomination denom, const int nHeight)
Accumulators (only for zPoS IBD): [checksum, denom] --> block height.
Definition: txdb.cpp:387
bool ReadCoinSpend(const CBigNum &bnSerial, uint256 &txHash)
Definition: txdb.cpp:365
bool ReadAccChecksum(const uint32_t nChecksum, const libzerocoin::CoinDenomination denom, int &nHeightRet)
Definition: txdb.cpp:392
bool EraseAccChecksum(const uint32_t nChecksum, const libzerocoin::CoinDenomination denom)
Definition: txdb.cpp:397
CZerocoinDB(size_t nCacheSize, bool fMemory=false, bool fWipe=false)
Definition: txdb.cpp:344
void WipeAccChecksums()
Definition: txdb.cpp:426
bool EraseCoinSpend(const CBigNum &bnSerial)
Definition: txdb.cpp:374
bool WriteCoinSpendBatch(const std::vector< std::pair< CBigNum, uint256 > > &spendInfo)
Write zPIV spends to the zerocoinDB in a batch Pair of: CBigNum -> coinSerialNumber and uint256 -> tx...
Definition: txdb.cpp:348
bool ReadAll(std::map< std::pair< uint32_t, libzerocoin::CoinDenomination >, int > &mapCheckpoints)
Definition: txdb.cpp:402
A UTXO entry.
Definition: coins.h:32
Fast randomness source.
Definition: random.h:107
uint64_t randrange(uint64_t range) noexcept
Generate a random integer in the range [0..range).
Definition: random.h:174
bool IsNull() const
Definition: uint256.h:36
256-bit opaque blob.
Definition: uint256.h:138
std::unordered_map< uint256, CAnchorsSaplingCacheEntry, SaltedIdHasher > CAnchorsSaplingMap
Definition: coins.h:174
std::unordered_map< COutPoint, CCoinsCacheEntry, SaltedOutpointHasher > CCoinsMap
Definition: coins.h:177
std::unordered_map< uint256, CNullifiersCacheEntry, SaltedIdHasher > CNullifiersMap
Definition: coins.h:175
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
Definition: hash.h:173
#define LogPrint(category,...)
Definition: logging.h:163
@ COINDB
Definition: logging.h:55
@ UPGRADE_POS
Definition: params.h:28
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
bool CheckProofOfWork(uint256 hash, unsigned int nBits)
Check whether a block hash satisfies the proof-of-work requirement specified by nBits.
Definition: pow.cpp:122
const char * name
Definition: rest.cpp:37
@ SER_GETHASH
Definition: serialize.h:176
#define VARINT(obj)
Definition: serialize.h:513
#define VARINT_MODE(obj, mode)
Definition: serialize.h:512
@ 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:219
void Unserialize(Stream &s, char &a)
Definition: serialize.h:253
#define READWRITE(...)
Definition: serialize.h:183
@ DIRTY
Definition: coins.h:139
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:724
ArgsManager gArgs
Definition: system.cpp:89
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
const uint256 UINT256_ZERO
constant uint256 instances
Definition: uint256.h:175
bool NetworkUpgradeActive(int nHeight, const Consensus::Params &params, Consensus::UpgradeIndex idx)
Returns true if the given network upgrade is active as of the given block height.
Definition: upgrades.cpp:107
std::vector< typename std::common_type< Args... >::type > Vector(Args &&... args)
Construct a vector with the specified elements.
Definition: vector.h:20