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.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. // Limit adjustment step
  48. int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
  49. LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
  50. if (nActualTimespan < params.nPowTargetTimespan/4)
  51. nActualTimespan = params.nPowTargetTimespan/4;
  52. if (nActualTimespan > params.nPowTargetTimespan*4)
  53. nActualTimespan = params.nPowTargetTimespan*4;
  54. // Retarget
  55. const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
  56. arith_uint256 bnNew;
  57. arith_uint256 bnOld;
  58. bnNew.SetCompact(pindexLast->nBits);
  59. bnOld = bnNew;
  60. bnNew *= nActualTimespan;
  61. bnNew /= params.nPowTargetTimespan;
  62. if (bnNew > bnPowLimit)
  63. bnNew = bnPowLimit;
  64. /// debug print
  65. LogPrintf("GetNextWorkRequired RETARGET\n");
  66. LogPrintf("params.nPowTargetTimespan = %d nActualTimespan = %d\n", params.nPowTargetTimespan, nActualTimespan);
  67. LogPrintf("Before: %08x %s\n", pindexLast->nBits, bnOld.ToString());
  68. LogPrintf("After: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
  69. return bnNew.GetCompact();
  70. }
  71. bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
  72. {
  73. bool fNegative;
  74. bool fOverflow;
  75. arith_uint256 bnTarget;
  76. bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
  77. // Check range
  78. if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
  79. return error("CheckProofOfWork(): nBits below minimum work");
  80. // Check proof of work matches claimed amount
  81. if (UintToArith256(hash) > bnTarget)
  82. return error("CheckProofOfWork(): hash doesn't match nBits");
  83. return true;
  84. }
  85. arith_uint256 GetBlockProof(const CBlockIndex& block)
  86. {
  87. arith_uint256 bnTarget;
  88. bool fNegative;
  89. bool fOverflow;
  90. bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
  91. if (fNegative || fOverflow || bnTarget == 0)
  92. return 0;
  93. // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
  94. // as it's too large for a arith_uint256. However, as 2**256 is at least as large
  95. // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
  96. // or ~bnTarget / (nTarget+1) + 1.
  97. return (~bnTarget / (bnTarget + 1)) + 1;
  98. }