Bitcoin ABC  0.26.3
P2P Digital Currency
blockindex.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2020 The Bitcoin developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #include <blockindex.h>
6 #include <tinyformat.h>
7 
11 static inline int InvertLowestOne(int n) {
12  return n & (n - 1);
13 }
14 
16 static inline int GetSkipHeight(int height) {
17  if (height < 2) {
18  return 0;
19  }
20 
21  // Determine which height to jump back to. Any number strictly lower than
22  // height is acceptable, but the following expression seems to perform well
23  // in simulations (max 110 steps to go back up to 2**18 blocks).
24  return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1
25  : InvertLowestOne(height);
26 }
27 
28 std::string CBlockIndex::ToString() const {
29  return strprintf(
30  "CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)", pprev,
32 }
33 
35  if (pprev == nullptr) {
36  nChainTx = nTx;
37  nChainSize = nSize;
38  return true;
39  }
40 
41  if (pprev->nChainTx > 0) {
44  return true;
45  }
46 
47  nChainTx = 0;
48  nChainSize = 0;
49  return false;
50 }
51 
52 const CBlockIndex *CBlockIndex::GetAncestor(int height) const {
53  if (height > nHeight || height < 0) {
54  return nullptr;
55  }
56 
57  const CBlockIndex *pindexWalk = this;
58  int heightWalk = nHeight;
59  while (heightWalk > height) {
60  int heightSkip = GetSkipHeight(heightWalk);
61  int heightSkipPrev = GetSkipHeight(heightWalk - 1);
62  if (pindexWalk->pskip != nullptr &&
63  (heightSkip == height ||
64  (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
65  heightSkipPrev >= height)))) {
66  // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
67  pindexWalk = pindexWalk->pskip;
68  heightWalk = heightSkip;
69  } else {
70  assert(pindexWalk->pprev);
71  pindexWalk = pindexWalk->pprev;
72  heightWalk--;
73  }
74  }
75  return pindexWalk;
76 }
77 
79  return const_cast<CBlockIndex *>(
80  const_cast<const CBlockIndex *>(this)->GetAncestor(height));
81 }
82 
84  if (pprev) {
86  }
87 }
static int GetSkipHeight(int height)
Compute what height to jump back to with the CBlockIndex::pskip pointer.
Definition: blockindex.cpp:16
static int InvertLowestOne(int n)
Turn the lowest '1' bit in the binary representation of a number into a '0'.
Definition: blockindex.cpp:11
The block chain is a tree shaped structure starting with the genesis block at the root,...
Definition: blockindex.h:25
uint256 hashMerkleRoot
Definition: blockindex.h:91
std::string ToString() const
Definition: blockindex.cpp:28
CBlockIndex * pprev
pointer to the index of the predecessor of this block
Definition: blockindex.h:32
void BuildSkip()
Build the skiplist pointer for this entry.
Definition: blockindex.cpp:83
uint64_t nChainSize
(memory only) Size of all blocks in the chain up to and including this block.
Definition: blockindex.h:83
bool UpdateChainStats()
Update chain tx stats.
Definition: blockindex.cpp:34
CBlockIndex * pskip
pointer to the index of some further predecessor of this block
Definition: blockindex.h:35
unsigned int nTx
Number of transactions in this block.
Definition: blockindex.h:60
CBlockIndex * GetAncestor(int height)
Efficiently find an ancestor of this block.
Definition: blockindex.cpp:78
BlockHash GetBlockHash() const
Definition: blockindex.h:146
unsigned int nSize
Size of this block.
Definition: blockindex.h:65
int nHeight
height of the entry in the chain. The genesis block has height 0
Definition: blockindex.h:38
unsigned int nChainTx
(memory only) Number of transactions in the chain up to and including this block.
Definition: blockindex.h:77
std::string ToString() const
Definition: uint256.h:80
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1202
assert(!tx.IsCoinBase())