Exemple #1
0
        /*
         * private static void Debug()
         * {
         *  decimal currentMinute = .1M;
         *  Random rng = new Random();
         *  int mode = rng.Next(2);
         *  //0 = bad
         *  //1 = okay
         *  //2 = good
         *  List<Gpu> gpus = new List<Gpu>();
         *  var gpu = new Gpu
         *  {
         *      Color = mode == 0 ? "Red" : mode == 1 ? "Yellow" : "Cyan",
         *      Id = "/nvidia/gpu/0",
         *      Name = "GTX970",
         *      Temp = mode == 0 ? rng.Next(65, 70) : mode == 1 ? rng.Next(60, 65) : rng.Next(55, 60)
         *  };
         *  gpus.Add(gpu);
         *
         *  var gpu2 = new Gpu
         *  {
         *      Color = mode == 0 ? "Red" : mode == 1 ? "Yellow" : "Cyan",
         *      Id = "/nvidia/gpu/1",
         *      Name = "GTX960",
         *      Temp = mode == 0 ? rng.Next(65, 70) : mode == 1 ? rng.Next(60, 65) : rng.Next(55, 60)
         *  };
         *  gpus.Add(gpu2);
         *
         *  for (;;)
         *  {
         *      var r = new MiningRig
         *      {
         *          WalletPrefix = "0x",
         *          Wallet = "1337",
         *          Name = "theRig",
         *          Gpus = gpus,
         *          Hr = mode == 0 ? rng.Next(40, 50) : mode == 1 ? rng.Next(100, 110) : rng.Next(115, 120),
         *          Units = "MH",
         *          HrColor = mode == 0 ? "Red" : mode == 1 ? "Yellow" : "Cyan",
         *          SolutionsFound = rng.Next(1337),
         *          SolutionsRejected = rng.Next(10),
         *          Paused = false,
         *          ActiveCurrency = "ETH",
         *          Channels = new List<string> { "xzon" },
         *          MiningPool = "ethermine.org:4444",
         *          WorkerName = "the_beast",
         *          Schedule = new Schedule {
         *              CurrentMinute = (int)decimal.Floor(currentMinute),
         *              ScheduledConfigs = new List<ScheduledConfig>
         *              {
         *                  new ScheduledConfig()
         *                  {
         *                      MinerCommandLine = "ethminer.exe -a test -o test",
         *                      Name = "Ethereum",
         *                      StartTime = 0
         *                  }
         *              },
         *              TotalMinutesInSchedule = 1440
         *          }
         *      };
         *
         *      var json = JsonConvert.SerializeObject(r);
         *
         *      try
         *      {
         *          MonitoringSocket.Emit("pulse", json);
         *          Console.WriteLine("pulse");
         *      }
         *      catch (Exception) { }
         *
         *
         *
         *      r = new MiningRig
         *      {
         *          WalletPrefix = "",
         *          Wallet = "",
         *          Name = "1234ABCD",
         *          Gpus = gpus,
         *          Hr = mode == 0 ? rng.Next(40, 50) : mode == 1 ? rng.Next(100, 110) : rng.Next(115, 120),
         *          Units = "MH",
         *          HrColor = mode == 0 ? "Red" : mode == 1 ? "Yellow" : "Cyan",
         *          SolutionsFound = rng.Next(1337),
         *          SolutionsRejected = rng.Next(10),
         *          Paused = false,
         *          ActiveCurrency = "ETH",
         *          Channels = new List<string> { "xzon_public" },
         *          MiningPool = "",
         *          WorkerName = "",
         *          Schedule = null
         *      };
         *
         *      json = JsonConvert.SerializeObject(r);
         *
         *      try
         *      {
         *          MonitoringSocket.Emit("pulse", json);
         *          Console.WriteLine("pulse");
         *      }
         *      catch (Exception) { }
         *
         *
         *
         *      System.Threading.Thread.Sleep(5000);
         *  }
         * }*/

        private static void ConnectToMonitoringSocket()
        {
            _monitoringSocket?.Disconnect();
            _monitoringSocket?.Close();

            //Open socket to Monitoring Server
            IO.Options options = new IO.Options
            {
                AutoConnect  = true,
                Reconnection = true,
                //ReconnectionAttempts = 5,
                //ReconnectionDelay = 5,
                //Timeout = 20, //This causes the socket to never open for some reason
                Secure   = true,
                ForceNew = true,
                //Multiplex = true,
                IgnoreServerCertificateValidation = true,
                ForceJsonp = true
            };

            _monitoringSocket = IO.Socket(MonitoringServer, options);

            _monitoringSocket.On(Socket.EVENT_ERROR, () =>
            {
                Log.Warning("Error encountered with Monitoring Socket");
                _monitoringSocket.Disconnect();
            });

            _monitoringSocket.On(Socket.EVENT_DISCONNECT, () =>
            {
                PrettyConsole.WriteLine($"Disconnected from {MonitoringServer} Monitoring Server");
            });
            _monitoringSocket.On(Socket.EVENT_CONNECT, () =>
            {
                PrettyConsole.WriteLine("Connected to Monitoring Socket", ConsoleColor.Green);

                foreach (var channel in _channels)
                {
                    var cr = new Credentials
                    {
                        ChannelName      = channel.Name,
                        Password         = channel.Password,
                        IsRig            = true,
                        IsTrustedChannel = channel.IsTrustedChannel,
                        Version          = $"Xzon{Version}"
                    };

                    var json = JsonConvert.SerializeObject(cr);

                    PrettyConsole.WriteLine($"Joining channel {channel.Name}", ConsoleColor.Green);
                    PrettyConsole.WriteLine($"\tTrusted Channel: {channel.IsTrustedChannel}", channel.IsTrustedChannel ? ConsoleColor.Green : ConsoleColor.Yellow);
                    PrettyConsole.WriteLine($"\tShow Rig Name: {channel.ShowRigName}");
                    PrettyConsole.WriteLine($"\tShow Wallet Address: {channel.ShowWalletAddress}");
                    PrettyConsole.WriteLine($"\tShow Mining Pool: {channel.ShowMiningPool}");
                    PrettyConsole.WriteLine($"\tShow Schedule: {channel.ShowSchedule}");

                    _monitoringSocket.Emit("auth", json);
                    Thread.Sleep(100);
                }

                _lastHandshake = DateTime.Now;
            });
            _monitoringSocket.On("executeCommand", (data) =>
            {
                PrettyConsole.WriteLine($"Command Requested: {data}", ConsoleColor.DarkMagenta);
                ProcessSocketCommand(data.ToString());
            });
            _monitoringSocket.On("authFailed", (data) =>
            {
                PrettyConsole.Write($"Authentication to channel {data}: ");
                PrettyConsole.WriteLine("FAILED", ConsoleColor.Red);
            });
            _monitoringSocket.On("authSuccess", (data) =>
            {
                PrettyConsole.Write($"Authentication to channel {data}: ");
                PrettyConsole.WriteLine("SUCCESS", ConsoleColor.Green);
            });
            _monitoringSocket.On("handshake", (data) =>
            {
                _lastHandshake = DateTime.Now;
                //Log.Informational("Handshake Successful");
            });
        }
Exemple #2
0
        static void Main()
        {
            Initialize();

            #region Error Mode
            //Prevent error dialog popups, this prevents the miner sub process from hanging by a windows error popup during a crash
            NativeMethods.SetErrorMode(NativeMethods.ErrorModes.SemFailcriticalerrors | NativeMethods.ErrorModes.SemNogpfaulterrorbox);
            #endregion

            #region Console Hooks
            //Hook Console to catch Close Event
            Handler = ConsoleEventCallback;
            NativeMethods.SetConsoleCtrlHandler(Handler, true);

            Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
            {
                e.Cancel = true;
                _running = false;
                PrettyConsole.WriteLine("Gracefully exiting...", ConsoleColor.Magenta);
            };
            #endregion


Startup:
            try
            {
                ConnectToMonitoringSocket();

                //Every minute the miner is running, it updates this file with how many minutes it has mined % MinutesInRotation
                var text = "";
                try
                {
                    text = File.ReadAllText(MiningMinuteFile);
                }
                catch (Exception ex)
                {
                    Log.Warning(ex);
                }

                if (!int.TryParse(text, out _miningMinute))
                {
                    Log.Warning($"Unable to read Mining Minute, defaulting to 0. Text received from {MiningMinuteFile}: {text}");
                }

                int currentMinute = -1;

                var freshStart = new List <string> {
                    "XzonControlPanel"
                };
                foreach (MinerConfig miner in _miners)
                {
                    var exeName = Path.GetFileNameWithoutExtension(miner.ExeLocation);
                    if (!freshStart.Contains(exeName))
                    {
                        freshStart.Add(exeName);
                    }
                }

                foreach (var p in freshStart)
                {
                    ProcessHelper.KillProcess(p);
                }
                Thread.Sleep(1000);

                PrettyConsole.Write("Max Allowed GPU Temperature is ");
                PrettyConsole.WriteLine($"{MaxTemp}°c", ConsoleColor.Red);
                PrettyConsole.WriteLine();

                Log.Warning("Miner Has Started");

                //Main Loop
                while (_running)
                {
                    Temperature.Refresh();

                    #region Scheduling
                    if (DateTime.Now.Hour * 60 + DateTime.Now.Minute != currentMinute && !_paused)
                    {
                        //Minute changed, increment
                        _miningMinute = (_miningMinute + 1) % MinutesInRotation;
                        UpdateMiningMinute(_miningMinute);
                        currentMinute = DateTime.Now.Hour * 60 + DateTime.Now.Minute;

                        PrettyConsole.WriteLine($"Current Minute: {_miningMinute}", ConsoleColor.DarkYellow);

                        //Check if it is time to use the next miner config in the schedule
                        MinerConfig newMinerConfig = _miners[0];
                        foreach (MinerConfig miner in _miners)
                        {
                            if (miner.StartMinute <= _miningMinute)
                            {
                                newMinerConfig = miner;
                            }
                            else
                            {
                                PrettyConsole.WriteLine($"Will start {miner.Name} at minute {miner.StartMinute}", ConsoleColor.DarkYellow);
                            }
                        }
                        if (!newMinerConfig.Equals(_currentMiningConfig))
                        {
                            SetActiveMiner(newMinerConfig);
                        }
                    }
                    #endregion

                    VerifyProcesses();
                    if (!_running)
                    {
                        break;
                    }

                    if (_paused)
                    {
                        Log.Informational("Miner is paused");

                        //If reboot after paused X minutes is set, reboot after X minutes
                        if (RebootAfterPausedXMinutes > 0 && _pausedTime != null)
                        {
                            if (DateTime.Now > _pausedTime.Value.AddMinutes(RebootAfterPausedXMinutes))
                            {
                                Log.Warning("Rebooting Machine");
                                Process.Start("shutdown.exe", "-r -t 30");
                                _running = false;
                            }
                            else
                            {
                                Log.Informational($"Rebooting machine in {_pausedTime.Value.AddMinutes(RebootAfterPausedXMinutes).Subtract(DateTime.Now).TotalSeconds} seconds", true);
                                PrettyConsole.Write("Rebooting machine in ");
                                PrettyConsole.Write($"{_pausedTime.Value.AddMinutes(RebootAfterPausedXMinutes).Subtract(DateTime.Now).TotalSeconds}", ConsoleColor.Yellow);
                                PrettyConsole.WriteLine(" seconds");
                            }
                        }
                    }

                    List <Gpu> gpus = new List <Gpu>();
                    List <Cpu> cpus = new List <Cpu>();

                    if (Temperature.GpuTemperatures == null)
                    {
                        Log.Warning("Unable to read GPU Temperatures, killing miner");
                        Pause();
                        KillMiner();
                        continue;
                    }

                    foreach (var temp in Temperature.CpuTemperatures)
                    {
                        PrettyConsole.Write($"{temp.InstanceName} ({temp.InstanceId}): ");
                        PrettyConsole.WriteLine($"{temp.CurrentValue}°c", ConsoleColor.Cyan);
                        cpus.Add(new Cpu {
                            Color = "Cyan", Id = temp.InstanceId, Name = temp.InstanceName, Temp = (int)temp.CurrentValue
                        });
                    }

                    foreach (var temp in Temperature.GpuTemperatures)
                    {
                        PrettyConsole.Write($"{temp.InstanceName} ({temp.InstanceId}): ");
                        var outputColor = ConsoleColor.Cyan;

                        if (temp.CurrentValue >= MaxTemp)
                        {
                            outputColor = ConsoleColor.Red;
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                        }
                        else if (temp.CurrentValue >= WarningTemp)
                        {
                            outputColor = ConsoleColor.Yellow;
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                        }
                        else if (Math.Abs(temp.CurrentValue) < 1)
                        {
                            //Check if GPU went offline, if it did its reported temperature is 0, check for <1 because floating point numbers doing their thing
                            outputColor = ConsoleColor.Red;
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                            Log.Error($"GPU {temp.InstanceName} ({temp.InstanceId}) Went Offline.");
                            KillMiner();
                            Pause();
                        }
                        else
                        {
                            PrettyConsole.Write($"{temp.CurrentValue}", outputColor);
                            PrettyConsole.Write(@"°c");
                        }

                        decimal gpuHr = -1;

                        try
                        {
                            int gpuId;
                            if (int.TryParse(temp.InstanceId.Substring(temp.InstanceId.LastIndexOf("/", StringComparison.Ordinal) + 1), out gpuId))
                            {
                                lock (RecentGpuHashrates)
                                {
                                    if (RecentGpuHashrates.ContainsKey(gpuId) && RecentGpuHashrates[gpuId].Count > 0)
                                    {
                                        gpuHr = decimal.Round(RecentGpuHashrates[gpuId].Average(), 2);
                                        PrettyConsole.Write($" ({gpuHr} {_units}/s)", ConsoleColor.Gray);
                                    }
                                }
                            }
                        }
                        catch (Exception)
                        {
                            //Do nothing
                        }
                        finally
                        {
                            PrettyConsole.WriteLine();
                        }


                        gpus.Add(new Gpu
                        {
                            Color = outputColor.ToString(),
                            Name  = temp.InstanceName,
                            Id    = temp.InstanceId,
                            Temp  = (int)temp.CurrentValue,
                            Rate  = gpuHr
                        });

                        if (temp.CurrentValue > MaxTemp)
                        {
                            Log.Error($"Killing miner, GPU Temperature is {temp.CurrentValue}°c but the max is set for {MaxTemp}°c");

                            //Hard shut down
                            //Exit(1);

                            //Soft shut down
                            KillMiner();
                            Pause();
                        }
                    }

                    //Check average hash rate
                    decimal      averageHashrate = 0;
                    ConsoleColor hashrateColor   = ConsoleColor.Red;
                    if (RecentHashrates.Count > 0)
                    {
                        Queue <decimal> localQueue = new Queue <decimal>(RecentHashrates);
                        averageHashrate = decimal.Round(localQueue.Average(), 3);

                        hashrateColor = ConsoleColor.Green;
                        if (averageHashrate < _currentMiningConfig.HashrateError)
                        {
                            hashrateColor = ConsoleColor.Red;
                            if (localQueue.Count == TotalReadingsToAverage)
                            {
                                var error = $"Average Hashrate {averageHashrate} dropped below configured error rate ({_currentMiningConfig.HashrateError}). Killing miner.";
                                Log.Error(error);
                                KillMiner();
                            }
                        }
                        else if (averageHashrate < _currentMiningConfig.HashrateWarning)
                        {
                            hashrateColor = ConsoleColor.Yellow;
                            if (localQueue.Count == TotalReadingsToAverage)
                            {
                                Log.Warning($"Average Hashrate {averageHashrate} dropped below configured warning rate {_currentMiningConfig.HashrateWarning}.");
                            }
                        }

                        if (localQueue.Count > 0)
                        {
                            PrettyConsole.Write(@"Current Average Hashrate: ");

                            PrettyConsole.Write($"{averageHashrate} {_units}/s", hashrateColor);

                            PrettyConsole.WriteLine();
                        }

                        PrettyConsole.Write(@"Solutions Found: ");
                        PrettyConsole.Write($"{_solutionsFound}", _solutionsFound > 0 ? ConsoleColor.Green : ConsoleColor.Yellow);

                        if (_rejectedSolutions > 0)
                        {
                            PrettyConsole.Write(@". Rejected: ");
                            PrettyConsole.Write($"{_rejectedSolutions}", ConsoleColor.Red);
                        }

                        PrettyConsole.WriteLine(@".");
                    }

                    UpdateMonitoringSockets(gpus, cpus, averageHashrate, hashrateColor);

                    //foreach (var config in _miners)
                    //{
                    //    PrettyConsole.WriteLine($"({config.Wallet}){WalletHelper.GetWalletBalance(config.CurrencyCode, config.Wallet)}", ConsoleColor.DarkGreen);
                    //}

                    Thread.Sleep(10000);

                    if (File.Exists("stop.txt"))
                    {
                        File.Delete("stop.txt");
                        _running = false;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);

                if (_running)
                {
                    Log.Warning(ex);
                    Log.Informational("Attempting to restart from the beginning...");
                    goto Startup;
                }
            }

            KillMiner();
            Exit();
        }
Exemple #3
0
        static void Initialize()
        {
            ChannelsSection channelConfigSection = null;

            try
            {
                channelConfigSection = ConfigurationManager.GetSection("ChannelsSection") as ChannelsSection;
                if (channelConfigSection == null)
                {
                    throw new Exception("Configuration Error");
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Warning("XzonControlPanel.exe.config file is malformed. Please fix it or run the Configuration Tool to generate a valid config.");
                PrettyConsole.WriteLine("Press [ENTER] to exit.");
                Console.ReadLine();
                Environment.Exit(0);
            }
            _channels = channelConfigSection.Channels;


            MinersSection minerConfigSection = null;

            try
            {
                minerConfigSection = ConfigurationManager.GetSection("MinersSection") as MinersSection;

                if (minerConfigSection == null)
                {
                    throw new Exception("Configuration Error");
                }
            }
            catch (Exception ex)
            {
                Log.Error(ex);
                Log.Warning("XzonControlPanel.exe.config file is malformed. Please fix it or run the Configuration Tool to generate a valid config.");
                PrettyConsole.WriteLine("Press [ENTER] to exit.");
                Console.ReadLine();
                Environment.Exit(0);
            }

            _miners = minerConfigSection.Miners;

            PrettyConsole.WriteLine("===========================");
            PrettyConsole.WriteLine("Detected Configured Miners:");
            PrettyConsole.WriteLine("===========================");
            decimal total = 0;

            List <string> purge = new List <string>();

            foreach (MinerConfig item in _miners)
            {
                if (item.Ratio == 0)
                {
                    purge.Add(item.Name);
                }
                total += item.Ratio;
            }
            purge.ForEach(s => _miners.Remove(s));

            decimal scale = 100 / total;

            int startMinute = 0;

            foreach (MinerConfig item in _miners)
            {
                item.TrueRatio   = item.Ratio * scale;
                item.StartMinute = startMinute;
                PrettyConsole.Write($"{item.Name} ");
                PrettyConsole.WriteLine($"({decimal.Round(item.TrueRatio, 2)}%)", ConsoleColor.Green);
                PrettyConsole.WriteLine($"\tStarts at minute {item.StartMinute}");
                PrettyConsole.WriteLine($"\t{Path.GetFileNameWithoutExtension(item.ExeLocation)} {item.CommandLineParameters}");
                PrettyConsole.WriteLine("---------------------------");
                startMinute += (int)decimal.Floor(item.TrueRatio / 100 * MinutesInRotation);
            }
            Console.WriteLine();

            foreach (var miner in _miners)
            {
                if (miner.Ratio == 0)
                {
                    continue;
                }

                var match = WalletRegex.Match(miner.CommandLineParameters);
                if (match.Groups.Count >= 2)
                {
                    miner.Wallet = $"{match.Groups[1].Value}{match.Groups[2].Value}";
                }

                ScheduledConfigs.Add(new ScheduledConfig
                {
                    Name             = miner.Name,
                    MinerCommandLine = Path.GetFileName(miner.ExeLocation) + miner.CommandLineParameters,
                    StartTime        = miner.StartMinute
                });
            }

            if (!File.Exists(MiningMinuteFile))
            {
                File.WriteAllText(MiningMinuteFile, "-1");
            }

            HandleAutoStartup();

            _paused = !("StartMinerOnStartup".FromConfig().ToBool() ?? false);
        }