Bitcoin Core  27.1.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 <serialize.h>
15 #include <sync.h>
16 #include <uint256.h>
17 #include <util/time.h>
18 
19 #include <algorithm>
20 #include <cassert>
21 #include <cstdint>
22 #include <string>
23 #include <vector>
24 
29 static constexpr int64_t MAX_FUTURE_BLOCK_TIME = 2 * 60 * 60;
30 
37 static constexpr int64_t TIMESTAMP_WINDOW = MAX_FUTURE_BLOCK_TIME;
38 
45 static constexpr int64_t MAX_BLOCK_TIME_GAP = 90 * 60;
46 
48 {
49 public:
50  unsigned int nBlocks{};
51  unsigned int nSize{};
52  unsigned int nUndoSize{};
53  unsigned int nHeightFirst{};
54  unsigned int nHeightLast{};
55  uint64_t nTimeFirst{};
56  uint64_t nTimeLast{};
57 
59  {
60  READWRITE(VARINT(obj.nBlocks));
61  READWRITE(VARINT(obj.nSize));
62  READWRITE(VARINT(obj.nUndoSize));
63  READWRITE(VARINT(obj.nHeightFirst));
64  READWRITE(VARINT(obj.nHeightLast));
65  READWRITE(VARINT(obj.nTimeFirst));
66  READWRITE(VARINT(obj.nTimeLast));
67  }
68 
70 
71  std::string ToString() const;
72 
74  void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
75  {
76  if (nBlocks == 0 || nHeightFirst > nHeightIn)
77  nHeightFirst = nHeightIn;
78  if (nBlocks == 0 || nTimeFirst > nTimeIn)
79  nTimeFirst = nTimeIn;
80  nBlocks++;
81  if (nHeightIn > nHeightLast)
82  nHeightLast = nHeightIn;
83  if (nTimeIn > nTimeLast)
84  nTimeLast = nTimeIn;
85  }
86 };
87 
88 enum BlockStatus : uint32_t {
91 
94 
98 
105 
109 
112 
116 
120 
124 
126 
142 };
143 
150 {
151 public:
153  const uint256* phashBlock{nullptr};
154 
156  CBlockIndex* pprev{nullptr};
157 
159  CBlockIndex* pskip{nullptr};
160 
162  int nHeight{0};
163 
165  int nFile GUARDED_BY(::cs_main){0};
166 
168  unsigned int nDataPos GUARDED_BY(::cs_main){0};
169 
171  unsigned int nUndoPos GUARDED_BY(::cs_main){0};
172 
175 
181  unsigned int nTx{0};
182 
191  unsigned int nChainTx{0};
192 
199  uint32_t nStatus GUARDED_BY(::cs_main){0};
200 
202  int32_t nVersion{0};
204  uint32_t nTime{0};
205  uint32_t nBits{0};
206  uint32_t nNonce{0};
207 
209  int32_t nSequenceId{0};
210 
212  unsigned int nTimeMax{0};
213 
214  explicit CBlockIndex(const CBlockHeader& block)
215  : nVersion{block.nVersion},
216  hashMerkleRoot{block.hashMerkleRoot},
217  nTime{block.nTime},
218  nBits{block.nBits},
219  nNonce{block.nNonce}
220  {
221  }
222 
224  {
227  if (nStatus & BLOCK_HAVE_DATA) {
228  ret.nFile = nFile;
229  ret.nPos = nDataPos;
230  }
231  return ret;
232  }
233 
235  {
238  if (nStatus & BLOCK_HAVE_UNDO) {
239  ret.nFile = nFile;
240  ret.nPos = nUndoPos;
241  }
242  return ret;
243  }
244 
246  {
247  CBlockHeader block;
248  block.nVersion = nVersion;
249  if (pprev)
250  block.hashPrevBlock = pprev->GetBlockHash();
252  block.nTime = nTime;
253  block.nBits = nBits;
254  block.nNonce = nNonce;
255  return block;
256  }
257 
259  {
260  assert(phashBlock != nullptr);
261  return *phashBlock;
262  }
263 
275  bool HaveNumChainTxs() const { return nChainTx != 0; }
276 
278  {
279  return NodeSeconds{std::chrono::seconds{nTime}};
280  }
281 
282  int64_t GetBlockTime() const
283  {
284  return (int64_t)nTime;
285  }
286 
287  int64_t GetBlockTimeMax() const
288  {
289  return (int64_t)nTimeMax;
290  }
291 
292  static constexpr int nMedianTimeSpan = 11;
293 
294  int64_t GetMedianTimePast() const
295  {
296  int64_t pmedian[nMedianTimeSpan];
297  int64_t* pbegin = &pmedian[nMedianTimeSpan];
298  int64_t* pend = &pmedian[nMedianTimeSpan];
299 
300  const CBlockIndex* pindex = this;
301  for (int i = 0; i < nMedianTimeSpan && pindex; i++, pindex = pindex->pprev)
302  *(--pbegin) = pindex->GetBlockTime();
303 
304  std::sort(pbegin, pend);
305  return pbegin[(pend - pbegin) / 2];
306  }
307 
308  std::string ToString() const;
309 
313  {
315  assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
316  if (nStatus & BLOCK_FAILED_MASK)
317  return false;
318  return ((nStatus & BLOCK_VALID_MASK) >= nUpTo);
319  }
320 
324  {
326  return nStatus & BLOCK_ASSUMED_VALID;
327  }
328 
332  {
334  assert(!(nUpTo & ~BLOCK_VALID_MASK)); // Only validity flags allowed.
335  if (nStatus & BLOCK_FAILED_MASK) return false;
336 
337  if ((nStatus & BLOCK_VALID_MASK) < nUpTo) {
338  // If this block had been marked assumed-valid and we're raising
339  // its validity to a certain point, there is no longer an assumption.
340  if (nStatus & BLOCK_ASSUMED_VALID && nUpTo >= BLOCK_VALID_SCRIPTS) {
341  nStatus &= ~BLOCK_ASSUMED_VALID;
342  }
343 
344  nStatus = (nStatus & ~BLOCK_VALID_MASK) | nUpTo;
345  return true;
346  }
347  return false;
348  }
349 
351  void BuildSkip();
352 
354  CBlockIndex* GetAncestor(int height);
355  const CBlockIndex* GetAncestor(int height) const;
356 
357  CBlockIndex() = default;
358  ~CBlockIndex() = default;
359 
360 protected:
370  CBlockIndex(const CBlockIndex&) = default;
371  CBlockIndex& operator=(const CBlockIndex&) = delete;
372  CBlockIndex(CBlockIndex&&) = delete;
373  CBlockIndex& operator=(CBlockIndex&&) = delete;
374 };
375 
378 int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params&);
380 const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb);
381 
382 
385 {
392  static constexpr int DUMMY_VERSION = 259900;
393 
394 public:
396 
398  {
399  hashPrev = uint256();
400  }
401 
402  explicit CDiskBlockIndex(const CBlockIndex* pindex) : CBlockIndex(*pindex)
403  {
404  hashPrev = (pprev ? pprev->GetBlockHash() : uint256());
405  }
406 
408  {
409  LOCK(::cs_main);
410  int _nVersion = DUMMY_VERSION;
412 
414  READWRITE(VARINT(obj.nStatus));
415  READWRITE(VARINT(obj.nTx));
417  if (obj.nStatus & BLOCK_HAVE_DATA) READWRITE(VARINT(obj.nDataPos));
418  if (obj.nStatus & BLOCK_HAVE_UNDO) READWRITE(VARINT(obj.nUndoPos));
419 
420  // block header
421  READWRITE(obj.nVersion);
422  READWRITE(obj.hashPrev);
423  READWRITE(obj.hashMerkleRoot);
424  READWRITE(obj.nTime);
425  READWRITE(obj.nBits);
426  READWRITE(obj.nNonce);
427  }
428 
430  {
431  CBlockHeader block;
432  block.nVersion = nVersion;
433  block.hashPrevBlock = hashPrev;
435  block.nTime = nTime;
436  block.nBits = nBits;
437  block.nNonce = nNonce;
438  return block.GetHash();
439  }
440 
441  uint256 GetBlockHash() = delete;
442  std::string ToString() = delete;
443 };
444 
446 class CChain
447 {
448 private:
449  std::vector<CBlockIndex*> vChain;
450 
451 public:
452  CChain() = default;
453  CChain(const CChain&) = delete;
454  CChain& operator=(const CChain&) = delete;
455 
458  {
459  return vChain.size() > 0 ? vChain[0] : nullptr;
460  }
461 
463  CBlockIndex* Tip() const
464  {
465  return vChain.size() > 0 ? vChain[vChain.size() - 1] : nullptr;
466  }
467 
470  {
471  if (nHeight < 0 || nHeight >= (int)vChain.size())
472  return nullptr;
473  return vChain[nHeight];
474  }
475 
477  bool Contains(const CBlockIndex* pindex) const
478  {
479  return (*this)[pindex->nHeight] == pindex;
480  }
481 
483  CBlockIndex* Next(const CBlockIndex* pindex) const
484  {
485  if (Contains(pindex))
486  return (*this)[pindex->nHeight + 1];
487  else
488  return nullptr;
489  }
490 
492  int Height() const
493  {
494  return int(vChain.size()) - 1;
495  }
496 
498  void SetTip(CBlockIndex& block);
499 
501  CBlockLocator GetLocator() const;
502 
504  const CBlockIndex* FindFork(const CBlockIndex* pindex) const;
505 
507  CBlockIndex* FindEarliestAtLeast(int64_t nTime, int height) const;
508 };
509 
511 CBlockLocator GetLocator(const CBlockIndex* index);
512 
514 std::vector<uint256> LocatorEntries(const CBlockIndex* index);
515 
516 #endif // BITCOIN_CHAIN_H
uint32_t nNonce
Definition: block.h:30
arith_uint256 nChainWork
(memory only) Total amount of work (expected number of hashes) in the chain up to and including this ...
Definition: chain.h:174
#define VARINT(obj)
Definition: serialize.h:513
int ret
std::string ToString() const
Definition: chain.cpp:15
int32_t nSequenceId
(memory only) Sequential id assigned to distinguish order in which blocks are received.
Definition: chain.h:209
bool HaveNumChainTxs() const
Check whether this block&#39;s and all previous blocks&#39; transactions have been downloaded (and stored to ...
Definition: chain.h:275
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
Definition: chain.h:159
std::vector< CBlockIndex * > vChain
Definition: chain.h:449
AssertLockHeld(pool.cs)
int64_t GetBlockTime() const
Definition: chain.h:282
assert(!tx.IsCoinBase())
NodeSeconds Time() const
Definition: chain.h:277
Describes a place in the block chain to another node such that if the other node doesn&#39;t have the sam...
Definition: block.h:123
descends from failed block
Definition: chain.h:122
Reserved (was BLOCK_VALID_HEADER).
Definition: chain.h:93
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: chain.h:156
void AddBlock(unsigned int nHeightIn, uint64_t nTimeIn)
update statistics (does not update nSize)
Definition: chain.h:74
CBlockLocator GetLocator(const CBlockIndex *index)
Get a locator for a block index entry.
Definition: chain.cpp:50
const CBlockIndex * LastCommonAncestor(const CBlockIndex *pa, const CBlockIndex *pb)
Find the forking point between two chain tips.
Definition: chain.cpp:165
An in-memory indexed chain of blocks.
Definition: chain.h:446
int nFile GUARDED_BY(::cs_main)
Which # file this block is stored in (blk?????.dat)
Definition: chain.h:165
unsigned int nHeight
All parent headers found, difficulty matches, timestamp >= median previous, checkpoint.
Definition: chain.h:97
CBlockHeader GetBlockHeader() const
Definition: chain.h:245
int Height() const
Return the maximal height in the chain.
Definition: chain.h:492
stage after last reached validness failed
Definition: chain.h:121
Only first tx is coinbase, 2 <= coinbase input script length <= 100, transactions valid...
Definition: chain.h:104
unsigned int nSize
number of used bytes of block file
Definition: chain.h:51
~CBlockIndex()=default
CBlockIndex * Genesis() const
Returns the index entry for the genesis block of this chain, or nullptr if none.
Definition: chain.h:457
CChain()=default
uint32_t nTime
Definition: chain.h:204
undo data available in rev*.dat
Definition: chain.h:118
Unused.
Definition: chain.h:90
SERIALIZE_METHODS(CDiskBlockIndex, obj)
Definition: chain.h:407
void SetTip(CBlockIndex &block)
Set/initialize a chain with a given tip.
Definition: chain.cpp:21
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:37
unsigned int nHeightLast
highest height of block in file
Definition: chain.h:54
uint32_t nTime
Definition: block.h:28
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block. ...
Definition: chain.h:191
unsigned int nUndoSize
number of used bytes in the undo file
Definition: chain.h:52
CBlockIndex()=default
std::chrono::time_point< NodeClock, std::chrono::seconds > NodeSeconds
Definition: time.h:23
static constexpr int nMedianTimeSpan
Definition: chain.h:292
uint256 GetBlockHash() const
Definition: chain.h:258
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
CBlockLocator GetLocator() const
Return a CBlockLocator that refers to the tip in of this chain.
Definition: chain.cpp:55
#define VARINT_MODE(obj, mode)
Definition: serialize.h:512
arith_uint256 GetBlockProof(const CBlockIndex &block)
Definition: chain.cpp:131
Outputs do not overspend inputs, no double spends, coinbase output ok, no immature coinbase spends...
Definition: chain.h:108
unsigned int nTimeMax
(memory only) Maximum nTime in the chain up to and including this block.
Definition: chain.h:212
uint64_t nTimeFirst
earliest time of block in file
Definition: chain.h:55
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:469
Scripts & signatures ok. Implies all parents are either at least VALID_SCRIPTS, or are ASSUMED_VALID...
Definition: chain.h:111
uint256 hashMerkleRoot
Definition: block.h:27
std::string ToString()=delete
uint32_t nNonce
Definition: chain.h:206
#define LOCK(cs)
Definition: sync.h:257
CBlockFileInfo()
Definition: chain.h:69
bool Contains(const CBlockIndex *pindex) const
Efficiently check whether a block is present in this chain.
Definition: chain.h:477
CBlockIndex(const CBlockHeader &block)
Definition: chain.h:214
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:483
uint256 hashPrevBlock
Definition: block.h:26
std::vector< uint256 > LocatorEntries(const CBlockIndex *index)
Construct a list of hash entries to put in a locator.
Definition: chain.cpp:31
int64_t GetBlockTimeMax() const
Definition: chain.h:287
static constexpr int DUMMY_VERSION
Historically CBlockLocator&#39;s version field has been written to disk streams as the client version...
Definition: chain.h:392
CDiskBlockIndex()
Definition: chain.h:397
uint256 hashMerkleRoot
Definition: chain.h:203
CChain & operator=(const CChain &)=delete
unsigned int nHeightFirst
lowest height of block in file
Definition: chain.h:53
void BuildSkip()
Build the skiplist pointer for this entry.
Definition: chain.cpp:125
Used to marshal pointers into hashes for db storage.
Definition: chain.h:384
Parameters that influence chain consensus.
Definition: params.h:74
256-bit unsigned big integer.
int64_t GetMedianTimePast() const
Definition: chain.h:294
block data in blk*.dat was received with a witness-enforcing client
Definition: chain.h:125
FlatFilePos GetUndoPos() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: chain.h:234
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
unsigned int nDataPos GUARDED_BY(::cs_main)
Byte offset within blk?????.dat where this block&#39;s data is stored.
Definition: chain.h:168
uint32_t nStatus GUARDED_BY(::cs_main)
Verification status of this block.
Definition: chain.h:199
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:311
uint256 GetHash() const
Definition: block.cpp:11
int32_t nVersion
block header
Definition: chain.h:202
256-bit opaque blob.
Definition: uint256.h:106
uint256 ConstructBlockHash() const
Definition: chain.h:429
uint256 hashPrev
Definition: chain.h:395
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:49
unsigned int nUndoPos GUARDED_BY(::cs_main)
Byte offset within rev?????.dat where this block&#39;s undo data is stored.
Definition: chain.h:171
CDiskBlockIndex(const CBlockIndex *pindex)
Definition: chain.h:402
The block chain is a tree shaped structure starting with the genesis block at the root...
Definition: chain.h:149
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
Definition: chain.h:463
bool RaiseValidity(enum BlockStatus nUpTo) EXCLUSIVE_LOCKS_REQUIRED(
Raise the validity level of this block index entry.
Definition: chain.h:331
bool IsAssumedValid() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: chain.h:323
unsigned int nBlocks
number of blocks stored in file
Definition: chain.h:50
BlockStatus
Definition: chain.h:88
All validity bits.
Definition: chain.h:114
uint64_t nTimeLast
latest time of block in file
Definition: chain.h:56
static constexpr int64_t MAX_FUTURE_BLOCK_TIME
Maximum amount of time that a block timestamp is allowed to exceed the current time before the block ...
Definition: chain.h:29
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: chain.h:162
FlatFilePos GetBlockPos() const EXCLUSIVE_LOCKS_REQUIRED(
Definition: chain.h:223
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: chain.cpp:120
full block available in blk*.dat
Definition: chain.h:117
SERIALIZE_METHODS(CBlockFileInfo, obj)
Definition: chain.h:58
#define READWRITE(...)
Definition: serialize.h:156
std::string ToString() const
Definition: chain.cpp:10
If ASSUMED_VALID is set, it means that this block has not been validated and has validity status less...
Definition: chain.h:141
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Definition: cs_main.cpp:8
const CBlockIndex * FindFork(const CBlockIndex *pindex) const
Find the last common block between this chain and a block index entry.
Definition: chain.cpp:60
int32_t nVersion
Definition: block.h:25
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:45
uint32_t nBits
Definition: chain.h:205
unsigned int nTx
Number of transactions in this block.
Definition: chain.h:181
Nodes collect new transactions into a block, hash them into a hash tree, and scan through nonce value...
Definition: block.h:21
uint32_t nBits
Definition: block.h:29
uint256 GetBlockHash()=delete
CBlockIndex & operator=(const CBlockIndex &)=delete
const uint256 * phashBlock
pointer to the hash of the block, if any. Memory is owned by this CBlockIndex
Definition: chain.h:153