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 3.2KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2016 The Starwels 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. unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock, const Consensus::Params& params)
  11. {
  12. assert(pindexLast != nullptr);
  13. unsigned int nProofOfWorkLimit = UintToArith256(params.powLimit).GetCompact();
  14. // Only change once per difficulty adjustment interval
  15. if ((pindexLast->nHeight+1) % params.DifficultyAdjustmentInterval() != 0)
  16. {
  17. if (params.fPowAllowMinDifficultyBlocks)
  18. {
  19. // Special difficulty rule for ai:
  20. // If the new block's timestamp is more than 2* 10 minutes
  21. // then allow mining of a min-difficulty block.
  22. if (pblock->GetBlockTime() > pindexLast->GetBlockTime() + params.nPowTargetSpacing*2)
  23. return nProofOfWorkLimit;
  24. else
  25. {
  26. // Return the last non-special-min-difficulty-rules-block
  27. const CBlockIndex* pindex = pindexLast;
  28. while (pindex->pprev && pindex->nHeight % params.DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
  29. pindex = pindex->pprev;
  30. return pindex->nBits;
  31. }
  32. }
  33. return pindexLast->nBits;
  34. }
  35. // Go back by what we want to be 14 days worth of blocks
  36. int nHeightFirst = pindexLast->nHeight - (params.DifficultyAdjustmentInterval()-1);
  37. assert(nHeightFirst >= 0);
  38. const CBlockIndex* pindexFirst = pindexLast->GetAncestor(nHeightFirst);
  39. assert(pindexFirst);
  40. return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime(), params);
  41. }
  42. unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
  43. {
  44. if (params.fPowNoRetargeting)
  45. return pindexLast->nBits;
  46. // Limit adjustment step
  47. int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
  48. if (nActualTimespan < params.nPowTargetTimespan/4)
  49. nActualTimespan = params.nPowTargetTimespan/4;
  50. if (nActualTimespan > params.nPowTargetTimespan*4)
  51. nActualTimespan = params.nPowTargetTimespan*4;
  52. // Retarget
  53. const arith_uint256 bnPowLimit = UintToArith256(params.powLimit);
  54. arith_uint256 bnNew;
  55. bnNew.SetCompact(pindexLast->nBits);
  56. bnNew *= nActualTimespan;
  57. bnNew /= params.nPowTargetTimespan;
  58. if (bnNew > bnPowLimit)
  59. bnNew = bnPowLimit;
  60. return bnNew.GetCompact();
  61. }
  62. bool CheckProofOfWork(uint256 hash, unsigned int nBits, const Consensus::Params& params)
  63. {
  64. bool fNegative;
  65. bool fOverflow;
  66. arith_uint256 bnTarget;
  67. bnTarget.SetCompact(nBits, &fNegative, &fOverflow);
  68. // Check range
  69. if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(params.powLimit))
  70. return false;
  71. // Check proof of work matches claimed amount
  72. if (UintToArith256(hash) > bnTarget)
  73. return false;
  74. return true;
  75. }