Example #1
0
        public double?Update(VarDiffContext ctx, double difficulty, double networkDifficulty, bool onSubmission)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));

            lock (ctx)
            {
                // Get Current Time
                double ts = DateTimeOffset.Now.ToUnixTimeMilliseconds() / 1000.0;

                // For the first time, won't change diff.
                if (ctx.LastTs == 0)
                {
                    ctx.LastRtc    = ts;
                    ctx.LastTs     = ts;
                    ctx.TimeBuffer = new CircularDoubleBuffer(bufferSize);
                    return(null);
                }

                var minDiff = options.MinDiff;
                var maxDiff = options.MaxDiff ?? Math.Max(minDiff, networkDifficulty);  // for regtest

                var sinceLast = ts - ctx.LastTs;

                // Always calculate the time until now even there is no share submitted.
                var timeTotal = ctx.TimeBuffer.Sum();
                var timeCount = ctx.TimeBuffer.Size;
                var avg       = (timeTotal + sinceLast) / (timeCount + 1);

                // Once there is a share submitted, store the time into the buffer and update the last time.
                if (onSubmission)
                {
                    ctx.TimeBuffer.PushBack(sinceLast);
                    ctx.LastTs = ts;
                }

                // Check if we need to change the difficulty
                if (ts - ctx.LastRtc < options.RetargetTime || avg >= tMin && avg <= tMax)
                {
                    return(null);
                }

                // Possible New Diff
                var newDiff = difficulty * options.TargetTime / avg;
                if (newDiff < minDiff)
                {
                    newDiff = minDiff;
                }
                if (newDiff > maxDiff)
                {
                    newDiff = maxDiff;
                }

                // RTC if the Diff is changed
                if (newDiff != difficulty)
                {
                    ctx.LastRtc = ts;

                    // Due to change of diff, Buffer needs to be cleared
                    ctx.TimeBuffer = new CircularDoubleBuffer(bufferSize);
                    return(newDiff);
                }
            }

            return(null);
        }
        public double?Update(VarDiffContext ctx, double difficulty, bool isIdleUpdate)
        {
            Contract.RequiresNonNull(ctx, nameof(ctx));

            lock (ctx)
            {
                // Get Current Time
                var ts = DateTimeOffset.Now.ToUnixTimeMilliseconds() / 1000.0;

                // For the first time, won't change diff.
                if (!ctx.LastTs.HasValue)
                {
                    ctx.LastRtc    = ts;
                    ctx.LastTs     = ts;
                    ctx.TimeBuffer = new CircularDoubleBuffer(bufferSize);
                    return(null);
                }

                var minDiff   = options.MinDiff;
                var maxDiff   = options.MaxDiff ?? Math.Max(minDiff, double.MaxValue); // for regtest
                var sinceLast = ts - ctx.LastTs.Value;

                // Always calculate the time until now even there is no share submitted.
                var timeTotal = ctx.TimeBuffer.Sum();
                var timeCount = ctx.TimeBuffer.Size;
                var avg       = (timeTotal + sinceLast) / (timeCount + 1);

                // Once there is a share submitted, store the time into the buffer and update the last time.
                if (!isIdleUpdate)
                {
                    ctx.TimeBuffer.PushBack(sinceLast);
                    ctx.LastTs = ts;
                }

                // Check if we need to change the difficulty
                if (ts - ctx.LastRtc < options.RetargetTime || avg >= tMin && avg <= tMax)
                {
                    return(null);
                }

                // Possible New Diff
                var newDiff = difficulty * options.TargetTime / avg;

                // Max delta
                if (options.MaxDelta.HasValue && options.MaxDelta > 0)
                {
                    var delta = Math.Abs(newDiff - difficulty);

                    if (delta > options.MaxDelta)
                    {
                        if (newDiff > difficulty)
                        {
                            newDiff -= delta - options.MaxDelta.Value;
                        }
                        else if (newDiff < difficulty)
                        {
                            newDiff += delta - options.MaxDelta.Value;
                        }
                    }
                }

                // Clamp to valid range
                if (newDiff < minDiff)
                {
                    newDiff = minDiff;
                }
                if (newDiff > maxDiff)
                {
                    newDiff = maxDiff;
                }

                // RTC if the Diff is changed
                if (newDiff < difficulty || newDiff > difficulty)
                {
                    ctx.LastRtc    = ts;
                    ctx.LastUpdate = clock.Now;

                    // Due to change of diff, Buffer needs to be cleared
                    ctx.TimeBuffer = new CircularDoubleBuffer(bufferSize);

                    return(newDiff);
                }
            }

            return(null);
        }
Example #3
0
 public double?Update(VarDiffContext ctx, double difficulty, double networkDifficulty)
 {
     return(Update(ctx, difficulty, networkDifficulty, false));
 }