1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
9 * CChain implementation
11 void CChain::SetTip(CBlockIndex
*pindex
) {
16 vChain
.resize(pindex
->nHeight
+ 1);
17 while (pindex
&& vChain
[pindex
->nHeight
] != pindex
) {
18 vChain
[pindex
->nHeight
] = pindex
;
19 pindex
= pindex
->pprev
;
23 CBlockLocator
CChain::GetLocator(const CBlockIndex
*pindex
) const {
25 std::vector
<uint256
> vHave
;
31 vHave
.push_back(pindex
->GetBlockHash());
32 // Stop when we have added the genesis block.
33 if (pindex
->nHeight
== 0)
35 // Exponentially larger steps back, plus the genesis block.
36 int nHeight
= std::max(pindex
->nHeight
- nStep
, 0);
37 if (Contains(pindex
)) {
38 // Use O(1) CChain index if possible.
39 pindex
= (*this)[nHeight
];
41 // Otherwise, use O(log n) skiplist.
42 pindex
= pindex
->GetAncestor(nHeight
);
44 if (vHave
.size() > 10)
48 return CBlockLocator(vHave
);
51 const CBlockIndex
*CChain::FindFork(const CBlockIndex
*pindex
) const {
55 if (pindex
->nHeight
> Height())
56 pindex
= pindex
->GetAncestor(Height());
57 while (pindex
&& !Contains(pindex
))
58 pindex
= pindex
->pprev
;
62 CBlockIndex
* CChain::FindEarliestAtLeast(int64_t nTime
) const
64 std::vector
<CBlockIndex
*>::const_iterator lower
= std::lower_bound(vChain
.begin(), vChain
.end(), nTime
,
65 [](CBlockIndex
* pBlock
, const int64_t& time
) -> bool { return pBlock
->GetBlockTimeMax() < time
; });
66 return (lower
== vChain
.end() ? NULL
: *lower
);
69 /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
70 int static inline InvertLowestOne(int n
) { return n
& (n
- 1); }
72 /** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
73 int static inline GetSkipHeight(int height
) {
77 // Determine which height to jump back to. Any number strictly lower than height is acceptable,
78 // but the following expression seems to perform well in simulations (max 110 steps to go back
79 // up to 2**18 blocks).
80 return (height
& 1) ? InvertLowestOne(InvertLowestOne(height
- 1)) + 1 : InvertLowestOne(height
);
83 CBlockIndex
* CBlockIndex::GetAncestor(int height
)
85 if (height
> nHeight
|| height
< 0)
88 CBlockIndex
* pindexWalk
= this;
89 int heightWalk
= nHeight
;
90 while (heightWalk
> height
) {
91 int heightSkip
= GetSkipHeight(heightWalk
);
92 int heightSkipPrev
= GetSkipHeight(heightWalk
- 1);
93 if (pindexWalk
->pskip
!= NULL
&&
94 (heightSkip
== height
||
95 (heightSkip
> height
&& !(heightSkipPrev
< heightSkip
- 2 &&
96 heightSkipPrev
>= height
)))) {
97 // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
98 pindexWalk
= pindexWalk
->pskip
;
99 heightWalk
= heightSkip
;
101 assert(pindexWalk
->pprev
);
102 pindexWalk
= pindexWalk
->pprev
;
109 const CBlockIndex
* CBlockIndex::GetAncestor(int height
) const
111 return const_cast<CBlockIndex
*>(this)->GetAncestor(height
);
114 void CBlockIndex::BuildSkip()
117 pskip
= pprev
->GetAncestor(GetSkipHeight(nHeight
));
120 arith_uint256
GetBlockProof(const CBlockIndex
& block
)
122 arith_uint256 bnTarget
;
125 bnTarget
.SetCompact(block
.nBits
, &fNegative
, &fOverflow
);
126 if (fNegative
|| fOverflow
|| bnTarget
== 0)
128 // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
129 // as it's too large for a arith_uint256. However, as 2**256 is at least as large
130 // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
131 // or ~bnTarget / (nTarget+1) + 1.
132 return (~bnTarget
/ (bnTarget
+ 1)) + 1;
135 int64_t GetBlockProofEquivalentTime(const CBlockIndex
& to
, const CBlockIndex
& from
, const CBlockIndex
& tip
, const Consensus::Params
& params
)
139 if (to
.nChainWork
> from
.nChainWork
) {
140 r
= to
.nChainWork
- from
.nChainWork
;
142 r
= from
.nChainWork
- to
.nChainWork
;
145 r
= r
* arith_uint256(params
.nPowTargetSpacing
) / GetBlockProof(tip
);
147 return sign
* std::numeric_limits
<int64_t>::max();
149 return sign
* r
.GetLow64();