SHARE
TWEET

Untitled

a guest Oct 22nd, 2017 61 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
Top