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 0 : std::vector<uint256> LocatorEntries(const CBlockIndex* index) 32 : { 33 0 : int step = 1; 34 0 : std::vector<uint256> have; 35 0 : if (index == nullptr) return have; 36 : 37 0 : have.reserve(32); 38 0 : while (index) { 39 0 : have.emplace_back(index->GetBlockHash()); 40 0 : if (index->nHeight == 0) break; 41 : // Exponentially larger steps back, plus the genesis block. 42 0 : int height = std::max(index->nHeight - step, 0); 43 : // Use skiplist. 44 0 : index = index->GetAncestor(height); 45 0 : if (have.size() > 10) step *= 2; 46 : } 47 0 : return have; 48 0 : } 49 : 50 0 : CBlockLocator GetLocator(const CBlockIndex* index) 51 : { 52 0 : 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 2 : 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 398177 : 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 265474 : int static inline GetSkipHeight(int height) { 84 265474 : if (height < 2) 85 21 : 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 265453 : return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height); 91 265474 : } 92 : 93 19250 : const CBlockIndex* CBlockIndex::GetAncestor(int height) const 94 : { 95 19250 : if (height > nHeight || height < 0) { 96 147 : return nullptr; 97 : } 98 : 99 19103 : const CBlockIndex* pindexWalk = this; 100 19103 : int heightWalk = nHeight; 101 151740 : while (heightWalk > height) { 102 132637 : int heightSkip = GetSkipHeight(heightWalk); 103 132637 : int heightSkipPrev = GetSkipHeight(heightWalk - 1); 104 133721 : if (pindexWalk->pskip != nullptr && 105 130865 : (heightSkip == height || 106 119286 : (heightSkip > height && !(heightSkipPrev < heightSkip - 2 && 107 1084 : heightSkipPrev >= height)))) { 108 : // Only follow pskip if pprev->pskip isn't better than pskip->pprev. 109 83672 : pindexWalk = pindexWalk->pskip; 110 83672 : heightWalk = heightSkip; 111 83672 : } else { 112 48965 : assert(pindexWalk->pprev); 113 48965 : pindexWalk = pindexWalk->pprev; 114 48965 : heightWalk--; 115 : } 116 : } 117 19103 : return pindexWalk; 118 19250 : } 119 : 120 12217 : CBlockIndex* CBlockIndex::GetAncestor(int height) 121 : { 122 12217 : 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 : }