You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pow.cpp 4.9KB

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