Branch data Line data Source code
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 : 1 : std::string CBlockFileInfo::ToString() const 11 : : { 12 [ + - ][ - + ]: 1 : return strprintf("CBlockFileInfo(blocks=%u, size=%u, heights=%u...%u, time=%s...%s)", nBlocks, nSize, nHeightFirst, nHeightLast, FormatISO8601Date(nTimeFirst), FormatISO8601Date(nTimeLast)); 13 : 0 : } 14 : : 15 : 0 : std::string CBlockIndex::ToString() const 16 : : { 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 : 201 : void CChain::SetTip(CBlockIndex& block) 22 : : { 23 : 201 : CBlockIndex* pindex = █ 24 : 201 : vChain.resize(pindex->nHeight + 1); 25 [ + + ][ + + ]: 402 : while (pindex && vChain[pindex->nHeight] != pindex) { 26 : 201 : vChain[pindex->nHeight] = pindex; 27 : 201 : pindex = pindex->pprev; 28 : : } 29 : 201 : } 30 : : 31 : 6 : std::vector<uint256> LocatorEntries(const CBlockIndex* index) 32 : : { 33 : 6 : int step = 1; 34 : 6 : std::vector<uint256> have; 35 [ + - ]: 6 : if (index == nullptr) return have; 36 : : 37 [ + - ]: 6 : have.reserve(32); 38 [ - + ]: 114 : while (index) { 39 [ + - ][ + - ]: 114 : have.emplace_back(index->GetBlockHash()); 40 [ + + ]: 114 : if (index->nHeight == 0) break; 41 : : // Exponentially larger steps back, plus the genesis block. 42 [ + - ]: 108 : int height = std::max(index->nHeight - step, 0); 43 : : // Use skiplist. 44 [ + - ]: 108 : index = index->GetAncestor(height); 45 [ + + ]: 108 : if (have.size() > 10) step *= 2; 46 : : } 47 : 6 : return have; 48 [ + - ]: 6 : } 49 : : 50 : 6 : CBlockLocator GetLocator(const CBlockIndex* index) 51 : : { 52 [ + - ]: 6 : return CBlockLocator{LocatorEntries(index)}; 53 : 0 : } 54 : : 55 : 0 : CBlockLocator CChain::GetLocator() const 56 : : { 57 : 0 : return ::GetLocator(Tip()); 58 : : } 59 : : 60 : 402 : const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const { 61 [ + + ]: 402 : if (pindex == nullptr) { 62 : 1 : return nullptr; 63 : : } 64 [ + + ]: 401 : if (pindex->nHeight > Height()) 65 : 201 : pindex = pindex->GetAncestor(Height()); 66 [ + + ][ - + ]: 401 : while (pindex && !Contains(pindex)) 67 : 0 : pindex = pindex->pprev; 68 : 401 : return pindex; 69 : 402 : } 70 : : 71 : 0 : CBlockIndex* CChain::FindEarliestAtLeast(int64_t nTime, int height) const 72 : : { 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 : : } 78 : : 79 : : /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */ 80 : 7205 : 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 : 4838 : int static inline GetSkipHeight(int height) { 84 [ + + ]: 4838 : if (height < 2) 85 : 33 : 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 [ + + ]: 4805 : return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); 91 : 4838 : } 92 : : 93 : 1311 : const CBlockIndex* CBlockIndex::GetAncestor(int height) const 94 : : { 95 [ + + ][ + + ]: 1311 : if (height > nHeight || height < 0) { 96 : 147 : return nullptr; 97 : : } 98 : : 99 : 1164 : const CBlockIndex* pindexWalk = this; 100 : 1164 : int heightWalk = nHeight; 101 [ + + ]: 3483 : while (heightWalk > height) { 102 : 2319 : int heightSkip = GetSkipHeight(heightWalk); 103 : 2319 : int heightSkipPrev = GetSkipHeight(heightWalk - 1); 104 [ + - ][ + + ]: 2610 : if (pindexWalk->pskip != nullptr && 105 [ + + ]: 2319 : (heightSkip == height || 106 [ + + ][ + + ]: 1807 : (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && 107 : 291 : heightSkipPrev >= height)))) { 108 : : // Only follow pskip if pprev->pskip isn't better than pskip->pprev. 109 : 1282 : pindexWalk = pindexWalk->pskip; 110 : 1282 : heightWalk = heightSkip; 111 : 1282 : } else { 112 [ + - ]: 1037 : assert(pindexWalk->pprev); 113 : 1037 : pindexWalk = pindexWalk->pprev; 114 : 1037 : heightWalk--; 115 : : } 116 : : } 117 : 1164 : return pindexWalk; 118 : 1311 : } 119 : : 120 : 801 : CBlockIndex* CBlockIndex::GetAncestor(int height) 121 : : { 122 : 801 : return const_cast<CBlockIndex*>(static_cast<const CBlockIndex*>(this)->GetAncestor(height)); 123 : : } 124 : : 125 : 200 : void CBlockIndex::BuildSkip() 126 : : { 127 [ + - ]: 200 : if (pprev) 128 : 200 : pskip = pprev->GetAncestor(GetSkipHeight(nHeight)); 129 : 200 : } 130 : : 131 : 201 : arith_uint256 GetBlockProof(const CBlockIndex& block) 132 : : { 133 : 201 : arith_uint256 bnTarget; 134 : : bool fNegative; 135 : : bool fOverflow; 136 : 201 : bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); 137 [ + - ][ + - ]: 201 : 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 : 201 : return (~bnTarget / (bnTarget + 1)) + 1; 144 : 201 : } 145 : : 146 : 0 : int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params) 147 : : { 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 : : } 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 : : } 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 : 0 : const CBlockIndex* LastCommonAncestor(const CBlockIndex* pa, const CBlockIndex* pb) { 166 [ # # ]: 0 : if (pa->nHeight > pb->nHeight) { 167 : 0 : pa = pa->GetAncestor(pb->nHeight); 168 [ # # ]: 0 : } else if (pb->nHeight > pa->nHeight) { 169 : 0 : pb = pb->GetAncestor(pa->nHeight); 170 : 0 : } 171 : : 172 [ # # ][ # # ]: 0 : while (pa != pb && pa && pb) { [ # # ] 173 : 0 : pa = pa->pprev; 174 : 0 : pb = pb->pprev; 175 : : } 176 : : 177 : : // Eventually all chain branches meet at the genesis block. 178 [ # # ]: 0 : assert(pa == pb); 179 : 0 : return pa; 180 : : }