Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2017
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.93 KB | None | 0 0
  1. // This is MIDAS (Multi Interval Difficulty Adjustment System), a novel getnextwork algorithm. It responds quickly to
  2. // huge changes in hashing power, is immune to time warp attacks, and regulates the block rate to keep the block height
  3. // close to the block height expected given the nominal block interval and the elapsed time. How close the
  4. // correspondence between block height and wall clock time is, depends on how stable the hashing power has been. Maybe
  5. // Bitcoin can wait 2 weeks between updates but no altcoin can.
  6.  
  7. // It is important that none of these intervals (5, 7, 9, 17) have any common divisor; eliminating the existence of
  8. // harmonics is an important part of eliminating the effectiveness of timewarp attacks.
  9. void avgRecentTimestamps(const CBlockIndex* pindexLast, int64_t *avgOf5, int64_t *avgOf7, int64_t *avgOf9, int64_t *avgOf17)
  10. {
  11. int blockoffset = 0;
  12. int64_t oldblocktime;
  13. int64_t blocktime;
  14.  
  15. *avgOf5 = *avgOf7 = *avgOf9 = *avgOf17 = 0;
  16. if (pindexLast)
  17. blocktime = pindexLast->GetBlockTime();
  18. else blocktime = 0;
  19.  
  20. for (blockoffset = 0; blockoffset < 17; blockoffset++)
  21. {
  22. oldblocktime = blocktime;
  23. if (pindexLast)
  24. {
  25. pindexLast = pindexLast->pprev;
  26. blocktime = pindexLast->GetBlockTime();
  27. }
  28. else
  29. { // genesis block or previous
  30. blocktime -= Params().TargetSpacing();
  31. }
  32. // for each block, add interval.
  33. if (blockoffset < 5) *avgOf5 += (oldblocktime - blocktime);
  34. if (blockoffset < 7) *avgOf7 += (oldblocktime - blocktime);
  35. if (blockoffset < 9) *avgOf9 += (oldblocktime - blocktime);
  36. *avgOf17 += (oldblocktime - blocktime);
  37. }
  38. // now we have the sums of the block intervals. Division gets us the averages.
  39. *avgOf5 /= 5;
  40. *avgOf7 /= 7;
  41. *avgOf9 /= 9;
  42. *avgOf17 /= 17;
  43. }
  44.  
  45. //unsigned int GetNextWorkRequired(const CBlockIndex *pindexLast, const CBlockHeader *pblock)
  46. unsigned int GetNextTargetRequiredV2(const CBlockIndex* pindexLast, bool fProofOfStake)
  47. {
  48. int64_t avgOf5;
  49. int64_t avgOf9;
  50. int64_t avgOf7;
  51. int64_t avgOf17;
  52. int64_t toofast;
  53. int64_t tooslow;
  54. int64_t difficultyfactor = 10000;
  55. int64_t now;
  56. int64_t BlockHeightTime;
  57.  
  58. int64_t nFastInterval = (Params().TargetSpacing() * 9 ) / 10; // seconds per block desired when far behind schedule
  59. int64_t nSlowInterval = (Params().TargetSpacing() * 11) / 10; // seconds per block desired when far ahead of schedule
  60. int64_t nIntervalDesired;
  61.  
  62. uint256 bnTargetLimit = fProofOfStake ? Params().ProofOfStakeLimit() : Params().ProofOfWorkLimit();
  63. unsigned int nTargetLimit = bnTargetLimit.GetCompact();
  64.  
  65. if (pindexLast == NULL)
  66. // Genesis Block
  67. return nTargetLimit;
  68.  
  69. // Regulate block times so as to remain synchronized in the long run with the actual time. The first step is to
  70. // calculate what interval we want to use as our regulatory goal. It depends on how far ahead of (or behind)
  71. // schedule we are. If we're more than an adjustment period ahead or behind, we use the maximum (nSlowInterval) or minimum
  72. // (nFastInterval) values; otherwise we calculate a weighted average somewhere in between them. The closer we are
  73. // to being exactly on schedule the closer our selected interval will be to our nominal interval (TargetSpacing).
  74.  
  75. now = pindexLast->GetBlockTime();
  76. BlockHeightTime = Params().GenesisBlock().nTime + pindexLast->nHeight * Params().TargetSpacing();
  77.  
  78. if (now < BlockHeightTime + Params().TargetTimespan() && now > BlockHeightTime )
  79. // ahead of schedule by less than one interval.
  80. nIntervalDesired = ((Params().TargetTimespan() - (now - BlockHeightTime)) * Params().TargetSpacing() +
  81. (now - BlockHeightTime) * nFastInterval) / Params().TargetSpacing();
  82. else if (now + Params().TargetTimespan() > BlockHeightTime && now < BlockHeightTime)
  83. // behind schedule by less than one interval.
  84. nIntervalDesired = ((Params().TargetTimespan() - (BlockHeightTime - now)) * Params().TargetSpacing() +
  85. (BlockHeightTime - now) * nSlowInterval) / Params().TargetTimespan();
  86.  
  87. // ahead by more than one interval;
  88. else if (now < BlockHeightTime) nIntervalDesired = nSlowInterval;
  89.  
  90. // behind by more than an interval.
  91. else nIntervalDesired = nFastInterval;
  92.  
  93. // find out what average intervals over last 5, 7, 9, and 17 blocks have been.
  94. avgRecentTimestamps(pindexLast, &avgOf5, &avgOf7, &avgOf9, &avgOf17);
  95.  
  96. // check for emergency adjustments. These are to bring the diff up or down FAST when a burst miner or multipool
  97. // jumps on or off. Once they kick in they can adjust difficulty very rapidly, and they can kick in very rapidly
  98. // after massive hash power jumps on or off.
  99.  
  100. // Important note: This is a self-damping adjustment because 8/5 and 5/8 are closer to 1 than 3/2 and 2/3. Do not
  101. // screw with the constants in a way that breaks this relationship. Even though self-damping, it will usually
  102. // overshoot slightly. But normal adjustment will handle damping without getting back to emergency.
  103. toofast = (nIntervalDesired * 2) / 3;
  104. tooslow = (nIntervalDesired * 3) / 2;
  105.  
  106. // both of these check the shortest interval to quickly stop when overshot. Otherwise first is longer and second shorter.
  107. if (avgOf5 < toofast && avgOf9 < toofast && avgOf17 < toofast)
  108. { //emergency adjustment, slow down (longer intervals because shorter blocks)
  109. LogPrint("difficulty", "GetNextWorkRequired EMERGENCY RETARGET\n");
  110. difficultyfactor *= 8;
  111. difficultyfactor /= 5;
  112. }
  113. else if (avgOf5 > tooslow && avgOf7 > tooslow && avgOf9 > tooslow)
  114. { //emergency adjustment, speed up (shorter intervals because longer blocks)
  115. LogPrint("difficulty", "GetNextWorkRequired EMERGENCY RETARGET\n");
  116. difficultyfactor *= 5;
  117. difficultyfactor /= 8;
  118. }
  119.  
  120. // If no emergency adjustment, check for normal adjustment.
  121. else if (((avgOf5 > nIntervalDesired || avgOf7 > nIntervalDesired) && avgOf9 > nIntervalDesired && avgOf17 > nIntervalDesired) ||
  122. ((avgOf5 < nIntervalDesired || avgOf7 < nIntervalDesired) && avgOf9 < nIntervalDesired && avgOf17 < nIntervalDesired))
  123. { // At least 3 averages too high or at least 3 too low, including the two longest. This will be executed 3/16 of
  124. // the time on the basis of random variation, even if the settings are perfect. It regulates one-sixth of the way
  125. // to the calculated point.
  126. LogPrint("difficulty", "GetNextWorkRequired RETARGET\n");
  127. difficultyfactor *= (6 * nIntervalDesired);
  128. difficultyfactor /= (avgOf17 +(5 * nIntervalDesired));
  129. }
  130.  
  131. // limit to doubling or halving. There are no conditions where this will make a difference unless there is an
  132. // unsuspected bug in the above code.
  133. if (difficultyfactor > 20000) difficultyfactor = 20000;
  134. if (difficultyfactor < 5000) difficultyfactor = 5000;
  135.  
  136. uint256 bnNew;
  137. uint256 bnOld;
  138.  
  139. bnOld.SetCompact(pindexLast->nBits);
  140.  
  141. if (difficultyfactor == 10000) // no adjustment.
  142. return(bnOld.GetCompact());
  143.  
  144. bnNew = bnOld / difficultyfactor;
  145. bnNew *= 10000;
  146.  
  147. if (bnNew > Params().ProofOfWorkLimit())
  148. bnNew = Params().ProofOfWorkLimit();
  149.  
  150. LogPrint("difficulty", "Actual time %d, Scheduled time for this block height = %d\n", now, BlockHeightTime );
  151. LogPrint("difficulty", "Nominal block interval = %d, regulating on interval %d to get back to schedule.\n",
  152. Params().TargetSpacing(), nIntervalDesired );
  153. LogPrint("difficulty", "Intervals of last 5/7/9/17 blocks = %d / %d / %d / %d.\n",
  154. avgOf5, avgOf7, avgOf9, avgOf17);
  155. LogPrint("difficulty", "Difficulty Before Adjustment: %08x %s\n", pindexLast->nBits, bnOld.ToString());
  156. LogPrint("difficulty", "Difficulty After Adjustment: %08x %s\n", bnNew.GetCompact(), bnNew.ToString());
  157.  
  158. return bnNew.GetCompact();
  159.  
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement