PIVX Core  5.6.99
P2P Digital Currency
chain.h
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) 2011-2013 The PPCoin developers
4 // Copyright (c) 2013-2014 The NovaCoin Developers
5 // Copyright (c) 2014-2018 The BlackCoin Developers
6 // Copyright (c) 2015-2021 The PIVX Core developers
7 // Distributed under the MIT software license, see the accompanying
8 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
9 
10 #ifndef PIVX_CHAIN_H
11 #define PIVX_CHAIN_H
12 
13 #include "chainparams.h"
14 #include "flatfile.h"
15 #include "optional.h"
16 #include "primitives/block.h"
17 #include "timedata.h"
18 #include "tinyformat.h"
19 #include "uint256.h"
20 #include "util/system.h"
22 
23 #include <vector>
24 
30 static constexpr int64_t TIMESTAMP_WINDOW = 2 * 60 * 60;
31 
33 {
34 public:
35  unsigned int nBlocks;
36  unsigned int nSize;
37  unsigned int nUndoSize;
38  unsigned int nHeightFirst;
39  unsigned int nHeightLast;
40  uint64_t nTimeFirst;
41  uint64_t nTimeLast;
42 
44  {
45  READWRITE(VARINT(obj.nBlocks));
46  READWRITE(VARINT(obj.nSize));
47  READWRITE(VARINT(obj.nUndoSize));
48  READWRITE(VARINT(obj.nHeightFirst));
49  READWRITE(VARINT(obj.nHeightLast));
50  READWRITE(VARINT(obj.nTimeFirst));
51  READWRITE(VARINT(obj.nTimeLast));
52  }
53 
54  void SetNull()
55  {
56  nBlocks = 0;
57  nSize = 0;
58  nUndoSize = 0;
59  nHeightFirst = 0;
60  nHeightLast = 0;
61  nTimeFirst = 0;
62  nTimeLast = 0;
63  }
64 
66  {
67  SetNull();
68  }
69 
70  std::string ToString() const;
71 
73  void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
74  {
75  if (nBlocks == 0 || nHeightFirst > nHeightIn)
76  nHeightFirst = nHeightIn;
77  if (nBlocks == 0 || nTimeFirst > nTimeIn)
78  nTimeFirst = nTimeIn;
79  nBlocks++;
80  if (nHeightIn > nHeightLast)
81  nHeightLast = nHeightIn;
82  if (nTimeIn > nTimeLast)
83  nTimeLast = nTimeIn;
84  }
85 };
86 
90 
93 
97 
104 
108 
111 
116 
120 
124 };
125 
126 // BlockIndex flags
127 enum {
128  BLOCK_PROOF_OF_STAKE = (1 << 0), // is proof-of-stake block
129  BLOCK_STAKE_ENTROPY = (1 << 1), // entropy bit for stake modifier
130  BLOCK_STAKE_MODIFIER = (1 << 2), // regenerated stake modifier
131 };
132 
139 {
140 public:
142  const uint256* phashBlock{nullptr};
143 
145  CBlockIndex* pprev{nullptr};
146 
148  CBlockIndex* pskip{nullptr};
149 
151  int nHeight{0};
152 
154  int nFile{0};
155 
157  unsigned int nDataPos{0};
158 
160  unsigned int nUndoPos{0};
161 
164 
167  unsigned int nTx{0};
168 
172  unsigned int nChainTx{0};
173 
175  uint32_t nStatus{0};
176 
177  // proof-of-stake specific fields
178  // char vector holding the stake modifier bytes. It is empty for PoW blocks.
179  // Modifier V1 is 64 bit while modifier V2 is 256 bit.
180  std::vector<unsigned char> vStakeModifier{};
181  unsigned int nFlags{0};
182 
187 
191 
193  int32_t nVersion{0};
196  uint32_t nTime{0};
197  uint32_t nBits{0};
198  uint32_t nNonce{0};
200 
202  uint32_t nSequenceId{0};
203 
205  unsigned int nTimeMax{0};
206 
208  explicit CBlockIndex(const CBlock& block);
209 
210  std::string ToString() const;
211 
212  FlatFilePos GetBlockPos() const;
213  FlatFilePos GetUndoPos() const;
215  uint256 GetBlockHash() const { return *phashBlock; }
216  int64_t GetBlockTime() const { return (int64_t)nTime; }
217  int64_t GetBlockTimeMax() const { return (int64_t)nTimeMax; }
218 
219  int64_t GetMedianTimePast() const;
220 
221  int64_t MaxFutureBlockTime() const;
222  int64_t MinPastBlockTime() const;
223 
224  bool IsProofOfStake() const { return (nFlags & BLOCK_PROOF_OF_STAKE); }
225  bool IsProofOfWork() const { return !IsProofOfStake(); }
227 
228  // Stake Modifier
229  unsigned int GetStakeEntropyBit() const;
230  bool SetStakeEntropyBit(unsigned int nEntropyBit);
232  void SetStakeModifier(const uint64_t nStakeModifier, bool fGeneratedStakeModifier);
233  void SetNewStakeModifier(); // generates and sets new v1 modifier
234  void SetStakeModifier(const uint256& nStakeModifier);
235  void SetNewStakeModifier(const uint256& prevoutId); // generates and sets new v2 modifier
236  uint64_t GetStakeModifierV1() const;
237  uint256 GetStakeModifierV2() const;
238 
239  // Update Sapling chain value
240  void SetChainSaplingValue();
241 
243  bool IsValid(enum BlockStatus nUpTo = BLOCK_VALID_TRANSACTIONS) const;
246  bool RaiseValidity(enum BlockStatus nUpTo);
248  void BuildSkip();
250  CBlockIndex* GetAncestor(int height);
251  const CBlockIndex* GetAncestor(int height) const;
252 };
253 
255 const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb);
256 
259 // New serialization introduced with 4.0.99
260 static const int DBI_OLD_SER_VERSION = 4009900;
261 static const int DBI_SER_VERSION_NO_ZC = 4009902; // removes mapZerocoinSupply, nMoneySupply
262 
264 {
265 public:
267 
269  {
271  }
272 
273  explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex)
274  {
276  }
277 
279  {
280  int nSerVersion = s.GetVersion();
281  if (!(s.GetType() & SER_GETHASH)) READWRITE(VARINT_MODE(nSerVersion, VarIntMode::NONNEGATIVE_SIGNED));
282 
284  READWRITE(VARINT(obj.nStatus));
285  READWRITE(VARINT(obj.nTx));
287  if (obj.nStatus & BLOCK_HAVE_DATA) READWRITE(VARINT(obj.nDataPos));
288  if (obj.nStatus & BLOCK_HAVE_UNDO) READWRITE(VARINT(obj.nUndoPos));
289 
290  if (nSerVersion >= DBI_SER_VERSION_NO_ZC) {
291  // Serialization with CLIENT_VERSION = 4009902+
292  READWRITE(obj.nFlags);
293  READWRITE(obj.nVersion);
294  READWRITE(obj.vStakeModifier);
295  READWRITE(obj.hashPrev);
296  READWRITE(obj.hashMerkleRoot);
297  READWRITE(obj.nTime);
298  READWRITE(obj.nBits);
299  READWRITE(obj.nNonce);
300  if(obj.nVersion > 3 && obj.nVersion < 7)
301  READWRITE(obj.nAccumulatorCheckpoint);
302 
303  // Sapling blocks
304  if (obj.nVersion >= 8) {
305  READWRITE(obj.hashFinalSaplingRoot);
306  READWRITE(obj.nSaplingValue);
307  }
308  } else if (nSerVersion > DBI_OLD_SER_VERSION && ser_action.ForRead()) {
309  // Serialization with CLIENT_VERSION = 4009901
310  std::map<libzerocoin::CoinDenomination, int64_t> mapZerocoinSupply;
311  int64_t nMoneySupply = 0;
312  READWRITE(nMoneySupply);
313  READWRITE(obj.nFlags);
314  READWRITE(obj.nVersion);
315  READWRITE(obj.vStakeModifier);
316  READWRITE(obj.hashPrev);
317  READWRITE(obj.hashMerkleRoot);
318  READWRITE(obj.nTime);
319  READWRITE(obj.nBits);
320  READWRITE(obj.nNonce);
321  if (obj.nVersion > 3) {
322  READWRITE(mapZerocoinSupply);
323  if (obj.nVersion < 7) READWRITE(obj.nAccumulatorCheckpoint);
324  }
325  } else if (ser_action.ForRead()) {
326  // Serialization with CLIENT_VERSION = 4009900-
327  int64_t nMint = 0;
328  uint256 hashNext{};
329  int64_t nMoneySupply = 0;
330  READWRITE(nMint);
331  READWRITE(nMoneySupply);
332  READWRITE(obj.nFlags);
333  if (!Params().GetConsensus().NetworkUpgradeActive(obj.nHeight, Consensus::UPGRADE_V3_4)) {
334  uint64_t nStakeModifier = 0;
335  READWRITE(nStakeModifier);
336  SER_READ(obj, obj.SetStakeModifier(nStakeModifier, obj.GeneratedStakeModifier()));
337  } else {
338  uint256 nStakeModifierV2;
339  READWRITE(nStakeModifierV2);
340  SER_READ(obj, obj.SetStakeModifier(nStakeModifierV2));
341  }
342  if (obj.IsProofOfStake()) {
343  COutPoint prevoutStake;
344  unsigned int nStakeTime = 0;
345  READWRITE(prevoutStake);
346  READWRITE(nStakeTime);
347  }
348  READWRITE(obj.nVersion);
349  READWRITE(obj.hashPrev);
350  READWRITE(hashNext);
351  READWRITE(obj.hashMerkleRoot);
352  READWRITE(obj.nTime);
353  READWRITE(obj.nBits);
354  READWRITE(obj.nNonce);
355  if (obj.nVersion > 3) {
356  std::map<libzerocoin::CoinDenomination, int64_t> mapZerocoinSupply;
357  std::vector<libzerocoin::CoinDenomination> vMintDenominationsInBlock;
358  READWRITE(obj.nAccumulatorCheckpoint);
359  READWRITE(mapZerocoinSupply);
360  READWRITE(vMintDenominationsInBlock);
361  }
362  }
363  }
364 
366  {
367  CBlockHeader block;
368  block.nVersion = nVersion;
369  block.hashPrevBlock = hashPrev;
371  block.nTime = nTime;
372  block.nBits = nBits;
373  block.nNonce = nNonce;
374  if (nVersion > 3 && nVersion < 7)
376  if (nVersion >= 8)
378  return block.GetHash();
379  }
380 
381 
382  std::string ToString() const
383  {
384  return strprintf("CDiskBlockIndex(%s\n hashBlock=%s, hashPrev=%s)",
387  hashPrev.ToString());
388  }
389 };
390 
392 class CChain
393 {
394 private:
395  std::vector<CBlockIndex*> vChain;
396 
397 public:
400  {
401  return vChain.size() > 0 ? vChain[0] : nullptr;
402  }
403 
405  CBlockIndex* Tip(bool fProofOfStake = false) const
406  {
407  if (vChain.size() < 1)
408  return nullptr;
409 
410  CBlockIndex* pindex = vChain[vChain.size() - 1];
411 
412  if (fProofOfStake) {
413  while (pindex && pindex->pprev && !pindex->IsProofOfStake())
414  pindex = pindex->pprev;
415  }
416  return pindex;
417  }
418 
420  CBlockIndex* operator[](int nHeight) const
421  {
422  if (nHeight < 0 || nHeight >= (int)vChain.size())
423  return nullptr;
424  return vChain[nHeight];
425  }
426 
428  friend bool operator==(const CChain& a, const CChain& b)
429  {
430  return a.vChain.size() == b.vChain.size() &&
431  a.vChain[a.vChain.size() - 1] == b.vChain[b.vChain.size() - 1];
432  }
433 
435  bool Contains(const CBlockIndex* pindex) const
436  {
437  return (*this)[pindex->nHeight] == pindex;
438  }
439 
441  CBlockIndex* Next(const CBlockIndex* pindex) const
442  {
443  if (Contains(pindex))
444  return (*this)[pindex->nHeight + 1];
445  else
446  return nullptr;
447  }
448 
450  int Height() const
451  {
452  return vChain.size() - 1;
453  }
454 
456  void SetTip(CBlockIndex* pindex);
457 
459  CBlockLocator GetLocator(const CBlockIndex* pindex = nullptr) const;
460 
462  const CBlockIndex* FindFork(const CBlockIndex* pindex) const;
463 
465  CBlockIndex* FindEarliestAtLeast(int64_t nTime) const;
466 };
467 
468 #endif // PIVX_CHAIN_H
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
BlockStatus
Definition: chain.h:87
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, immature coinbase spends.
Definition: chain.h:107
@ BLOCK_VALID_MASK
All validity bits.
Definition: chain.h:113
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
Definition: chain.h:103
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Definition: chain.h:110
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
Definition: chain.h:96
@ BLOCK_HAVE_UNDO
full block available in blk*.dat
Definition: chain.h:118
@ BLOCK_HAVE_DATA
Definition: chain.h:117
@ BLOCK_FAILED_CHILD
stage after last reached validness failed
Definition: chain.h:122
@ BLOCK_FAILED_MASK
descends from failed block
Definition: chain.h:123
@ BLOCK_VALID_HEADER
Parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future.
Definition: chain.h:92
@ BLOCK_FAILED_VALID
Definition: chain.h:121
@ BLOCK_HAVE_MASK
undo data available in rev*.dat
Definition: chain.h:119
@ BLOCK_VALID_UNKNOWN
Unused.
Definition: chain.h:89
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the forking point between two chain tips.
Definition: chain.cpp:337
@ BLOCK_PROOF_OF_STAKE
Definition: chain.h:128
@ BLOCK_STAKE_ENTROPY
Definition: chain.h:129
@ BLOCK_STAKE_MODIFIER
Definition: chain.h:130
const CChainParams & Params()
Return the currently selected parameters.
uint64_t nTimeFirst
earliest time of block in file
Definition: chain.h:40
uint64_t nTimeLast
latest time of block in file
Definition: chain.h:41
void SetNull()
Definition: chain.h:54
std::string ToString() const
CBlockFileInfo()
Definition: chain.h:65
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
update statistics (does not update nSize)
Definition: chain.h:73
unsigned int nHeightFirst
lowest height of block in file
Definition: chain.h:38
unsigned int nHeightLast
highest height of block in file
Definition: chain.h:39
unsigned int nUndoSize
number of used bytes in the undo file
Definition: chain.h:37
unsigned int nBlocks
number of blocks stored in file
Definition: chain.h:35
SERIALIZE_METHODS(CBlockFileInfo, obj)
Definition: chain.h:43
unsigned int nSize
number of used bytes of block file
Definition: chain.h:36
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:23
uint32_t nNonce
Definition: block.h:32
uint256 hashFinalSaplingRoot
Definition: block.h:34
uint32_t nBits
Definition: block.h:31
uint256 nAccumulatorCheckpoint
Definition: block.h:33
uint32_t nTime
Definition: block.h:30
int32_t nVersion
Definition: block.h:27
uint256 hashPrevBlock
Definition: block.h:28
uint256 hashMerkleRoot
Definition: block.h:29
uint256 GetHash() const
Definition: block.cpp:15
Definition: block.h:80
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
bool RaiseValidity(enum BlockStatus nUpTo)
Raise the validity level of this block index entry.
Definition: chain.cpp:323
CBlockIndex()
Definition: chain.h:207
uint256 GetStakeModifierV2() const
Definition: chain.cpp:289
std::string ToString() const
Definition: chain.cpp:138
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:145
void BuildSkip()
Build the skiplist pointer for this entry.
Definition: chain.cpp:118
unsigned int GetStakeEntropyBit() const
Definition: chain.cpp:218
bool IsProofOfStake() const
Definition: chain.h:224
std::vector< unsigned char > vStakeModifier
Definition: chain.h:180
CBlockHeader GetBlockHeader() const
Definition: chain.cpp:166
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: chain.h:163
int nFile
Which # file this block is stored in (blk?????.dat)
Definition: chain.h:154
FlatFilePos GetBlockPos() const
Definition: chain.cpp:146
void SetNewStakeModifier()
Definition: chain.cpp:245
int64_t MaxFutureBlockTime() const
Definition: chain.cpp:180
uint32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
Definition: chain.h:202
void SetProofOfStake()
Definition: chain.h:226
uint32_t nTime
Definition: chain.h:196
unsigned int nTimeMax
(memory only) Maximum nTime in the chain upto and including this block.
Definition: chain.h:205
void SetStakeModifier(const uint64_t nStakeModifier, bool fGeneratedStakeModifier)
Definition: chain.cpp:233
bool SetStakeEntropyBit(unsigned int nEntropyBit)
Definition: chain.cpp:224
bool GeneratedStakeModifier() const
Definition: chain.h:231
bool IsProofOfWork() const
Definition: chain.h:225
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
int64_t GetBlockTime() const
Definition: chain.h:216
void SetChainSaplingValue()
Definition: chain.cpp:298
int64_t GetMedianTimePast() const
Definition: chain.cpp:204
CAmount nSaplingValue
Change in value held by the Sapling circuit over this block.
Definition: chain.h:186
uint32_t nBits
Definition: chain.h:197
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
Definition: chain.h:148
int64_t GetBlockTimeMax() const
Definition: chain.h:217
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:167
uint256 hashFinalSaplingRoot
Definition: chain.h:195
int64_t MinPastBlockTime() const
Definition: chain.cpp:185
FlatFilePos GetUndoPos() const
Definition: chain.cpp:156
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const
Check whether this block index entry is valid up to the passed validity level.
Definition: chain.cpp:313
int32_t nVersion
block header
Definition: chain.h:193
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:113
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
Optional< CAmount > nChainSaplingValue
(memory only) Total value held by the Sapling circuit up to and including this block.
Definition: chain.h:190
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
Definition: chain.h:172
const uint256 * phashBlock
pointer to the hash of the block, if any. memory is owned by this CBlockIndex
Definition: chain.h:142
uint64_t GetStakeModifierV1() const
Definition: chain.cpp:279
An in-memory indexed chain of blocks.
Definition: chain.h:393
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:399
friend bool operator==(const CChain &a, const CChain &b)
Compare two chains efficiently.
Definition: chain.h:428
CBlockIndex * operator[](int nHeight) const
Returns the index entry at a particular height in this chain, or nullptr if no such height exists.
Definition: chain.h:420
CBlockIndex * Next(const CBlockIndex *pindex) const
Find the successor of a block in this chain, or nullptr if the given index is not found or is the tip...
Definition: chain.h:441
CBlockIndex * Tip(bool fProofOfStake=false) const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:405
CBlockLocator GetLocator(const CBlockIndex *pindex=nullptr) const
Return a CBlockLocator that refers to a block in this chain (by default the tip).
Definition: chain.cpp:27
int Height() const
Return the maximal height in the chain.
Definition: chain.h:450
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:56
std::vector< CBlockIndex * > vChain
Definition: chain.h:395
void SetTip(CBlockIndex *pindex)
Set/initialize a chain with a given tip.
Definition: chain.cpp:14
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:435
CBlockIndex * FindEarliestAtLeast(int64_t nTime) const
Find the earliest block with timestamp equal or greater than the given.
Definition: chain.cpp:67
std::string ToString() const
Definition: chain.h:382
uint256 hashPrev
Definition: chain.h:266
SERIALIZE_METHODS(CDiskBlockIndex, obj)
Definition: chain.h:278
CDiskBlockIndex()
Definition: chain.h:268
CDiskBlockIndex(const CBlockIndex *pindex)
Definition: chain.h:273
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
256-bit unsigned big integer.
std::string ToString() const
Definition: uint256.cpp:65
256-bit opaque blob.
Definition: uint256.h:138
@ UPGRADE_V3_4
Definition: params.h:34
boost::optional< T > Optional
Substitute for C++17 std::optional.
Definition: optional.h:12
@ 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 SER_READ(obj, code)
Definition: serialize.h:185
#define READWRITE(...)
Definition: serialize.h:183
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:154
#define strprintf
Definition: tinyformat.h:1056
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