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