Bitcoin Core  24.99.0
P2P Digital Currency
chain.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2022 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 #ifndef BITCOIN_CHAIN_H
7 #define BITCOIN_CHAIN_H
8 
9 #include <arith_uint256.h>
10 #include <consensus/params.h>
11 #include <flatfile.h>
12 #include <kernel/cs_main.h>
13 #include <primitives/block.h>
14 #include <sync.h>
15 #include <uint256.h>
16 #include <util/time.h>
17 
18 #include <vector>
19 
24 static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60;
25 
32 static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME;
33 
40 static constexpr int64_t MAX_BLOCK_TIME_GAP = 90 * 60;
41 
43 {
44 public:
45  unsigned int nBlocks;
46  unsigned int nSize;
47  unsigned int nUndoSize;
48  unsigned int nHeightFirst;
49  unsigned int nHeightLast;
50  uint64_t nTimeFirst;
51  uint64_t nTimeLast;
52 
54  {
55  READWRITE(VARINT(obj.nBlocks));
56  READWRITE(VARINT(obj.nSize));
57  READWRITE(VARINT(obj.nUndoSize));
58  READWRITE(VARINT(obj.nHeightFirst));
59  READWRITE(VARINT(obj.nHeightLast));
60  READWRITE(VARINT(obj.nTimeFirst));
61  READWRITE(VARINT(obj.nTimeLast));
62  }
63 
64  void SetNull()
65  {
66  nBlocks = 0;
67  nSize = 0;
68  nUndoSize = 0;
69  nHeightFirst = 0;
70  nHeightLast = 0;
71  nTimeFirst = 0;
72  nTimeLast = 0;
73  }
74 
76  {
77  SetNull();
78  }
79 
80  std::string ToString() const;
81 
83  void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
84  {
85  if (nBlocks == 0 || nHeightFirst > nHeightIn)
86  nHeightFirst = nHeightIn;
87  if (nBlocks == 0 || nTimeFirst > nTimeIn)
88  nTimeFirst = nTimeIn;
89  nBlocks++;
90  if (nHeightIn > nHeightLast)
91  nHeightLast = nHeightIn;
92  if (nTimeIn > nTimeLast)
93  nTimeLast = nTimeIn;
94  }
95 };
96 
97 enum BlockStatus : uint32_t {
100 
103 
107 
114 
118 
121 
125 
129 
133 
135 
143 };
144 
151 {
152 public:
154  const uint256* phashBlock{nullptr};
155 
157  CBlockIndex* pprev{nullptr};
158 
160  CBlockIndex* pskip{nullptr};
161 
163  int nHeight{0};
164 
166  int nFile GUARDED_BY(::cs_main){0};
167 
169  unsigned int nDataPos GUARDED_BY(::cs_main){0};
170 
172  unsigned int nUndoPos GUARDED_BY(::cs_main){0};
173 
176 
182  unsigned int nTx{0};
183 
192  unsigned int nChainTx{0};
193 
200  uint32_t nStatus GUARDED_BY(::cs_main){0};
201 
203  int32_t nVersion{0};
205  uint32_t nTime{0};
206  uint32_t nBits{0};
207  uint32_t nNonce{0};
208 
210  int32_t nSequenceId{0};
211 
213  unsigned int nTimeMax{0};
214 
215  explicit CBlockIndex(const CBlockHeader& block)
216  : nVersion{block.nVersion},
218  nTime{block.nTime},
219  nBits{block.nBits},
220  nNonce{block.nNonce}
221  {
222  }
223 
225  {
228  if (nStatus & BLOCK_HAVE_DATA) {
229  ret.nFile = nFile;
230  ret.nPos = nDataPos;
231  }
232  return ret;
233  }
234 
236  {
239  if (nStatus & BLOCK_HAVE_UNDO) {
240  ret.nFile = nFile;
241  ret.nPos = nUndoPos;
242  }
243  return ret;
244  }
245 
247  {
248  CBlockHeader block;
249  block.nVersion = nVersion;
250  if (pprev)
251  block.hashPrevBlock = pprev->GetBlockHash();
253  block.nTime = nTime;
254  block.nBits = nBits;
255  block.nNonce = nNonce;
256  return block;
257  }
258 
260  {
261  assert(phashBlock != nullptr);
262  return *phashBlock;
263  }
264 
272  bool HaveTxsDownloaded() const { return nChainTx != 0; }
273 
275  {
276  return NodeSeconds{std::chrono::seconds{nTime}};
277  }
278 
279  int64_t GetBlockTime() const
280  {
281  return (int64_t)nTime;
282  }
283 
284  int64_t GetBlockTimeMax() const
285  {
286  return (int64_t)nTimeMax;
287  }
288 
289  static constexpr int nMedianTimeSpan = 11;
290 
291  int64_t GetMedianTimePast() const
292  {
293  int64_t pmedian[nMedianTimeSpan];
294  int64_t* pbegin = &pmedian[nMedianTimeSpan];
295  int64_t* pend = &pmedian[nMedianTimeSpan];
296 
297  const CBlockIndex* pindex = this;
298  for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
299  *(--pbegin) = pindex->GetBlockTime();
300 
301  std::sort(pbegin, pend);
302  return pbegin[(pend - pbegin) / 2];
303  }
304 
305  std::string ToString() const;
306 
310  {
312  assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
313  if (nStatus & BLOCK_FAILED_MASK)
314  return false;
315  return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
316  }
317 
321  {
323  return nStatus & BLOCK_ASSUMED_VALID;
324  }
325 
329  {
331  assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
332  if (nStatus & BLOCK_FAILED_MASK) return false;
333 
334  if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
335  // If this block had been marked assumed-valid and we're raising
336  // its validity to a certain point, there is no longer an assumption.
337  if (nStatus & BLOCK_ASSUMED_VALID && nUpTo >= BLOCK_VALID_SCRIPTS) {
338  nStatus &= ~BLOCK_ASSUMED_VALID;
339  }
340 
341  nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
342  return true;
343  }
344  return false;
345  }
346 
348  void BuildSkip();
349 
351  CBlockIndex* GetAncestor(int height);
352  const CBlockIndex* GetAncestor(int height) const;
353 
354  CBlockIndex() = default;
355  ~CBlockIndex() = default;
356 
357 protected:
367  CBlockIndex(const CBlockIndex&) = default;
368  CBlockIndex& operator=(const CBlockIndex&) = delete;
371 };
372 
375 int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
377 const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb);
378 
379 
382 {
383 public:
385 
387  {
388  hashPrev = uint256();
389  }
390 
391  explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex)
392  {
393  hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
394  }
395 
397  {
398  LOCK(::cs_main);
399  int _nVersion = s.GetVersion();
400  if (!(s.GetType() & SER_GETHASH)) READWRITE(VARINT_MODE(_nVersion, VarIntMode::NONNEGATIVE_SIGNED));
401 
403  READWRITE(VARINT(obj.nStatus));
404  READWRITE(VARINT(obj.nTx));
406  if (obj.nStatus & BLOCK_HAVE_DATA) READWRITE(VARINT(obj.nDataPos));
407  if (obj.nStatus & BLOCK_HAVE_UNDO) READWRITE(VARINT(obj.nUndoPos));
408 
409  // block header
410  READWRITE(obj.nVersion);
411  READWRITE(obj.hashPrev);
412  READWRITE(obj.hashMerkleRoot);
413  READWRITE(obj.nTime);
414  READWRITE(obj.nBits);
415  READWRITE(obj.nNonce);
416  }
417 
419  {
420  CBlockHeader block;
421  block.nVersion = nVersion;
422  block.hashPrevBlock = hashPrev;
424  block.nTime = nTime;
425  block.nBits = nBits;
426  block.nNonce = nNonce;
427  return block.GetHash();
428  }
429 
430  uint256 GetBlockHash() = delete;
431  std::string ToString() = delete;
432 };
433 
435 class CChain
436 {
437 private:
438  std::vector<CBlockIndex*> vChain;
439 
440 public:
441  CChain() = default;
442  CChain(const CChain&) = delete;
443  CChain& operator=(const CChain&) = delete;
444 
447  {
448  return vChain.size() > 0 ? vChain[0] : nullptr;
449  }
450 
452  CBlockIndex* Tip() const
453  {
454  return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr;
455  }
456 
459  {
460  if (nHeight < 0 || nHeight >= (int)vChain.size())
461  return nullptr;
462  return vChain[nHeight];
463  }
464 
466  bool Contains(const CBlockIndex* pindex) const
467  {
468  return (*this)[pindex->nHeight] == pindex;
469  }
470 
472  CBlockIndex* Next(const CBlockIndex* pindex) const
473  {
474  if (Contains(pindex))
475  return (*this)[pindex->nHeight + 1];
476  else
477  return nullptr;
478  }
479 
481  int Height() const
482  {
483  return int(vChain.size()) - 1;
484  }
485 
487  void SetTip(CBlockIndex& block);
488 
490  CBlockLocator GetLocator() const;
491 
493  const CBlockIndex* FindFork(const CBlockIndex* pindex) const;
494 
496  CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const;
497 };
498 
500 CBlockLocator GetLocator(const CBlockIndex* index);
501 
503 std::vector<uint256> LocatorEntries(const CBlockIndex* index);
504 
505 #endif // BITCOIN_CHAIN_H
int ret
BlockStatus
Definition: chain.h:97
@ BLOCK_VALID_CHAIN
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends,...
Definition: chain.h:117
@ BLOCK_VALID_MASK
All validity bits.
Definition: chain.h:123
@ BLOCK_ASSUMED_VALID
If set, this indicates that the block index entry is assumed-valid.
Definition: chain.h:142
@ BLOCK_VALID_TRANSACTIONS
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid,...
Definition: chain.h:113
@ BLOCK_VALID_SCRIPTS
Scripts & signatures ok. Implies all parents are also at least SCRIPTS.
Definition: chain.h:120
@ BLOCK_VALID_RESERVED
Reserved (was BLOCK_VALID_HEADER).
Definition: chain.h:102
@ BLOCK_VALID_TREE
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
Definition: chain.h:106
@ BLOCK_HAVE_UNDO
undo data available in rev*.dat
Definition: chain.h:127
@ BLOCK_HAVE_DATA
full block available in blk*.dat
Definition: chain.h:126
@ BLOCK_FAILED_CHILD
descends from failed block
Definition: chain.h:131
@ BLOCK_FAILED_MASK
Definition: chain.h:132
@ BLOCK_FAILED_VALID
stage after last reached validness failed
Definition: chain.h:130
@ BLOCK_OPT_WITNESS
block data in blk*.dat was received with a witness-enforcing client
Definition: chain.h:134
@ BLOCK_HAVE_MASK
Definition: chain.h:128
@ BLOCK_VALID_UNKNOWN
Unused.
Definition: chain.h:99
arith_uint256 GetBlockProof(const CBlockIndex &block)
Definition: chain.cpp:131
CBlockLocator GetLocator(const CBlockIndex *index)
Get a locator for a block index entry.
Definition: chain.cpp:50
int64_t GetBlockProofEquivalentTime(const CBlockIndex &to, const CBlockIndex &from, const CBlockIndex &tip, const Consensus::Params &)
Return the time it would take to redo the work difference between from and to, assuming the current h...
Definition: chain.cpp:146
static constexpr int64_t MAX_BLOCK_TIME_GAP
Maximum gap between node time and block time used for the "Catching up..." mode in GUI.
Definition: chain.h:40
static constexpr int64_t MAX_FUTURE_BLOCK_TIME
Maximum amount of time that a block timestamp is allowed to exceed the current network-adjusted time ...
Definition: chain.h:24
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the forking point between two chain tips.
Definition: chain.cpp:165
static constexpr int64_t TIMESTAMP_WINDOW
Timestamp window used as a grace period by code that compares external timestamps (such as timestamps...
Definition: chain.h:32
std::vector< uint256 > LocatorEntries(const CBlockIndex *index)
Construct a list of hash entries to put in a locator.
Definition: chain.cpp:31
uint64_t nTimeFirst
earliest time of block in file
Definition: chain.h:50
uint64_t nTimeLast
latest time of block in file
Definition: chain.h:51
void SetNull()
Definition: chain.h:64
std::string ToString() const
Definition: chain.cpp:10
CBlockFileInfo()
Definition: chain.h:75
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
update statistics (does not update nSize)
Definition: chain.h:83
unsigned int nHeightFirst
lowest height of block in file
Definition: chain.h:48
unsigned int nHeightLast
highest height of block in file
Definition: chain.h:49
unsigned int nUndoSize
number of used bytes in the undo file
Definition: chain.h:47
unsigned int nBlocks
number of blocks stored in file
Definition: chain.h:45
SERIALIZE_METHODS(CBlockFileInfo, obj)
Definition: chain.h:53
unsigned int nSize
number of used bytes of block file
Definition: chain.h:46
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:22
uint32_t nNonce
Definition: block.h:30
uint32_t nBits
Definition: block.h:29
uint32_t nTime
Definition: block.h:28
int32_t nVersion
Definition: block.h:25
uint256 hashPrevBlock
Definition: block.h:26
uint256 hashMerkleRoot
Definition: block.h:27
uint256 GetHash() const
Definition: block.cpp:11
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: chain.h:151
uint256 hashMerkleRoot
Definition: chain.h:204
uint32_t nStatus GUARDED_BY(::cs_main)
Verification status of this block.
Definition: chain.h:200
std::string ToString() const
Definition: chain.cpp:15
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:157
bool IsAssumedValid() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: chain.h:320
void BuildSkip()
Build the skiplist pointer for this entry.
Definition: chain.cpp:125
CBlockHeader GetBlockHeader() const
Definition: chain.h:246
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: chain.h:175
CBlockIndex()=default
bool HaveTxsDownloaded() const
Check whether this block's and all previous blocks' transactions have been downloaded (and stored to ...
Definition: chain.h:272
unsigned int nDataPos GUARDED_BY(::cs_main)
Byte offset within blk?????.dat where this block's data is stored.
Definition: chain.h:169
unsigned int nUndoPos GUARDED_BY(::cs_main)
Byte offset within rev?????.dat where this block's undo data is stored.
Definition: chain.h:172
uint32_t nTime
Definition: chain.h:205
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
Definition: chain.h:213
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
Definition: chain.h:210
CBlockIndex & operator=(const CBlockIndex &)=delete
uint32_t nNonce
Definition: chain.h:207
uint256 GetBlockHash() const
Definition: chain.h:259
~CBlockIndex()=default
int64_t GetBlockTime() const
Definition: chain.h:279
int64_t GetMedianTimePast() const
Definition: chain.h:291
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: chain.h:235
uint32_t nBits
Definition: chain.h:206
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(
Raise the validity level of this block index entry.
Definition: chain.h:328
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
Definition: chain.h:160
int64_t GetBlockTimeMax() const
Definition: chain.h:284
CBlockIndex(CBlockIndex &&)=delete
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:182
CBlockIndex(const CBlockHeader &block)
Definition: chain.h:215
bool IsValid(enum BlockStatus nUpTo=BLOCK_VALID_TRANSACTIONS) const EXCLUSIVE_LOCKS_REQUIRED(
Check whether this block index entry is valid up to the passed validity level.
Definition: chain.h:308
CBlockIndex & operator=(CBlockIndex &&)=delete
NodeSeconds Time() const
Definition: chain.h:274
int32_t nVersion
block header
Definition: chain.h:203
CBlockIndex(const CBlockIndex &)=default
CBlockIndex should not allow public copy construction because equality comparison via pointer is very...
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:120
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:163
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: chain.h:224
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
Definition: chain.h:192
int nFile GUARDED_BY(::cs_main)
Which # file this block is stored in (blk?????.dat)
Definition: chain.h:166
static constexpr int nMedianTimeSpan
Definition: chain.h:289
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
Definition: chain.h:154
An in-memory indexed chain of blocks.
Definition: chain.h:436
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:446
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:458
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:472
CChain(const CChain &)=delete
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:452
void SetTip(CBlockIndex &block)
Set/initialize a chain with a given tip.
Definition: chain.cpp:21
CChain()=default
CChain & operator=(const CChain &)=delete
CBlockIndex * FindEarliestAtLeast(int64_t nTime, int height) const
Find the earliest block with timestamp equal or greater than the given time and height equal or great...
Definition: chain.cpp:71
int Height() const
Return the maximal height in the chain.
Definition: chain.h:481
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:60
std::vector< CBlockIndex * > vChain
Definition: chain.h:438
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:466
CBlockLocator GetLocator() const
Return a CBlockLocator that refers to the tip in of this chain.
Definition: chain.cpp:55
Used to marshal pointers into hashes for db storage.
Definition: chain.h:382
std::string ToString()=delete
uint256 hashPrev
Definition: chain.h:384
uint256 GetBlockHash()=delete
uint256 ConstructBlockHash() const
Definition: chain.h:418
SERIALIZE_METHODS(CDiskBlockIndex, obj)
Definition: chain.h:396
CDiskBlockIndex()
Definition: chain.h:386
CDiskBlockIndex(const CBlockIndex *pindex)
Definition: chain.h:391
256-bit unsigned big integer.
256-bit opaque blob.
Definition: uint256.h:105
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
Definition: cs_main.cpp:8
unsigned int nHeight
#define VARINT(obj)
Definition: serialize.h:436
#define VARINT_MODE(obj, mode)
Definition: serialize.h:435
@ SER_GETHASH
Definition: serialize.h:133
@ NONNEGATIVE_SIGNED
#define READWRITE(...)
Definition: serialize.h:140
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:121
Parameters that influence chain consensus.
Definition: params.h:74
#define LOCK(cs)
Definition: sync.h:258
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
Definition: time.h:25
AssertLockHeld(pool.cs)
assert(!tx.IsCoinBase())