Example #1
0
    public static double?IdleUpdate(WorkerContextBase context, VarDiffConfig options, IMasterClock clock)
    {
        var ctx        = context.VarDiff;
        var difficulty = context.Difficulty;

        // abort if a regular update is just happening
        if (!Monitor.TryEnter(ctx))
        {
            return(null);
        }

        try
        {
            var    now = clock.Now;
            var    ts  = now.ToUnixSeconds();
            double timeDelta;

            if (ctx.LastTs.HasValue)
            {
                timeDelta = ts - ctx.LastTs.Value;
            }
            else
            {
                timeDelta = ts - ctx.Created.ToUnixSeconds();
            }

            timeDelta += SafetyMargin;

            // we only get involved if there was never an update or the last update happened longer than retargetTime ago
            if (timeDelta < options.RetargetTime)
            {
                return(null);
            }

            // update the last time
            ctx.LastTs = ts;

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

            // Always calculate the time until now even there is no share submitted.
            var timeTotal = (ctx.TimeBuffer?.Sum() ?? 0) + (timeDelta - SafetyMargin);
            var avg       = timeTotal / ((ctx.TimeBuffer?.Size ?? 0) + 1);

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

            if (TryApplyNewDiff(ref newDiff, difficulty, minDiff, maxDiff, ts, ctx, options, clock))
            {
                return(newDiff);
            }
        }

        finally
        {
            Monitor.Exit(ctx);
        }

        return(null);
    }
        public VarDiffManager(VarDiffConfig varDiffOptions)
        {
            options = varDiffOptions;

            var variance = varDiffOptions.TargetTime * (varDiffOptions.VariancePercent / 100.0);

            tMin    = varDiffOptions.TargetTime - variance;
            tMax    = varDiffOptions.TargetTime + variance;
            maxJump = varDiffOptions.MaxDelta ?? 10000;
        }
        public VarDiffManager(VarDiffConfig varDiffOptions, IMasterClock clock)
        {
            options    = varDiffOptions;
            this.clock = clock;
            bufferSize = 10;
            var variance = varDiffOptions.TargetTime * (varDiffOptions.VariancePercent / 100.0);

            tMin = varDiffOptions.TargetTime - variance;
            tMax = varDiffOptions.TargetTime + variance;
        }
Example #4
0
        public VarDiffManager(VarDiffConfig varDiffOptions, IMasterClock clock)
        {
            options    = varDiffOptions;
            this.clock = clock;

            var variance = varDiffOptions.TargetTime * (varDiffOptions.VariancePercent / 100.0);

            tMin    = varDiffOptions.TargetTime - variance;
            tMax    = varDiffOptions.TargetTime + variance;
            maxJump = varDiffOptions.MaxDelta ?? 10000;
        }
        public void Init(PoolConfig poolConfig, double difficulty, VarDiffConfig varDiffConfig, IMasterClock clock)
        {
            Difficulty   = difficulty;
            LastActivity = clock.Now;
            Stats        = new ShareStats();

            if (varDiffConfig != null)
            {
                VarDiff = new VarDiffContext();
            }
        }
Example #6
0
        public VarDiffManager(VarDiffConfig varDiffOptions)
        {
            options = varDiffOptions;

            var variance = varDiffOptions.TargetTime * (varDiffOptions.VariancePercent / 100.0);

            /* We need to decided the size of buffer to calculate average. */
            bufferSize = 10; // Last 10 shares is always enough

            tMin = varDiffOptions.TargetTime - variance;
            tMax = varDiffOptions.TargetTime + variance;
        }
Example #7
0
        public void Init(PoolConfig poolConfig, double difficulty, VarDiffConfig varDiffConfig)
        {
            Difficulty   = difficulty;
            LastActivity = DateTime.UtcNow;

            if (poolConfig.Banning != null)
            {
                Stats = new BanningStats();
            }

            if (varDiffConfig != null)
            {
                VarDiff = new VarDiffContext();
            }
        }
Example #8
0
    /// <summary>
    /// Assumes to be called with lock held
    /// </summary>
    private static bool TryApplyNewDiff(ref double newDiff, double oldDiff, double minDiff, double maxDiff, double ts,
                                        VarDiffContext ctx, VarDiffConfig options, IMasterClock clock)
    {
        // Max delta
        if (options.MaxDelta is > 0)
        {
            var delta = Math.Abs(newDiff - oldDiff);

            if (delta > options.MaxDelta)
            {
                if (newDiff > oldDiff)
                {
                    newDiff -= delta - options.MaxDelta.Value;
                }
                else if (newDiff < oldDiff)
                {
                    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 < oldDiff) && !(newDiff > oldDiff))
        {
            return(false);
        }

        ctx.LastRetarget = ts;
        ctx.LastUpdate   = clock.Now;

        // Due to change of diff, Buffer needs to be cleared
        if (ctx.TimeBuffer != null)
        {
            ctx.TimeBuffer = new CircularBuffer <double>(BufferSize);
        }

        return(true);
    }
Example #9
0
    private const double SafetyMargin = 1;  // ensure we don't miss a cycle due a sub-second fraction delta;

    public static double?Update(WorkerContextBase context, VarDiffConfig options, IMasterClock clock)
    {
        var ctx        = context.VarDiff;
        var difficulty = context.Difficulty;
        var now        = clock.Now;
        var ts         = now.ToUnixSeconds();

        try
        {
            Monitor.Enter(ctx);

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

                // make sure buffer exists as this point
                ctx.TimeBuffer ??= new CircularBuffer <double>(BufferSize);

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

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

                // Check if we need to change the difficulty
                var variance = options.TargetTime * (options.VariancePercent / 100.0);
                var tMin     = options.TargetTime - variance;
                var tMax     = options.TargetTime + variance;

                if (ts - ctx.LastRetarget < options.RetargetTime || avg >= tMin && avg <= tMax)
                {
                    return(null);
                }

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

                if (TryApplyNewDiff(ref newDiff, difficulty, minDiff, maxDiff, ts, ctx, options, clock))
                {
                    return(newDiff);
                }
            }

            else
            {
                // init
                ctx.LastRetarget = ts;
                ctx.LastTs       = ts;
            }
        }

        finally
        {
            Monitor.Exit(ctx);
        }

        return(null);
    }