Пример #1
0
        // TODO copy pasted crap from NiceHashStats
        #region NonRpcMessages
        #region SMA
        private static void SetAlgorithmRates(JArray data)
        {
            try
            {
                var payingDict = new Dictionary <AlgorithmType, double>();
                if (data != null)
                {
                    foreach (var algo in data)
                    {
                        var algoKey = (AlgorithmType)algo[0].Value <int>();
                        payingDict[algoKey] = algo[1].Value <double>();
                    }
                }

                NHSmaData.UpdateSmaPaying(payingDict);
                // TODO new check crap
                foreach (var dev in AvailableDevices.Devices)
                {
                    dev.UpdateEstimatePaying(payingDict);
                }
            }
            catch (Exception e)
            {
                NHLog.Error("NHWebSocket", $"SetAlgorithmRates error: {e.Message}");
            }
        }
 public void StartConnectionold()
 {
     NHSmaData.InitializeIfNeeded();
     _connectionAttempted = true;
     try
     {
         if (_webSocket == null)
         {
             _webSocket = new WebSocket(Links.NhmSocketAddress_old, true);
         }
         else
         {
             _webSocket.Close();
         }
         _webSocket.OnOpen           += ConnectCallback;
         _webSocket.OnMessage        += ReceiveCallback;
         _webSocket.OnError          += ErrorCallback;
         _webSocket.OnClose          += CloseCallback;
         _webSocket.Log.Level         = LogLevel.Debug;
         _webSocket.Log.Output        = (data, s) => Helpers.ConsolePrint("SOCKET_OLD", data.ToString());
         _webSocket.EnableRedirection = true;
         _webSocket.Connect();
         _connectionEstablished = true;
     }
     catch (Exception e)
     {
         Helpers.ConsolePrint("SOCKET_OLD", e.ToString());
     }
 }
Пример #3
0
        static public async Task Start(string address, CancellationToken token)
        {
            var random = new Random();

            _address = address;
            NHLog.Info("NHWebSocket-WD", "Starting nhmws watchdog");
            NHSmaData.InitializeIfNeeded();
            // TODO use this or just use the application exit source
            while (!token.IsCancellationRequested)
            {
                try
                {
                    await NewConnection(token);
                }
                catch (Exception e)
                {
                    NHLog.Error("NHWebSocket-WD", $"Error occured: {e.Message}");
                }
                // if we didn't initialize the restart delay reconnect
                if (!_isNhmwsRestart && !token.IsCancellationRequested)
                {
                    // delays re-connect 10 to 30 seconds
                    var delaySeconds = 10 + random.Next(0, 20);
                    NHLog.Info("NHWebSocket-WD", $"Attempting reconnect in {delaySeconds} seconds");
                    await Task.Delay(delaySeconds * 1000, token);
                }
                else if (_isNhmwsRestart && !token.IsCancellationRequested)
                {
                    NHLog.Info("NHWebSocket-WD", $"Restarting nhmws SESSION");
                }
            }
            NHLog.Info("NHWebSocket-WD", "Ending nhmws watchdog");
        }
Пример #4
0
        public static string GetLocationUrl(AlgorithmType algorithmType, string miningLocation, NhmConectionType conectionType)
        {
            if (!NHSmaData.TryGetSma(algorithmType, out var sma))
            {
                return("");
            }

            var name    = sma.Name;
            var nPort   = sma.Port;
            var sslPort = 30000 + nPort;

            var prefix = "";
            var port   = nPort;

            switch (conectionType)
            {
            case NhmConectionType.LOCKED:
                return(miningLocation);

            case NhmConectionType.STRATUM_TCP:
                prefix = "stratum+tcp://";
                break;

            case NhmConectionType.STRATUM_SSL:
                prefix = "stratum+ssl://";
                port   = sslPort;
                break;
            }

            return(prefix
                   + name
                   + "." + miningLocation
                   + ".nicehash.com:"
                   + port);
        }
Пример #5
0
        protected override void BenchmarkThreadRoutineStartSettup()
        {
            AlgorithmType nhDataIndex = BenchmarkAlgorithm.NiceHashID;

            if (!NHSmaData.HasData)
            {
                Helpers.ConsolePrint("BENCHMARK", "Skipping mkxminer benchmark because there is no internet " +
                                     "connection. mkxminer needs internet connection to do benchmarking.");

                throw new Exception("No internet connection");
            }

            NHSmaData.TryGetPaying(nhDataIndex, out var paying);
            if (paying == 0)
            {
                Helpers.ConsolePrint("BENCHMARK", "Skipping mkxminer benchmark because there is no work on Nicehash.com " +
                                     "[algo: " + BenchmarkAlgorithm.AlgorithmName + "(" + nhDataIndex + ")]");

                throw new Exception("No work can be used for benchmarking");
            }
            _benchmarkTimer.Reset();
            _benchmarkTimer.Start();
            // call base, read only outpus
            //BenchmarkHandle.BeginOutputReadLine();
        }
Пример #6
0
        public async Task MinerStatsCheck()
        {
            var currentProfit = 0.0d;

            _mainFormRatesComunication.ClearRates(_runningGroupMiners.Count);
            var checks = new List <GroupMiner>(_runningGroupMiners.Values);

            try
            {
                foreach (var groupMiners in checks)
                {
                    var m = groupMiners.Miner;

                    // skip if not running or if await already in progress
                    if (!m.IsRunning || m.IsUpdatingApi)
                    {
                        continue;
                    }

                    m.IsUpdatingApi = true;
                    var ad = await m.GetSummaryAsync();

                    m.IsUpdatingApi = false;
                    if (ad == null)
                    {
                        Helpers.ConsolePrint(m.MinerTag(), "GetSummary returned null..");
                    }

                    // set rates
                    if (ad != null && NHSmaData.TryGetPaying(ad.AlgorithmID, out var paying))
                    {
                        groupMiners.CurrentRate = paying * ad.Speed * 0.000000001;
                        if (NHSmaData.TryGetPaying(ad.SecondaryAlgorithmID, out var secPaying))
                        {
                            groupMiners.CurrentRate += secPaying * ad.SecondarySpeed * 0.000000001;
                        }
                        // Deduct power costs
                        var powerUsage = ad.PowerUsage > 0 ? ad.PowerUsage : groupMiners.TotalPower;
                        groupMiners.CurrentRate -= ExchangeRateApi.GetKwhPriceInBtc() * powerUsage * 24 / 1000;
                        groupMiners.PowerRate    = ExchangeRateApi.GetKwhPriceInBtc() * powerUsage * 24 / 1000;
                    }
                    else
                    {
                        groupMiners.CurrentRate = 0;
                        // set empty
                        ad = new ApiData(groupMiners.AlgorithmType);
                    }

                    currentProfit += groupMiners.CurrentRate;
                    // Update GUI
                    _mainFormRatesComunication.AddRateInfo(m.MinerTag(), groupMiners.DevicesInfoString, ad,
                                                           groupMiners.CurrentRate, groupMiners.PowerRate,
                                                           m.IsApiReadException);
                }
            }
            catch (Exception e) { Helpers.ConsolePrint(Tag, e.Message); }
        }
Пример #7
0
        public void CalculateProfits()
        {
            // save last state
            PrevProfitableAlgorithmType = MostProfitableAlgorithmType;
            PrevProfitableMinerBaseType = MostProfitableMinerBaseType;
            // assume none is profitable
            MostProfitableAlgorithmType = AlgorithmType.NONE;
            MostProfitableMinerBaseType = MinerBaseType.NONE;
            // calculate new profits
            foreach (var algo in Algorithms)
            {
                var key          = algo.NiceHashID;
                var secondaryKey = algo.SecondaryNiceHashID;
                if (NHSmaData.TryGetPayingWithTick("", key, out var paying))
                {
                    algo.CurNhmSmaDataVal = paying;
                    algo.CurrentProfit    = algo.CurNhmSmaDataVal * algo.AvaragedSpeed * 0.000000001;
                    if (NHSmaData.TryGetPayingWithTick("", secondaryKey, out var secPaying))
                    {
                        algo.SecondaryCurNhmSmaDataVal = secPaying;
                        algo.CurrentProfit            +=
                            algo.SecondaryCurNhmSmaDataVal * algo.SecondaryAveragedSpeed * 0.000000001;
                    }
                }
                else
                {
                    algo.CurrentProfit = 0;
                }
            }
            // find max paying value and save key
            double maxProfit = 0;

            foreach (var algo in Algorithms)
            {
                if (maxProfit < algo.CurrentProfit)
                {
                    maxProfit = algo.CurrentProfit;
                    MostProfitableAlgorithmType = algo.DualNiceHashID();
                    MostProfitableMinerBaseType = algo.MinerBaseType;
                }
            }
#if (SWITCH_TESTING)
            var devName = Device.GetFullName();
            // set new most profit
            if (Algorithms.ContainsKey(testingAlgos[next]))
            {
                MostProfitableKey = testingAlgos[next];
            }
            else if (ForceNone)
            {
                MostProfitableKey = AlgorithmType.NONE;
            }
            var mostProfitKeyName = AlgorithmNiceHashNames.GetName(MostProfitableKey);
            Helpers.ConsolePrint("SWITCH_TESTING", String.Format("Setting device {0} to {1}", devName, mostProfitKeyName));
#endif
        }
        public static void Initialize(TestContext context)
        {
            _gMiner   = new TestGMiner();
            _beamAlgo = new Algorithm(MinerBaseType.GMiner, AlgorithmType.Beam);
            var dev  = new ComputeDevice(0);
            var pair = new MiningPair(dev, _beamAlgo);

            _gMiner.InitBenchmarkSetup(pair);
            NHSmaData.Initialize();
        }
Пример #9
0
        public static void UpdateGroup(ApiData apiData, string minerUUID, string minerName)
        {
            if (apiData == null)
            {
                return;
            }
            if (apiData.AlgorithmSpeedsPerDevice == null || apiData.AlgorithmSpeedsPerDevice.Count == 0)
            {
                return;
            }
            if (apiData.PowerUsagePerDevice == null || apiData.PowerUsagePerDevice.Count == 0)
            {
                return;
            }
            if (apiData.AlgorithmSpeedsTotal == null || apiData.AlgorithmSpeedsTotal.Count == 0)
            {
                return;
            }

            var sortedDeviceUUIDs = apiData.AlgorithmSpeedsPerDevice.Select(speedInfo => speedInfo.Key).OrderBy(uuid => uuid).ToList();
            var uuidsKeys         = string.Join(",", sortedDeviceUUIDs);


            var groupKey = $"{minerUUID}-{uuidsKeys}";

            // update groups
            lock (_lock)
            {
                // check what keys to remove
                var removeKeys = _apiDataGroups.Keys.Where(checkKey => {
                    var minerUUIDDiffers = checkKey.StartsWith(minerUUID) == false;
                    var deviceInKey      = sortedDeviceUUIDs.Any(uuid => checkKey.Contains(uuid));
                    return(minerUUIDDiffers && deviceInKey);
                }).ToArray();
                foreach (var removeKey in removeKeys)
                {
                    _apiDataGroups.Remove(removeKey);
                    _minersMiningStats.Remove(removeKey);
                }
                // add / update data
                _apiDataGroups[groupKey] = apiData;

                var payingRates = NHSmaData.CurrentPayingRatesSnapshot();
                // update stats
                UpdateMinerMiningStats(apiData, minerUUID, minerName, groupKey, payingRates);
                // update device stats
                foreach (var deviceUuid in sortedDeviceUUIDs)
                {
                    UpdateDeviceMiningStats(apiData, minerUUID, minerName, groupKey, deviceUuid, payingRates);
                }

                // TODO notify change
            }
        }
Пример #10
0
        public void AddAlgorithmsToDevices()
        {
            var payingRates = NHSmaData.CurrentPayingRatesSnapshot();

            CheckExec(nameof(AddAlgorithmsToDevices), () => {
                if (!_initInternalsCalled && _plugin is IInitInternals impl)
                {
                    _initInternalsCalled = true;
                    impl.InitInternals();
                }
                // update settings for algos per device
                var devices = _cachedNiceHashMinerAlgorithms.Keys.Select(uuid => AvailableDevices.GetDeviceWithUuid(uuid)).Where(d => d != null);
                foreach (var dev in devices)
                {
                    var algos = _cachedNiceHashMinerAlgorithms[dev.Uuid];
                    foreach (var algo in algos)
                    {
                        algo.UpdateEstimatedProfit(payingRates);
                        // try get data from configs
                        var pluginConf = dev.GetPluginAlgorithmConfig(algo.AlgorithmStringID);
                        if (pluginConf == null)
                        {
                            continue;
                        }
                        // set plugin algo
                        algo.Speeds  = pluginConf.Speeds;
                        algo.Enabled = pluginConf.Enabled;
                        if (ConfigManager.IsVersionChanged && PluginUUID == "0e0a7320-94ec-11ea-a64d-17be303ea466" && algo.AlgorithmName.Contains(AlgorithmType.RandomXmonero.ToString()) && (pluginConf.ExtraLaunchParameters == "" || pluginConf.ExtraLaunchParameters == "--cpu-priority=0"))
                        {
                            algo.ExtraLaunchParameters = "--cpu-priority 0";
                        }
                        else
                        {
                            algo.ExtraLaunchParameters = pluginConf.ExtraLaunchParameters;
                        }
                        algo.PowerUsage    = pluginConf.PowerUsage;
                        algo.ConfigVersion = pluginConf.GetVersion();
                        // check if re-bench is needed
                        var isReBenchmark = ShouldReBenchmarkAlgorithmOnDevice(dev.BaseDevice, algo.ConfigVersion, algo.IDs);
                        if (isReBenchmark)
                        {
                            Logger.Info(LogTag, $"Algorithms {algo.AlgorithmStringID} SET TO RE-BENCHMARK");
                        }
                        algo.IsReBenchmark = isReBenchmark;
                    }
                    // finally update algorithms
                    // remove old
                    dev.RemovePluginAlgorithms(PluginUUID);
                    dev.AddPluginAlgorithms(algos);
                }
            });
        }
Пример #11
0
        public void StartConnection(string btc = null, string worker = null, string group = null)
        {
            NHSmaData.InitializeIfNeeded();
            _connectionAttempted = true;

            _login.rig = ApplicationStateManager.RigID;

            if (btc != null)
            {
                _login.btc = btc;
            }
            if (worker != null)
            {
                _login.worker = worker;
            }
            if (group != null)
            {
                _login.group = group;
            }

            try
            {
                if (_webSocket == null)
                {
                    _webSocket = new WebSocket(_address, true);

                    _webSocket.OnOpen           += Login;
                    _webSocket.OnMessage        += ReceiveCallback;
                    _webSocket.OnError          += ErrorCallback;
                    _webSocket.OnClose          += CloseCallback;
                    _webSocket.Log.Level         = LogLevel.Debug;
                    _webSocket.Log.Output        = (data, s) => NHM.Common.Logger.Info("SOCKET", data.ToString());
                    _webSocket.EnableRedirection = true;
                }
                else
                {
                    NHM.Common.Logger.Info("SOCKET", $"Credentials change reconnecting nhmws");
                    _connectionEstablished = false;
                    _restartConnection     = true;
                    _webSocket?.Close(CloseStatusCode.Normal, $"Credentials change reconnecting {ApplicationStateManager.Title}.");
                }
                NHM.Common.Logger.Info("SOCKET", "Connecting");
                _webSocket.Connect();
                NHM.Common.Logger.Info("SOCKET", "Connected");
                _connectionEstablished = true;
                _restartConnection     = false;
            } catch (Exception e)
            {
                NHM.Common.Logger.Error("SOCKET", e.ToString());
            }
        }
        public static void Initialize(TestContext context)
        {
            _zHashBMiner = new TestBMiner(AlgorithmType.ZHash);
            _zHashAlgo   = new Algorithm(MinerBaseType.BMiner, AlgorithmType.ZHash);
            var dev = new ComputeDevice(0);

            _zHashBMiner.InitBenchmarkSetup(new MiningPair(dev, _zHashAlgo));

            _ethashBMiner = new TestBMiner(AlgorithmType.DaggerHashimoto);
            _etHashAlgo   = new Algorithm(MinerBaseType.BMiner, AlgorithmType.DaggerHashimoto);
            _ethashBMiner.InitBenchmarkSetup(new MiningPair(dev, _etHashAlgo));

            NHSmaData.Initialize();
        }
        public static void Initialize(TestContext context)
        {
            foreach (AlgorithmType algo in Enum.GetValues(typeof(AlgorithmType)))
            {
                if (algo > 0)
                {
                    StartPaying[algo] = R.NextDouble();
                }
            }

            NHSmaData.InitializeIfNeeded();
            NHSmaData.UpdateSmaPaying(StartPaying);

            NHSmaData.UpdateStableAlgorithms(TestStables);
        }
Пример #14
0
        private static Task HandleSMAMessage(string data)
        {
            dynamic message = JsonConvert.DeserializeObject(data);

            // Try in case stable is not sent, we still get updated paying rates
            try
            {
                JArray stable = JsonConvert.DeserializeObject(message.stable.Value);
                //SetStableAlgorithms(stable);
                var stables = stable.Select(algo => (AlgorithmType)algo.Value <int>());
                NHSmaData.UpdateStableAlgorithms(stables);
            }
            catch
            { }
            SetAlgorithmRates(message.data);
            return(Task.Delay(0)); // completed task
        }
Пример #15
0
        private void ConnectCallback(object sender, EventArgs e)
        {
            try
            {
                NHSmaData.InitializeIfNeeded();
                //send login
                var version = "NHML/" + Application.ProductVersion;
                var login   = new NicehashLogin
                {
                    version = version
                };
                var loginJson = JsonConvert.SerializeObject(login);
                SendData(loginJson);

                OnConnectionEstablished?.Invoke(null, EventArgs.Empty);
            } catch (Exception er)
            {
                Helpers.ConsolePrint("SOCKET", er.ToString());
            }
        }
Пример #16
0
        public void Paying_ShouldReturnCorrectAndFlagsAreSet()
        {
            var testPaying = new Dictionary <AlgorithmType, double>
            {
                { AlgorithmType.CryptoNight, 0.11 },
                { AlgorithmType.DaggerHashimoto, 0.9 },
                { AlgorithmType.Blake2s, 0 }
            };

            var testZero = new List <AlgorithmType>
            {
                AlgorithmType.Keccak,
                AlgorithmType.Equihash,
                AlgorithmType.Pascal
            };

            // Check initialized flag and initialize
            NHSmaData.Initialize();
            Assert.IsTrue(NHSmaData.Initialized);

            // Check hasdata flag and update with test data
            NHSmaData.UpdateSmaPaying(testPaying);
            Assert.IsTrue(NHSmaData.HasData);

            foreach (var algo in testPaying.Keys)
            {
                // Every key from test dict should return true and paying
                Assert.IsTrue(NHSmaData.TryGetPaying(algo, out var paying));
                Assert.AreEqual(testPaying[algo], paying);
            }

            foreach (var algo in testZero)
            {
                // These algos were not set so their value should be 0 (but still return true)
                Assert.IsTrue(NHSmaData.TryGetPaying(algo, out var paying));
                Assert.AreEqual(0, paying);
            }

            // Should be false since DaggerDecred does not have a valid SMA
            Assert.IsFalse(NHSmaData.TryGetPaying(AlgorithmType.DaggerDecred, out _));
        }
Пример #17
0
        public void Stable_ShouldReturnCorrect()
        {
            // We will update the stable algos multiple times
            var testStable = new List <List <AlgorithmType> >
            {
                new List <AlgorithmType>
                {
                    AlgorithmType.Keccak,
                    AlgorithmType.Equihash,
                    AlgorithmType.Pascal
                },
                new List <AlgorithmType>
                {
                    AlgorithmType.Keccak,
                    AlgorithmType.Equihash,
                    AlgorithmType.Pascal,
                    AlgorithmType.Blake2s
                },
                new List <AlgorithmType>
                {
                    AlgorithmType.DaggerHashimoto,
                    AlgorithmType.Equihash,
                    AlgorithmType.Pascal
                }
            };

            NHSmaData.Initialize();

            foreach (var epoch in testStable)
            {
                NHSmaData.UpdateStableAlgorithms(epoch);

                // Test over all algo types
                foreach (AlgorithmType algo in Enum.GetValues(typeof(AlgorithmType)))
                {
                    var stable = epoch.Contains(algo);
                    Assert.AreEqual(stable, NHSmaData.IsAlgorithmStable(algo));
                }
            }
        }
        public void SwitchingManager_ShouldReportNewProfitAfterTicks()
        {
            var higherPayings = new Dictionary <AlgorithmType, double>();

            foreach (var key in StartPaying.Keys)
            {
                higherPayings[key] = StartPaying[key] + 0.000001;
            }

            var manager = new AlgorithmSwitchingManager();

            manager.SmaCheckTimerOnElapsed(null, null);
            NHSmaData.UpdateSmaPaying(higherPayings);

            for (var i = 1; i <= AlgorithmSwitchingManager.MaxHistory + 5; i++)
            {
                manager.SmaCheckTimerOnElapsed(null, null);
                foreach (var algo in higherPayings.Keys)
                {
                    var paying = manager.LastPayingForAlgo(algo);

                    Assert.AreEqual(NHSmaData.IsAlgorithmStable(algo), TestStables.Contains(algo));

                    var range = NHSmaData.IsAlgorithmStable(algo)
                        ? AlgorithmSwitchingManager.StableRange
                        : AlgorithmSwitchingManager.UnstableRange;

                    if (i < range.Lower)
                    {
                        // We are below the interval for this algo to have updated
                        Assert.AreEqual(StartPaying[algo], paying);
                    }
                    else if (i >= range.Upper)
                    {
                        // We are above the max ticks for this algo to be updated
                        Assert.AreEqual(higherPayings[algo], paying);
                    }
                }
            }
        }
Пример #19
0
        private static void SetAlgorithmRates(JArray data)
        {
            try
            {
                var payingDict = new Dictionary <AlgorithmType, double>();
                if (data != null)
                {
                    foreach (var algo in data)
                    {
                        var algoKey = (AlgorithmType)algo[0].Value <int>();
                        payingDict[algoKey] = algo[1].Value <double>();
                    }
                }

                NHSmaData.UpdateSmaPaying(payingDict);

                OnSmaUpdate?.Invoke(null, EventArgs.Empty);
            }
            catch (Exception e)
            {
                Helpers.ConsolePrint("SOCKET", e.ToString());
            }
        }
Пример #20
0
            private static void ConnectCallback(object sender, EventArgs e)
            {
                try
                {
                    NHSmaData.InitializeIfNeeded();
                    //send login
                    var version = "NHML/" + Application.ProductVersion;
                    var login   = new nicehash_login
                    {
                        version = version
                    };
                    var loginJson = JsonConvert.SerializeObject(login);
                    SendData(loginJson);

                    DeviceStatus_Tick(null); // Send device to populate rig stats

                    OnConnectionEstablished.Emit(null, EventArgs.Empty);
                }
                catch (Exception er)
                {
                    Helpers.ConsolePrint("SOCKET", er.ToString());
                }
            }
Пример #21
0
        private static void SetAlgorithmRates(JArray data)
        {
            try
            {
                var payingDict = new Dictionary <AlgorithmType, double>();
                if (data != null)
                {
                    foreach (var algo in data)
                    {
                        var algoKey = (AlgorithmType)algo[0].Value <int>();
                        payingDict[algoKey] = algo[1].Value <double>();
                    }
                }

                NHSmaData.UpdateSmaPaying(payingDict);

                OnSmaUpdate?.Invoke(null, EventArgs.Empty);
            }
            catch (Exception e)
            {
                NHM.Common.Logger.Error("SOCKET", $"SetAlgorithmRates error: {e.Message}");
            }
        }
        public void SwitchingManager_ShouldAlwaysReportLowerProfit()
        {
            var manager = new AlgorithmSwitchingManager();

            manager.SmaCheckTimerOnElapsed(null, null);

            var currentPaying = new Dictionary <AlgorithmType, double>();

            for (var i = 0; i < AlgorithmSwitchingManager.MaxHistory + 10; i++)
            {
                foreach (var algo in StartPaying.Keys)
                {
                    currentPaying[algo] = manager.LastPayingForAlgo(algo);
                    // Randomly add or subtract
                    NHSmaData.UpdatePayingForAlgo(algo, StartPaying[algo] + (R.NextDouble() - 0.5));
                }

                manager.SmaCheckTimerOnElapsed(null, null);

                // Iterate again to check
                foreach (var algo in StartPaying.Keys)
                {
                    Assert.IsTrue(NHSmaData.TryGetPaying(algo, out var paying));
                    if (paying <= currentPaying[algo])
                    {
                        // New value was less/same, so normalized value should be that
                        Assert.AreEqual(paying, manager.LastPayingForAlgo(algo));
                    }
                    else
                    {
                        // New value was more, so normalized should be equal or greater (depending on ticks)
                        Assert.IsTrue(manager.LastPayingForAlgo(algo) >= currentPaying[algo]);
                    }
                }
            }
        }
Пример #23
0
        private static void SetStableAlgorithms(JArray stable)
        {
            var stables = stable.Select(algo => (AlgorithmType)algo.Value <int>());

            NHSmaData.UpdateStableAlgorithms(stables);
        }