Example #1
0
        private async Task MinerSpeedsLoop(CancellationTokenSource ct)
        {
            Logger.Info("EXCAVATOR-MinerSpeedsLoop", $"STARTING");
            try
            {
                var         workers      = string.Join(",", _miningPairs.Select((_, i) => $@"""{i}"""));
                var         workersReset = @"{""id"":1,""method"":""workers.reset"",""params"":[__WORKERS__]}".Replace("__WORKERS__", workers);
                Func <bool> isActive     = () => !ct.Token.IsCancellationRequested;
                while (isActive())
                {
                    try
                    {
                        _ = await ApiDataHelpers.GetApiDataAsync(_apiPort, workersReset + "\r\n", _logGroup);

                        if (isActive())
                        {
                            await ExcavatorTaskHelpers.TryDelay(TimeSpan.FromSeconds(30), ct.Token);
                        }
                        // get speeds
                        var ad = await GetMinerStatsDataAsyncPrivate();

                        lock (_lock2)
                        {
                            _lastApiData = ad;
                        }
                        // speed print and reset
                        _ = await ApiDataHelpers.GetApiDataAsync(_apiPort, @"{""id"":1,""method"":""worker.print.efficiencies"",""params"":[]}" + "\r\n", _logGroup);
                    }
                    catch (TaskCanceledException e)
                    {
                        break;
                    }
                    catch (Exception e)
                    {
                    }
                }
                Logger.Info("EXCAVATOR-MinerSpeedsLoop", $"EXIT WHILE");
            }
            catch (TaskCanceledException e)
            {
            }
            catch (Exception ex)
            {
                Logger.Error("EXCAVATOR-API_LOOP", $"error {ex}");
            }
            finally
            {
                ct.Dispose();
            }
        }
Example #2
0
        private async Task <string> ExecuteCommand(string command)
        {
            try
            {
                var response = await ApiDataHelpers.GetApiDataAsync(_apiPort, command + "\r\n", _logGroup);

                return(response);
            }
            catch (Exception e)
            {
                Logger.Error(_logGroup, $"Error occured with command '{command}' error: {e.Message}");
            }
            return(null);
        }
Example #3
0
        public async override Task <ApiData> GetMinerStatsDataAsync()
        {
            var summaryApiResult = await ApiDataHelpers.GetApiDataAsync(_apiPort, ApiDataHelpers.GetHttpRequestNhmAgentString("summary"), _logGroup);

            double totalSpeed         = 0;
            int    totalPower         = 0;
            var    perDeviceSpeedInfo = new Dictionary <string, IReadOnlyList <AlgorithmTypeSpeedPair> >();
            var    perDevicePowerInfo = new Dictionary <string, int>();

            if (!string.IsNullOrEmpty(summaryApiResult))
            {
                // TODO return empty
                try
                {
                    var summaryOptvals = summaryApiResult.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var optvalPairs in summaryOptvals)
                    {
                        var pair = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                        if (pair.Length != 2)
                        {
                            continue;
                        }
                        if (pair[0] == "KHS")
                        {
                            var currentSpeed = double.Parse(pair[1], CultureInfo.InvariantCulture) * 1000; // HPS
                            totalSpeed += currentSpeed;
                            perDeviceSpeedInfo.Add(_miningPairs.FirstOrDefault()?.Device.UUID, new List <AlgorithmTypeSpeedPair>()
                            {
                                new AlgorithmTypeSpeedPair(_algorithmType, currentSpeed * (1 - DevFee * 0.01))
                            });
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}");
                }
            }
            var ad = new ApiData();

            ad.AlgorithmSpeedsTotal = new List <AlgorithmTypeSpeedPair> {
                new AlgorithmTypeSpeedPair(_algorithmType, totalSpeed)
            };
            ad.AlgorithmSpeedsPerDevice = perDeviceSpeedInfo;
            ad.PowerUsageTotal          = totalPower;
            ad.PowerUsagePerDevice      = perDevicePowerInfo;

            return(ad);
        }
Example #4
0
        public async override Task <ApiData> GetMinerStatsDataAsync()
        {
            var summaryApiResult = await ApiDataHelpers.GetApiDataAsync(_apiPort, ApiDataHelpers.GetHttpRequestNhmAgentString("summary"), _logGroup);

            double totalSpeed = 0;
            int    totalPower = 0;

            if (!string.IsNullOrEmpty(summaryApiResult))
            {
                // TODO return empty
                try
                {
                    var summaryOptvals = summaryApiResult.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    foreach (var optvalPairs in summaryOptvals)
                    {
                        var pair = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                        if (pair.Length != 2)
                        {
                            continue;
                        }
                        if (pair[0] == "KHS")
                        {
                            totalSpeed = double.Parse(pair[1], CultureInfo.InvariantCulture) * 1000; // HPS
                        }
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}");
                }
            }
            var ad = new ApiData();

            ad.AlgorithmSpeedsTotal = new List <AlgorithmTypeSpeedPair> {
                new AlgorithmTypeSpeedPair(_algorithmType, totalSpeed)
            };
            ad.PowerUsageTotal = totalPower;
            // cpuMiner is single device so no need for API

            return(ad);
        }
Example #5
0
        public override async Task <ApiData> GetMinerStatsDataAsync()
        {
            var ad = new ApiData();

            try
            {
                const string speeds   = @"{""id"":123456789,""method"":""worker.list"",""params"":[]}" + "\r\n";
                var          response = await ApiDataHelpers.GetApiDataAsync(_apiPort, speeds, _logGroup);

                ad.ApiResponse = response;
                var summary            = JsonConvert.DeserializeObject <JsonApiResponse>(response);
                var gpus               = _miningPairs.Select(pair => pair.Device.UUID);
                var perDeviceSpeedInfo = new Dictionary <string, IReadOnlyList <(AlgorithmType type, double speed)> >();
                var perDevicePowerInfo = new Dictionary <string, int>();
                var totalSpeed         = 0d;
                //var totalSpeed2 = 0d;
                //var totalPowerUsage = 0;
                foreach (var gpu in gpus)
                {
                    var speed = summary.workers.Where(w => w.device_uuid == gpu).SelectMany(w => w.algorithms.Select(a => a.speed)).Sum();
                    totalSpeed += speed;
                    perDeviceSpeedInfo.Add(gpu, new List <(AlgorithmType type, double speed)>()
                    {
                        (_algorithmType, speed)
                    });
                }
                ad.PowerUsageTotal          = 0;
                ad.AlgorithmSpeedsPerDevice = perDeviceSpeedInfo;
                ad.PowerUsagePerDevice      = perDevicePowerInfo;
                Logger.Info("EXCAVATOR", response);
                await Task.CompletedTask;
            }
            catch (Exception e)
            {
                Logger.Error("EXCAVATOR-API_ERR", e.ToString());
            }
            return(ad);
        }
        public static Task <string> GetApiDataThreads(int port, string logGroup)
        {
            var dataToSend = ApiDataHelpers.GetHttpRequestNhmAgentString("threads");

            return(ApiDataHelpers.GetApiDataAsync(port, dataToSend, logGroup));
        }
Example #7
0
        public async override Task <ApiData> GetMinerStatsDataAsync()
        {
            var api = new ApiData();
            var perDeviceSpeedInfo = new Dictionary <string, IReadOnlyList <AlgorithmTypeSpeedPair> >();
            var perDevicePowerInfo = new Dictionary <string, int>();
            var totalSpeed         = 0d;
            var totalPowerUsage    = 0;

            try
            {
                var result = await ApiDataHelpers.GetApiDataAsync(_apiPort, "summary", _logGroup);

                if (result == "")
                {
                    return(api);
                }

                //total speed
                if (!string.IsNullOrEmpty(result))
                {
                    try
                    {
                        var summaryOptvals = result.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        foreach (var optvalPairs in summaryOptvals)
                        {
                            var pair = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                            if (pair.Length != 2)
                            {
                                continue;
                            }
                            if (pair[0] == "KHS")
                            {
                                totalSpeed = double.Parse(pair[1], CultureInfo.InvariantCulture) * 1000; // HPS
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}");
                    }
                }

                var threadsApiResult = await ApiDataHelpers.GetApiDataAsync(_apiPort, "threads", _logGroup);

                if (!string.IsNullOrEmpty(threadsApiResult))
                {
                    try
                    {
                        var gpus       = threadsApiResult.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);
                        var apiDevices = new List <IdPowerHash>();

                        foreach (var gpu in gpus)
                        {
                            var gpuOptvalPairs = gpu.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                            var gpuData        = new IdPowerHash();
                            foreach (var optvalPairs in gpuOptvalPairs)
                            {
                                var optval = optvalPairs.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                                if (optval.Length != 2)
                                {
                                    continue;
                                }
                                if (optval[0] == "GPU")
                                {
                                    gpuData.id = int.Parse(optval[1], CultureInfo.InvariantCulture);
                                }
                                if (optval[0] == "POWER")
                                {
                                    gpuData.power = int.Parse(optval[1], CultureInfo.InvariantCulture);
                                }
                                if (optval[0] == "KHS")
                                {
                                    gpuData.speed = double.Parse(optval[1], CultureInfo.InvariantCulture) * 1000; // HPS
                                }
                            }
                            apiDevices.Add(gpuData);
                        }

                        foreach (var miningPair in _miningPairs)
                        {
                            var deviceUUID = miningPair.Device.UUID;
                            var deviceID   = miningPair.Device.ID;

                            var apiDevice = apiDevices.Find(apiDev => apiDev.id == deviceID);
                            if (apiDevice.Equals(default(IdPowerHash)))
                            {
                                continue;
                            }
                            perDeviceSpeedInfo.Add(deviceUUID, new List <AlgorithmTypeSpeedPair>()
                            {
                                new AlgorithmTypeSpeedPair(_algorithmType, apiDevice.speed * (1 - DevFee * 0.01))
                            });
                            perDevicePowerInfo.Add(deviceUUID, apiDevice.power);
                            totalPowerUsage += apiDevice.power;
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}");
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Error(_logGroup, $"Error occured while getting API stats: {e.Message}");
            }

            api.AlgorithmSpeedsTotal = new List <AlgorithmTypeSpeedPair> {
                new AlgorithmTypeSpeedPair(_algorithmType, totalSpeed * (1 - DevFee * 0.01))
            };
            api.PowerUsageTotal          = totalPowerUsage;
            api.AlgorithmSpeedsPerDevice = perDeviceSpeedInfo;
            api.PowerUsagePerDevice      = perDevicePowerInfo;

            return(api);
        }
Example #8
0
        public override async Task <BenchmarkResult> StartBenchmark(CancellationToken stop, BenchmarkPerformanceType benchmarkType = BenchmarkPerformanceType.Standard)
        {
            using (var tickCancelSource = new CancellationTokenSource())
            {
                var workers      = string.Join(",", _miningPairs.Select((_, i) => $@"""{i}"""));
                var workersReset = @"{""id"":1,""method"":"" workers.reset"",""params"":[__WORKERS__]}".Replace("__WORKERS__", workers);

                // determine benchmark time
                // settup times
                var benchmarkTime = MinerBenchmarkTimeSettings.ParseBenchmarkTime(new List <int> {
                    20, 40, 60
                }, MinerBenchmarkTimeSettings, _miningPairs, benchmarkType);                                                                                              // in seconds
                var maxTicks = MinerBenchmarkTimeSettings.ParseBenchmarkTicks(new List <int> {
                    1, 3, 9
                }, MinerBenchmarkTimeSettings, _miningPairs, benchmarkType);
                var maxTicksEnabled = MinerBenchmarkTimeSettings.MaxTicksEnabled;

                //// use demo user and disable the watchdog
                var commandLine = MiningCreateCommandLine();
                var(binPath, binCwd) = GetBinAndCwdPaths();
                Logger.Info(_logGroup, $"Benchmarking started with command: {commandLine}");
                Logger.Info(_logGroup, $"Benchmarking settings: time={benchmarkTime} ticks={maxTicks} ticksEnabled={maxTicksEnabled}");
                var bp = new BenchmarkProcess(binPath, binCwd, commandLine, GetEnvironmentVariables());
                // disable line readings and read speeds from API
                bp.CheckData = null;

                var benchmarkTimeout = TimeSpan.FromSeconds(benchmarkTime + 5);
                var benchmarkWait    = TimeSpan.FromMilliseconds(500);
                var t = MinerToolkit.WaitBenchmarkResult(bp, benchmarkTimeout, benchmarkWait, stop, tickCancelSource.Token);


                var stoppedAfterTicks = false;
                var validTicks        = 0;
                var ticks             = benchmarkTime / 10; // on each 10 seconds tick
                var result            = new BenchmarkResult();
                var benchmarkApiData  = new List <ApiData>();
                for (var tick = 0; tick < ticks; tick++)
                {
                    if (t.IsCompleted || t.IsCanceled || stop.IsCancellationRequested)
                    {
                        break;
                    }
                    _ = await ApiDataHelpers.GetApiDataAsync(_apiPort, workersReset + "\r\n", _logGroup);

                    await ExcavatorTaskHelpers.TryDelay(TimeSpan.FromSeconds(10), stop);

                    if (t.IsCompleted || t.IsCanceled || stop.IsCancellationRequested)
                    {
                        break;
                    }

                    // get speeds
                    var ad = await GetMinerStatsDataAsyncPrivate();

                    var adTotal     = ad.AlgorithmSpeedsTotal();
                    var isTickValid = adTotal.Count > 0 && adTotal.All(pair => pair.speed > 0);
                    benchmarkApiData.Add(ad);
                    if (isTickValid)
                    {
                        ++validTicks;
                    }
                    if (maxTicksEnabled && validTicks >= maxTicks)
                    {
                        stoppedAfterTicks = true;
                        break;
                    }
                }
                // await benchmark task
                if (stoppedAfterTicks)
                {
                    try
                    {
                        tickCancelSource.Cancel();
                    }
                    catch
                    { }
                }
                await t;
                if (stop.IsCancellationRequested)
                {
                    return(t.Result);
                }

                // calc speeds
                // TODO calc std deviaton to reduce invalid benches
                try
                {
                    var nonZeroSpeeds = benchmarkApiData.Where(ad => ad.AlgorithmSpeedsTotal().Count > 0 && ad.AlgorithmSpeedsTotal().All(pair => pair.speed > 0))
                                        .Select(ad => (ad, ad.AlgorithmSpeedsTotal().Count)).ToList();
                    var speedsFromTotals = new List <(AlgorithmType type, double speed)>();
                    if (nonZeroSpeeds.Count > 0)
                    {
                        var maxAlgoPiarsCount = nonZeroSpeeds.Select(adCount => adCount.Count).Max();
                        var sameCountApiDatas = nonZeroSpeeds.Where(adCount => adCount.Count == maxAlgoPiarsCount).Select(adCount => adCount.ad).ToList();
                        var firstPair         = sameCountApiDatas.FirstOrDefault();
                        var speedSums         = firstPair.AlgorithmSpeedsTotal().Select(pair => new KeyValuePair <AlgorithmType, double>(pair.type, 0.0)).ToDictionary(x => x.Key, x => x.Value);
                        // sum
                        foreach (var ad in sameCountApiDatas)
                        {
                            foreach (var pair in ad.AlgorithmSpeedsTotal())
                            {
                                speedSums[pair.type] += pair.speed;
                            }
                        }
                        // average
                        foreach (var algoId in speedSums.Keys.ToArray())
                        {
                            speedSums[algoId] /= sameCountApiDatas.Count;
                        }
                        result = new BenchmarkResult
                        {
                            AlgorithmTypeSpeeds = firstPair.AlgorithmSpeedsTotal().Select(pair => (pair.type, speedSums[pair.type])).ToList(),
                            Success             = true
                        };
                    }
                }
                catch (Exception e)
                {
                    Logger.Warn(_logGroup, $"benchmarking AlgorithmSpeedsTotal error {e.Message}");
                }

                // return API result
                return(result);
            }
        }