Line | Count | Source (jump to first uncovered line) | ||||||
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 | #include <chain.h> | |||||||
7 | #include <tinyformat.h> | |||||||
8 | #include <util/time.h> | |||||||
9 | ||||||||
10 | std::string CBlockFileInfo::ToString() const | |||||||
11 | 49.9k | { | ||||||
12 | 49.9k | return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast));
| ||||||
13 | 49.9k | } | ||||||
14 | ||||||||
15 | std::string CBlockIndex::ToString() const | |||||||
16 | 0 | { | ||||||
17 | 0 | return strprintf("CBlockIndex(pprev=%p, nHeight=%d, merkle=%s, hashBlock=%s)",
| ||||||
18 | 0 | pprev, nHeight, hashMerkleRoot.ToString(), GetBlockHash().ToString()); | ||||||
19 | 0 | } | ||||||
20 | ||||||||
21 | void CChain::SetTip(CBlockIndex& block) | |||||||
22 | 40.2M | { | ||||||
23 | 40.2M | CBlockIndex* pindex = █ | ||||||
24 | 40.2M | vChain.resize(pindex->nHeight + 1); | ||||||
25 | 3.12G | while (pindex && | ||||||
26 | 3.08G | vChain[pindex->nHeight] = pindex; | ||||||
27 | 3.08G | pindex = pindex->pprev; | ||||||
28 | 3.08G | } | ||||||
29 | 40.2M | } | ||||||
30 | ||||||||
31 | std::vector<uint256> LocatorEntries(const CBlockIndex* index) | |||||||
32 | 24.9k | { | ||||||
33 | 24.9k | int step = 1; | ||||||
34 | 24.9k | std::vector<uint256> have; | ||||||
35 | 24.9k | if (index == nullptr) | ||||||
36 | ||||||||
37 | 24.9k | have.reserve(32); | ||||||
38 | 473k | while (index) { | ||||||
39 | 473k | have.emplace_back(index->GetBlockHash()); | ||||||
40 | 473k | if (index->nHeight == 0) | ||||||
41 | // Exponentially larger steps back, plus the genesis block. | |||||||
42 | 448k | int height = std::max(index->nHeight - step, 0); | ||||||
43 | // Use skiplist. | |||||||
44 | 448k | index = index->GetAncestor(height); | ||||||
45 | 448k | if (have.size() > 10) | ||||||
46 | 448k | } | ||||||
47 | 24.9k | return have; | ||||||
48 | 24.9k | } | ||||||
49 | ||||||||
50 | CBlockLocator GetLocator(const CBlockIndex* index) | |||||||
51 | 24.9k | { | ||||||
52 | 24.9k | return CBlockLocator{LocatorEntries(index)}; | ||||||
53 | 24.9k | } | ||||||
54 | ||||||||
55 | CBlockLocator CChain::GetLocator() const | |||||||
56 | 517 | { | ||||||
57 | 517 | return ::GetLocator(Tip()); | ||||||
58 | 517 | } | ||||||
59 | ||||||||
60 | 20.0M | const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { | ||||||
61 | 20.0M | if (pindex == nullptr) { | ||||||
62 | 49.9k | return nullptr; | ||||||
63 | 49.9k | } | ||||||
64 | 20.0M | if (pindex->nHeight > Height()) | ||||||
65 | 10.0M | pindex = pindex->GetAncestor(Height()); | ||||||
66 | 20.0M | while (pindex && | ||||||
67 | 110 | pindex = pindex->pprev; | ||||||
68 | 20.0M | return pindex; | ||||||
69 | 20.0M | } | ||||||
70 | ||||||||
71 | CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime, int height) const | |||||||
72 | 0 | { | ||||||
73 | 0 | std::pair<int64_t, int> blockparams = std::make_pair(nTime, height); | ||||||
74 | 0 | std::vector<CBlockIndex*>::const_iterator lower = std::lower_bound(vChain.begin(), vChain.end(), blockparams, | ||||||
75 | 0 | [](CBlockIndex* pBlock, const std::pair<int64_t, int>& blockparams) -> bool { return pBlock->GetBlockTimeMax() < blockparams.first || pBlock->nHeight < blockparams.second; }); | ||||||
76 | 0 | return (lower == vChain.end() ? nullptr : *lower); | ||||||
77 | 0 | } | ||||||
78 | ||||||||
79 | /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ | |||||||
80 | 329M | int static inline InvertLowestOne(int n) { return n & (n - 1); } | ||||||
81 | ||||||||
82 | /** Compute what height to jump back to with the CBlockIndex::pskip pointer. */ | |||||||
83 | 221M | int static inline GetSkipHeight(int height) { | ||||||
84 | 221M | if (height < 2) | ||||||
85 | 1.49M | return 0; | ||||||
86 | ||||||||
87 | // Determine which height to jump back to. Any number strictly lower than height is acceptable, | |||||||
88 | // but the following expression seems to perform well in simulations (max 110 steps to go back | |||||||
89 | // up to 2**18 blocks). | |||||||
90 | 219M | return (height & 1) ? | ||||||
91 | 221M | } | ||||||
92 | ||||||||
93 | const CBlockIndex* CBlockIndex::GetAncestor(int height) const | |||||||
94 | 60.9M | { | ||||||
95 | 60.9M | if (height > nHeight || | ||||||
96 | 7.35M | return nullptr; | ||||||
97 | 7.35M | } | ||||||
98 | ||||||||
99 | 53.5M | const CBlockIndex* pindexWalk = this; | ||||||
100 | 53.5M | int heightWalk = nHeight; | ||||||
101 | 159M | while (heightWalk > height) { | ||||||
102 | 105M | int heightSkip = GetSkipHeight(heightWalk); | ||||||
103 | 105M | int heightSkipPrev = GetSkipHeight(heightWalk - 1); | ||||||
104 | 105M | if (pindexWalk->pskip != nullptr && | ||||||
105 | 105M | (heightSkip == height || | ||||||
106 | 105M |
| ||||||
107 | 61.8M |
| ||||||
108 | // Only follow pskip if pprev->pskip isn't better than pskip->pprev. | |||||||
109 | 61.8M | pindexWalk = pindexWalk->pskip; | ||||||
110 | 61.8M | heightWalk = heightSkip; | ||||||
111 | 61.8M | } else { | ||||||
112 | 43.7M | assert(pindexWalk->pprev); | ||||||
113 | 43.7M | pindexWalk = pindexWalk->pprev; | ||||||
114 | 43.7M | heightWalk--; | ||||||
115 | 43.7M | } | ||||||
116 | 105M | } | ||||||
117 | 53.5M | return pindexWalk; | ||||||
118 | 53.5M | } | ||||||
119 | ||||||||
120 | CBlockIndex* CBlockIndex::GetAncestor(int height) | |||||||
121 | 40.0M | { | ||||||
122 | 40.0M | return const_cast<CBlockIndex*>(static_cast<const CBlockIndex*>(this)->GetAncestor(height)); | ||||||
123 | 40.0M | } | ||||||
124 | ||||||||
125 | void CBlockIndex::BuildSkip() | |||||||
126 | 9.99M | { | ||||||
127 | 9.99M | if (pprev) | ||||||
128 | 9.99M | pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); | ||||||
129 | 9.99M | } | ||||||
130 | ||||||||
131 | arith_uint256 GetBlockProof(const CBlockIndex& block) | |||||||
132 | 10.2M | { | ||||||
133 | 10.2M | arith_uint256 bnTarget; | ||||||
134 | 10.2M | bool fNegative; | ||||||
135 | 10.2M | bool fOverflow; | ||||||
136 | 10.2M | bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); | ||||||
137 | 10.2M | if (fNegative || fOverflow || bnTarget == 0) | ||||||
138 | 0 | return 0; | ||||||
139 | // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 | |||||||
140 | // as it's too large for an arith_uint256. However, as 2**256 is at least as large | |||||||
141 | // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1, | |||||||
142 | // or ~bnTarget / (bnTarget+1) + 1. | |||||||
143 | 10.2M | return (~bnTarget / (bnTarget + 1)) + 1; | ||||||
144 | 10.2M | } | ||||||
145 | ||||||||
146 | int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) | |||||||
147 | 0 | { | ||||||
148 | 0 | arith_uint256 r; | ||||||
149 | 0 | int sign = 1; | ||||||
150 | 0 | if (to.nChainWork > from.nChainWork) { | ||||||
151 | 0 | r = to.nChainWork - from.nChainWork; | ||||||
152 | 0 | } else { | ||||||
153 | 0 | r = from.nChainWork - to.nChainWork; | ||||||
154 | 0 | sign = -1; | ||||||
155 | 0 | } | ||||||
156 | 0 | r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip); | ||||||
157 | 0 | if (r.bits() > 63) { | ||||||
158 | 0 | return sign * std::numeric_limits<int64_t>::max(); | ||||||
159 | 0 | } | ||||||
160 | 0 | return sign * int64_t(r.GetLow64()); | ||||||
161 | 0 | } | ||||||
162 | ||||||||
163 | /** Find the last common ancestor two blocks have. | |||||||
164 | * Both pa and pb must be non-nullptr. */ | |||||||
165 | 69.0k | const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb) { | ||||||
166 | 69.0k | if (pa->nHeight > pb->nHeight) { | ||||||
167 | 0 | pa = pa->GetAncestor(pb->nHeight); | ||||||
168 | 69.0k | } else if (pb->nHeight > pa->nHeight) { | ||||||
169 | 63.6k | pb = pb->GetAncestor(pa->nHeight); | ||||||
170 | 63.6k | } | ||||||
171 | ||||||||
172 | 69.2k | while (pa != pb && | ||||||
173 | 225 | pa = pa->pprev; | ||||||
174 | 225 | pb = pb->pprev; | ||||||
175 | 225 | } | ||||||
176 | ||||||||
177 | // Eventually all chain branches meet at the genesis block. | |||||||
178 | 69.0k | assert(pa == pb); | ||||||
179 | 69.0k | return pa; | ||||||
180 | 69.0k | } |