LCOV - code coverage report
Current view: top level - src - pow.cpp (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 45 52 86.5 %
Date: 2015-10-12 22:39:14 Functions: 7 7 100.0 %
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 "pow.h"
       7             : 
       8             : #include "arith_uint256.h"
       9             : #include "chain.h"
      10             : #include "primitives/block.h"
      11             : #include "uint256.h"
      12             : #include "util.h"
      13             : 
      14        9520 : unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
      15             : {
      16        9520 :     unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
      17             : 
      18             :     // Genesis block
      19        9520 :     if (pindexLast == NULL)
      20             :         return nProofOfWorkLimit;
      21             : 
      22             :     // Only change once per difficulty adjustment interval
      23       19040 :     if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
      24             :     {
      25        9520 :         if (params.fPowAllowMinDifficultyBlocks)
      26             :         {
      27             :             // Special difficulty rule for testnet:
      28             :             // If the new block's timestamp is more than 2* 10 minutes
      29             :             // then allow mining of a min-difficulty block.
      30       28152 :             if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
      31             :                 return nProofOfWorkLimit;
      32             :             else
      33             :             {
      34             :                 // Return the last non-special-min-difficulty-rules-block
      35             :                 const CBlockIndex* pindex = pindexLast;
      36      797814 :                 while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
      37             :                     pindex = pindex->pprev;
      38        9261 :                 return pindex->nBits;
      39             :             }
      40             :         }
      41         136 :         return pindexLast->nBits;
      42             :     }
      43             : 
      44             :     // Go back by what we want to be 14 days worth of blocks
      45           0 :     int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
      46           0 :     assert(nHeightFirst >= 0);
      47           0 :     const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
      48           0 :     assert(pindexFirst);
      49             : 
      50           0 :     return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
      51             : }
      52             : 
      53           4 : unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
      54             : {
      55             :     // Limit adjustment step
      56           8 :     int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
      57           4 :     LogPrintf("  nActualTimespan = %d  before bounds\n", nActualTimespan);
      58           4 :     if (nActualTimespan < params.nPowTargetTimespan/4)
      59           1 :         nActualTimespan = params.nPowTargetTimespan/4;
      60           4 :     if (nActualTimespan > params.nPowTargetTimespan*4)
      61           1 :         nActualTimespan = params.nPowTargetTimespan*4;
      62             : 
      63             :     // Retarget
      64           4 :     const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
      65             :     arith_uint256 bnNew;
      66             :     arith_uint256 bnOld;
      67           4 :     bnNew.SetCompact(pindexLast->nBits);
      68             :     bnOld = bnNew;
      69           4 :     bnNew *= nActualTimespan;
      70           8 :     bnNew /= params.nPowTargetTimespan;
      71             : 
      72           4 :     if (bnNew > bnPowLimit)
      73             :         bnNew = bnPowLimit;
      74             : 
      75             :     /// debug print
      76           4 :     LogPrintf("GetNextWorkRequired RETARGET\n");
      77           4 :     LogPrintf("params.nPowTargetTimespan = %d    nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
      78           8 :     LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
      79           8 :     LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());
      80             : 
      81           4 :     return bnNew.GetCompact();
      82             : }
      83             : 
      84       61453 : bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
      85             : {
      86             :     bool fNegative;
      87             :     bool fOverflow;
      88             :     arith_uint256 bnTarget;
      89             : 
      90       61453 :     bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
      91             : 
      92             :     // Check range
      93      184359 :     if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
      94           0 :         return error("CheckProofOfWork(): nBits below minimum work");
      95             : 
      96             :     // Check proof of work matches claimed amount
      97      122906 :     if (UintToArith256(hash) > bnTarget)
      98        1344 :         return error("CheckProofOfWork(): hash doesn't match nBits");
      99             : 
     100             :     return true;
     101             : }
     102             : 
     103       27758 : arith_uint256 GetBlockProof(const CBlockIndex& block)
     104             : {
     105             :     arith_uint256 bnTarget;
     106             :     bool fNegative;
     107             :     bool fOverflow;
     108       27758 :     bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
     109       55516 :     if (fNegative || fOverflow || bnTarget == 0)
     110             :         return 0;
     111             :     // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
     112             :     // as it's too large for a arith_uint256. However, as 2**256 is at least as large
     113             :     // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
     114             :     // or ~bnTarget / (nTarget+1) + 1.
     115       55516 :     return (~bnTarget / (bnTarget + 1)) + 1;
     116             : }
     117             : 
     118        1000 : int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& from, const CBlockIndex& tip, const Consensus::Params& params)
     119             : {
     120             :     arith_uint256 r;
     121        1000 :     int sign = 1;
     122        2000 :     if (to.nChainWork > from.nChainWork) {
     123         976 :         r = to.nChainWork - from.nChainWork;
     124             :     } else {
     125        1024 :         r = from.nChainWork - to.nChainWork;
     126         512 :         sign = -1;
     127             :     }
     128        3000 :     r = r * arith_uint256(params.nPowTargetSpacing) / GetBlockProof(tip);
     129        1000 :     if (r.bits() > 63) {
     130           0 :         return sign * std::numeric_limits<int64_t>::max();
     131             :     }
     132        2000 :     return sign * r.GetLow64();
     133         288 : }

Generated by: LCOV version 1.11