LCOV - code coverage report
Current view: top level - src - chain.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 49 50 98.0 %
Date: 2015-10-12 22:39:14 Functions: 7 8 87.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2009-2010 Satoshi Nakamoto
       2             : // Copyright (c) 2009-2014 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             : 
       8             : using namespace std;
       9             : 
      10             : /**
      11             :  * CChain implementation
      12             :  */
      13        5731 : void CChain::SetTip(CBlockIndex *pindex) {
      14        5731 :     if (pindex == NULL) {
      15         119 :         vChain.clear();
      16        5731 :         return;
      17             :     }
      18        5612 :     vChain.resize(pindex->nHeight + 1);
      19      249998 :     while (pindex && vChain[pindex->nHeight] != pindex) {
      20      233282 :         vChain[pindex->nHeight] = pindex;
      21      116641 :         pindex = pindex->pprev;
      22             :     }
      23             : }
      24             : 
      25        4939 : CBlockLocator CChain::GetLocator(const CBlockIndex *pindex) const {
      26        4939 :     int nStep = 1;
      27             :     std::vector<uint256> vHave;
      28        4939 :     vHave.reserve(32);
      29             : 
      30        4939 :     if (!pindex)
      31          87 :         pindex = Tip();
      32       44603 :     while (pindex) {
      33       89206 :         vHave.push_back(pindex->GetBlockHash());
      34             :         // Stop when we have added the genesis block.
      35       44603 :         if (pindex->nHeight == 0)
      36             :             break;
      37             :         // Exponentially larger steps back, plus the genesis block.
      38       79328 :         int nHeight = std::max(pindex->nHeight - nStep, 0);
      39       39664 :         if (Contains(pindex)) {
      40             :             // Use O(1) CChain index if possible.
      41       37792 :             pindex = (*this)[nHeight];
      42             :         } else {
      43             :             // Otherwise, use O(log n) skiplist.
      44        1872 :             pindex = pindex->GetAncestor(nHeight);
      45             :         }
      46       79328 :         if (vHave.size() > 10)
      47       15131 :             nStep *= 2;
      48             :     }
      49             : 
      50        9878 :     return CBlockLocator(vHave);
      51             : }
      52             : 
      53        5493 : const CBlockIndex *CChain::FindFork(const CBlockIndex *pindex) const {
      54       10986 :     if (pindex->nHeight > Height())
      55       10968 :         pindex = pindex->GetAncestor(Height());
      56       11020 :     while (pindex && !Contains(pindex))
      57          48 :         pindex = pindex->pprev;
      58        5493 :     return pindex;
      59             : }
      60             : 
      61             : /** Turn the lowest '1' bit in the binary representation of a number into a '0'. */
      62     5300148 : int static inline InvertLowestOne(int n) { return n & (n - 1); }
      63             : 
      64             : /** Compute what height to jump back to with the CBlockIndex::pskip pointer. */
      65             : int static inline GetSkipHeight(int height) {
      66     3537330 :     if (height < 2)
      67             :         return 0;
      68             : 
      69             :     // Determine which height to jump back to. Any number strictly lower than height is acceptable,
      70             :     // but the following expression seems to perform well in simulations (max 110 steps to go back
      71             :     // up to 2**18 blocks).
      72     7066758 :     return (height & 1) ? InvertLowestOne(InvertLowestOne(height - 1)) + 1 : InvertLowestOne(height);
      73             : }
      74             : 
      75      504451 : CBlockIndex* CBlockIndex::GetAncestor(int height)
      76             : {
      77      504451 :     if (height > nHeight || height < 0)
      78             :         return NULL;
      79             : 
      80             :     CBlockIndex* pindexWalk = this;
      81             :     int heightWalk = nHeight;
      82     2033091 :     while (heightWalk > height) {
      83     1535388 :         int heightSkip = GetSkipHeight(heightWalk);
      84     3070776 :         int heightSkipPrev = GetSkipHeight(heightWalk - 1);
      85     1535388 :         if (pindexWalk->pskip != NULL &&
      86     1278228 :             (heightSkip == height ||
      87      582355 :              (heightSkip > height && !(heightSkipPrev < heightSkip - 2 &&
      88      181564 :                                        heightSkipPrev >= height)))) {
      89             :             // Only follow pskip if pprev->pskip isn't better than pskip->pprev.
      90             :             pindexWalk = pindexWalk->pskip;
      91             :             heightWalk = heightSkip;
      92             :         } else {
      93      757648 :             pindexWalk = pindexWalk->pprev;
      94      757648 :             heightWalk--;
      95             :         }
      96             :     }
      97      497703 :     return pindexWalk;
      98             : }
      99             : 
     100           0 : const CBlockIndex* CBlockIndex::GetAncestor(int height) const
     101             : {
     102        7356 :     return const_cast<CBlockIndex*>(this)->GetAncestor(height);
     103             : }
     104             : 
     105      466556 : void CBlockIndex::BuildSkip()
     106             : {
     107      466556 :     if (pprev)
     108      933108 :         pskip = pprev->GetAncestor(GetSkipHeight(nHeight));
     109      466844 : }

Generated by: LCOV version 1.11