示例#1
0
        static void DataReceivedFromMiner(string strData, CmdLineParams info)
        {
            //Process data received from the miner

            if (string.IsNullOrEmpty(strData))
            {
                return;
            }

            //Try to colorize text received
            SortedDictionary <int, FindAndColorText> dicClrs = new SortedDictionary <int, FindAndColorText>();

            foreach (FindAndColorText fac in gArrClrText)
            {
                for (int i = 0; ;)
                {
                    int nFnd = strData.IndexOf(fac.strText, i, fac.bIgnoreCase ? StringComparison.CurrentCultureIgnoreCase : StringComparison.CurrentCulture);
                    if (nFnd == -1)
                    {
                        break;
                    }

                    dicClrs[nFnd] = fac;

                    i = nFnd + fac.strText.Length;
                }
            }


            //Sort by index
            var sorted = dicClrs.ToList();
            int j      = 0;

            //And output on the console with color
            foreach (var kvp in sorted)
            {
                int nInd = kvp.Key;
                Console.Write(strData.Substring(j, nInd - j));

                int nLn = kvp.Value.strText.Length;

                Console.ForegroundColor = kvp.Value.clr;
                Console.Write(strData.Substring(nInd, nLn));
                Console.ForegroundColor = ConsoleColor.White;

                j = nInd + nLn;
            }

            if (j < strData.Length)
            {
                Console.Write(strData.Substring(j));
            }

            Console.WriteLine("");


            //Then analyze the data received from the miner
            AnalyzeDataReceivedFromMiner(strData, info);
        }
示例#2
0
        private static void threadWatchMiner(CmdLineParams cmd)
        {
            //Worker thread that watches the miner output
            //'cmd' = command line parameters

            Random rnd = new Random();

            DateTime dtmUtcLastNotRunning = DateTime.MinValue;
            DateTime dtmUtcLastStatsShown = DateTime.UtcNow;


            for (;; System.Threading.Thread.Sleep(500))
            {
                bool     bMinerRunning   = false;
                TimeSpan spnProcLifetime = new TimeSpan();

                //Is miner running?
                Process procMiner = gWS.getMinerProcessClass();
                if (procMiner != null &&
                    IsProcessRunning(procMiner))
                {
                    //Miner is running
                    dtmUtcLastNotRunning = DateTime.MinValue;
                    bMinerRunning        = true;

                    //How long ago did the miner process start running?
                    DateTime dtmStarted = procMiner.StartTime;

                    //How long ago was it?
                    spnProcLifetime = DateTime.Now - dtmStarted;


                    //Only if been running for 40 seconds
                    //INFO: The miner will be passing its own initialization, so skip it ....
                    double fSecRan = spnProcLifetime.TotalSeconds;
                    if (fSecRan > 40.0)
                    {
                        int nPID = procMiner.Id;
                        int nSleepDelaySec;

                        double fSecSinceLastGH;
                        double fSecKillAfter;

                        //Get last time we had a good hash rate
                        DateTime dtmUtc_LastGHR = gWS.getLastGoodHashRateTimeUTC();
                        if (dtmUtc_LastGHR != DateTime.MinValue)
                        {
                            TimeSpan spnSinceLGH = DateTime.UtcNow - dtmUtc_LastGHR;
                            fSecSinceLastGH = spnSinceLGH.TotalSeconds;
                            fSecKillAfter   = 60.0 * 2;                                         //When to restart miner - if no good hash rate after
                        }
                        else
                        {
                            //Never before
                            fSecSinceLastGH = fSecRan;
                            fSecKillAfter   = 60.0 * 4;                                         //When to restart miner - if no good hash rate after
                        }


                        //See if we need to kill the miner process
                        if (fSecSinceLastGH > fSecKillAfter)
                        {
                            //Kill the miner
                            try
                            {
                                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Warning, "Will attempt to kill miner (PID=" + nPID + ") after no good hash rates for " + fSecKillAfter + " sec");
                                OutputConsoleError("Will attempt to kill miner (PID=" + nPID + ") after no good hash rates for " + fSecKillAfter + " sec");

                                procMiner.Kill();

                                //Reset counters
                                gWS.setLastGoodHashRateTimeUTC();
                                gWS.setLastMinerExitTimeUTC(0xdead0001);

                                nSleepDelaySec = rnd.Next(1000, 3000);
                            }
                            catch (Exception ex)
                            {
                                //Failed
                                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Critical, "Failed to kill miner (PID=" + nPID + ") after no good hash rates -- " + ex.ToString());
                                OutputConsoleError("ERROR: Kill miner process failed! Check the log for details...");

                                nSleepDelaySec = rnd.Next(3000, 10000);
                            }

                            //Wait a little
                            Thread.Sleep(nSleepDelaySec);

                            continue;
                        }



                        //Get last time we had an accepted hash
                        double   fSecSinceLastAcc;
                        DateTime dtmUtc_LastAccept = gWS.getLastAccaptedTimeUTC();
                        if (dtmUtc_LastAccept != DateTime.MinValue)
                        {
                            TimeSpan spnSinceLAcc = DateTime.UtcNow - dtmUtc_LastAccept;
                            fSecSinceLastAcc = spnSinceLAcc.TotalSeconds;
                            fSecKillAfter    = 60.0 * 30;                                       //When to restart miner - if no good hash rate after
                        }
                        else
                        {
                            //Never before
                            fSecSinceLastAcc = fSecRan;
                            fSecKillAfter    = 60.0 * 35;                                       //When to restart miner - if no good hash rate after
                        }

                        //See if we need to kill the miner process
                        if (fSecSinceLastAcc > fSecKillAfter)
                        {
                            //Kill the miner
                            try
                            {
                                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Warning, "Will attempt to kill miner (PID=" + nPID + ") after no accepted hashes for " + fSecKillAfter + " sec");
                                OutputConsoleError("Will attempt to kill miner (PID=" + nPID + ") after no accepted hashes for " + fSecKillAfter + " sec");

                                procMiner.Kill();

                                //Reset counters
                                gWS.setLastAcceptedTimeUTC();
                                gWS.setLastMinerExitTimeUTC(0xdead0002);

                                nSleepDelaySec = rnd.Next(1000, 3000);
                            }
                            catch (Exception ex)
                            {
                                //Failed
                                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Critical, "Failed to kill miner (PID=" + nPID + ") after no accepted hashes -- " + ex.ToString());
                                OutputConsoleError("ERROR: Kill miner process failed! Check the log for details...");

                                nSleepDelaySec = rnd.Next(3000, 10000);
                            }

                            //Wait a little
                            Thread.Sleep(nSleepDelaySec);

                            continue;
                        }
                    }
                }
                else
                {
                    //Miner is not running
                    if (dtmUtcLastNotRunning != DateTime.MinValue)
                    {
                        //See how long the miner wasn't running
                        TimeSpan spnNotRunning  = DateTime.UtcNow - dtmUtcLastNotRunning;
                        double   fSecNotRunning = spnNotRunning.TotalSeconds;

                        //Check if miner was not running for too long
                        if (fSecNotRunning > (5 * 60.0))                                //5 minutes
                        {
                            //Need to reboot
                            gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "Will attempt to REBOOT the rig after " + fSecNotRunning + " sec of miner process not running");
                            OutputConsoleError("CRITICAL: Will attempt to REBOOT the rig after " + fSecNotRunning + " sec of miner process not running");

                            Thread.Sleep(3 * 1000);

                            //Force reboot
                            rebootRig(true, "After " + fSecNotRunning + " of miner process not running");

                            //Reset counter
                            dtmUtcLastNotRunning = DateTime.MinValue;
                        }
                    }
                    else
                    {
                        dtmUtcLastNotRunning = DateTime.UtcNow;
                    }
                }



                //See if we need to show stats
                DateTime dtmNowUtc          = DateTime.UtcNow;
                double   fSecSinceLastStats = (dtmNowUtc - dtmUtcLastStatsShown).TotalSeconds;

                //Show it every N seconds
                if (fSecSinceLastStats > 15.0)
                {
                    dtmUtcLastStatsShown = dtmNowUtc;

                    const string strFmtTimeSpan = "hh\\:mm\\:ss";

                    //Output watch stats
                    string strStats = "WATCH: Miner=" + (bMinerRunning ? "On" : "OFF");

                    if (bMinerRunning)
                    {
                        strStats += " Runtime=";
                        strStats += spnProcLifetime.ToString("dd\\:hh\\:mm\\:ss");
                    }

                    int  nExitCode;
                    uint nNumRunning;
                    gWS.getLastMinerExitTimeUTC(out nExitCode, out nNumRunning);
                    strStats += " Restarts=" + (nNumRunning - 1);

                    strStats += " LastAccepted=";
                    DateTime dtmLastAcceptedUTC = gWS.getLastAccaptedTimeUTC();
                    if (dtmLastAcceptedUTC != DateTime.MinValue)
                    {
                        strStats += (dtmNowUtc - dtmLastAcceptedUTC).ToString(strFmtTimeSpan);
                    }
                    else
                    {
                        strStats += "Never";
                    }


                    strStats += " LastGoodHash=";
                    DateTime dtmLastGoodHashUTC = gWS.getLastGoodHashRateTimeUTC();
                    if (dtmLastGoodHashUTC != DateTime.MinValue)
                    {
                        strStats += (dtmNowUtc - dtmLastGoodHashUTC).ToString(strFmtTimeSpan);
                    }
                    else
                    {
                        strStats += "Never";
                    }



                    //Output
                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                    Console.WriteLine(strStats);
                    Console.ForegroundColor = ConsoleColor.White;
                }
            }
        }
示例#3
0
        public static EventLog gEventLog = new EventLog();                 //Event log for diagnotic logging


        static void Main(string[] args)
        {
            //Do we have command line arguments?
            if (args.Length > 0)
            {
                if (args.Length >= 4)
                {
                    CmdLineParams clp = new CmdLineParams();
                    int           p   = 0;

                    if (uint.TryParse(args[p++], out clp.nHashRangeMin))
                    {
                        if (uint.TryParse(args[p++], out clp.nHashRangeMax))
                        {
                            if (clp.nHashRangeMax < clp.nHashRangeMin)
                            {
                                //Swap them
                                uint v = clp.nHashRangeMin;
                                clp.nHashRangeMin = clp.nHashRangeMax;
                                clp.nHashRangeMax = v;
                            }

                            if (uint.TryParse(args[p++], out clp.nMaxAllowedMinerRestartsBeforeReboot))
                            {
                                //Then
                                clp.strMinerExePath = args[p++];

                                //Get command line parameters follow
                                for (int a = p; a < args.Length; a++)
                                {
                                    clp.arrMinerCmdParams.Add(args[a]);
                                }


                                //Set event log message
                                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Information, "[PID=" + Process.GetCurrentProcess().Id + "] Starting miner watch with parameters: " +
                                                     String.Join(" ", args.ToArray()) +
                                                     " -- Last boot time: " + GetLastBootTime().ToString("g"));

                                //Set time when this app started
                                gWS.setWhenThisAppStartedTimeUTC();

                                //Begin a watching thread
                                Thread threadWatch = new Thread(() => { threadWatchMiner(clp); });
                                threadWatch.Start();

                                //And run the miner app
                                MinerRunningLoop(clp);
                            }
                            else
                            {
                                OutputConsoleError("ERROR: Invalid RebootAfter");
                            }
                        }
                        else
                        {
                            OutputConsoleError("ERROR: Invalid MaxHash");
                        }
                    }
                    else
                    {
                        OutputConsoleError("ERROR: Invalid MinHash");
                    }
                }
                else
                {
                    OutputConsoleError("ERROR: Not all command line parameters were provided");
                }
            }
            else
            {
                //Show command line args
                string strAppName = Process.GetCurrentProcess().ProcessName;

                Console.WriteLine(gkstrAppName + " v." + gkstrAppVersion);
                Console.WriteLine("by www.dennisbabkin.com");
                Console.WriteLine("");
                Console.WriteLine("Usage:");
                Console.WriteLine(strAppName + " MinHash MaxHash RebootAfter \"path-to\\ethminer.exe\" miner_commad_line");
                Console.WriteLine("");
                Console.WriteLine("where:");
                Console.WriteLine("  MinHash      = mininum allowed hash rate range (in Mh), ex: 80");
                Console.WriteLine("  MaxHash      = maximum allowed hash rate range (in Mh), or 0 if any, ex: 100");
                Console.WriteLine("  RebootAfter  = number of ethminer restarts before rebooting the rig, or 0 not to reboot");
                Console.WriteLine("");
                Console.WriteLine("Example:");
                Console.WriteLine("");
                Console.WriteLine(strAppName + " 80 100 32 \"path-to\\ethminer.exe\" -P stratum://0xETH_PUB_KEY:[email protected]:14444");
                Console.WriteLine("");
            }
        }
示例#4
0
        static void AnalyzeDataReceivedFromMiner(string strData, CmdLineParams info)
        {
            //Tokenzine by space
            string[] arrPs = strData.Trim().Split(' ');
            int      nCnt  = arrPs.Count();

            // i 16:08:18 <unknown> Job: 23a95ff1... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:18 <unknown> Job: 4e9718f8... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:22 <unknown> Job: 03e90dfb... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:22 <unknown> 30:02 A2334:R4 90.96 Mh - cu0 22.65, cu1 22.77, cu2 22.77, cu3 22.77
            // i 16:08:26 <unknown> Job: cea10285... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:27 <unknown> 30:02 A2334:R4 90.90 Mh - cu0 22.58, cu1 22.77, cu2 22.77, cu3 22.77
            // i 16:08:30 <unknown> Job: e8275758... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:33 <unknown> 30:02 A2334:R4 90.97 Mh - cu0 22.65, cu1 22.77, cu2 22.77, cu3 22.77
            // i 16:08:34 <unknown> Job: 78de40c4... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:37 <unknown> Job: 3884b399... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:37 <unknown> Job: 894baba6... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:38 <unknown> 30:02 A2334:R4 90.96 Mh - cu0 22.65, cu1 22.77, cu2 22.77, cu3 22.77
            // i 16:08:41 <unknown> Job: 4c86d1d0... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:43 <unknown> 30:02 A2334:R4 90.90 Mh - cu0 22.58, cu1 22.77, cu2 22.77, cu3 22.77
            // i 16:08:43 <unknown> Job: cc9d4a34... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:43 <unknown> Job: 4c34a4ad... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:47 <unknown> Job: cc8dced9... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:48 <unknown> 30:03 A2334:R4 90.97 Mh - cu0 22.65, cu1 22.77, cu2 22.77, cu3 22.77
            //cu 16:08:48 cuda-1   Job: cc8dced9... Sol: 0xbca14f007c4cf6d7
            // i 16:08:48 <unknown> **Accepted  27 ms. us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:50 <unknown> Job: 24773f74... us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:50 <unknown> Job: b7631f18... us2.ethermine.org [172.65.226.101:14444]
            // m 16:08:53 <unknown> 30:03 A2335:R4 90.90 Mh - cu0 22.59, cu1 22.77, cu2 22.77, cu3 22.77
            //cu 16:08:54 cuda-2   Job: b7631f18... Sol: 0xbca14f017f7427cb
            // i 16:08:54 <unknown> **Accepted  26 ms. us2.ethermine.org [172.65.226.101:14444]
            // i 16:08:54 <unknown> Job: 8a7cbba8... us2.ethermine.org [172.65.226.101:14444]


            if (nCnt > 0 &&
                (arrPs[0].CompareTo("m") == 0 || arrPs[0].CompareTo("i") == 0))
            {
                for (int i = 1; i < nCnt; i++)
                {
                    //Look for Mh
                    if (arrPs[i].CompareTo("Mh") == 0)
                    {
                        //Look for:      A53 89.96 Mh
                        if (i - 2 > 0)
                        {
                            //Value before must be a float
                            double fHashRate;
                            if (double.TryParse(arrPs[i - 1], out fHashRate))
                            {
                                if (arrPs[i - 2].IndexOf('A') == 0)
                                {
                                    //This is a match
                                    bool bHashGood = false;

                                    //See if hashrate within range
                                    if (fHashRate >= info.nHashRangeMin)
                                    {
                                        //Good so far
                                        if (info.nHashRangeMax != 0)
                                        {
                                            //Need max range too
                                            if (fHashRate <= info.nHashRangeMax)
                                            {
                                                bHashGood = true;
                                            }
                                        }
                                        else
                                        {
                                            bHashGood = true;
                                        }
                                    }

                                    if (bHashGood)
                                    {
                                        //Register when we got a good hash rate
                                        gWS.setLastGoodHashRateTimeUTC();
                                    }

                                    break;
                                }
                            }
                        }
                    }
                    else if (arrPs[i].CompareTo("**Accepted") == 0)
                    {
                        //Hash was accepted
                        gWS.setLastAcceptedTimeUTC();

                        break;
                    }
                }
            }
        }
示例#5
0
        static MinerRunResult RunMiner(CmdLineParams info)
        {
            //Run the miner process and begin watching it
            MinerRunResult res = MinerRunResult.RES_MR_BAD_PARAMS_DIDNT_RUN;

            try
            {
                Process proc = new Process();
                proc.StartInfo.FileName = info.strMinerExePath;

                if (info.arrMinerCmdParams.Count > 0)
                {
                    //Make command line
                    string strCmdLn = "";

                    foreach (string strCmd in info.arrMinerCmdParams)
                    {
                        if (!string.IsNullOrEmpty(strCmdLn))
                        {
                            strCmdLn += " ";
                        }

                        if (strCmd.IndexOf(' ') == -1)
                        {
                            strCmdLn += strCmd;
                        }
                        else
                        {
                            strCmdLn += "\"" + strCmd + "\"";
                        }
                    }

                    proc.StartInfo.Arguments       = strCmdLn;
                    proc.StartInfo.UseShellExecute = false;
                    proc.StartInfo.CreateNoWindow  = true;

                    proc.StartInfo.RedirectStandardOutput = true;
                    proc.StartInfo.RedirectStandardError  = true;

                    proc.OutputDataReceived += new DataReceivedEventHandler((sender, e) =>
                    {
                        try
                        {
                            DataReceivedFromMiner(e.Data, info);
                        }
                        catch (Exception ex)
                        {
                            //Failed
                            gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "EXCEPTION_2: " + ex.ToString());
                            OutputConsoleError("EXCEPTION_2: " + ex.ToString());
                        }
                    });

                    proc.ErrorDataReceived += new DataReceivedEventHandler((sender, e) =>
                    {
                        try
                        {
                            DataReceivedFromMiner(e.Data, info);
                        }
                        catch (Exception ex)
                        {
                            //Failed
                            gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "EXCEPTION_3: " + ex.ToString());
                            OutputConsoleError("EXCEPTION_3: " + ex.ToString());
                        }
                    });


                    //Start the process
                    gWS.setMinerProcessClass(proc, true);
                    proc.Start();

                    //Make the miner process exit with ours
                    AttachChildProcessToThisProcess(proc);


                    int nPID = proc.Id;
                    gEventLog.logMessage(EventLogMsgType.ELM_TYP_Information, "Miner started (PID=" + nPID + ") ... with CMD: " + strCmdLn);

                    proc.BeginErrorReadLine();
                    proc.BeginOutputReadLine();
                    proc.WaitForExit();

                    //Get exit code & remember it
                    uint nExitCd = (uint)proc.ExitCode;
                    gWS.setLastMinerExitTimeUTC(nExitCd);

                    gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "Miner process (PID=" + nPID + ") has exited with error code 0x" + nExitCd.ToString("X"));

                    OutputConsoleError("WARNING: Miner has exited with error code 0x" + nExitCd.ToString("X") + " ....");

                    res = MinerRunResult.RES_MR_MINER_EXITED;
                }
                else
                {
                    //Error
                    OutputConsoleError("ERROR: Not enough parameters to start a miner");

                    res = MinerRunResult.RES_MR_BAD_PARAMS_DIDNT_RUN;
                }
            }
            catch (Exception ex)
            {
                //Failed
                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "EXCEPTION_1: " + ex.ToString());
                OutputConsoleError("EXCEPTION_1: " + ex.ToString());
                res = MinerRunResult.RES_MR_EXCEPTION;
            }

            return(res);
        }
示例#6
0
        static void MinerRunningLoop(CmdLineParams info)
        {
            //Loop that runs the miner and watches its performance

            Random rnd = new Random();

            for (;;)
            {
                int nmsWait;

                //Run the miner
                MinerRunResult res = RunMiner(info);

                if (res == MinerRunResult.RES_MR_BAD_PARAMS_DIDNT_RUN)
                {
                    gEventLog.logMessage(EventLogMsgType.ELM_TYP_Critical, "Quitting watch app due to unrecoverable error!");
                    OutputConsoleError("CRITICAL ERROR: Quitting watch app due to unrecoverable error!");
                    return;
                }
                else if (res == MinerRunResult.RES_MR_EXCEPTION)
                {
                    //Wait for some time
                    nmsWait = rnd.Next(10 * 1000, 60 * 1000);
                }
                else if (res == MinerRunResult.RES_MR_MINER_EXITED)
                {
                    //Wait for some time
                    nmsWait = rnd.Next(10 * 1000, 30 * 1000);
                }
                else
                {
                    //Some other value
                    gEventLog.logMessage(EventLogMsgType.ELM_TYP_Critical, "Quitting watch app due to unknown error! err=" + res);
                    OutputConsoleError("CRITICAL ERROR: Quitting watch app due to unknown error!");
                    return;
                }


                //Wait before restarting
                Console.WriteLine("Waiting for " + nmsWait / 1000 + " sec before restarting the miner...");
                Thread.Sleep(nmsWait);

                //Log message
                int  nExitCode;
                uint nNumStarted;
                gWS.getLastMinerExitTimeUTC(out nExitCode, out nNumStarted);
                gEventLog.logMessage(EventLogMsgType.ELM_TYP_Warning, "MINER RESTART (number " + nNumStarted + ") after " + nmsWait / 1000 + " sec delay. Reason=" + res +
                                     ", exitCode=0x" + nExitCode.ToString("X"));


                //See if we've restarted too many times (and if we're allowed to reboot)
                if (info.nMaxAllowedMinerRestartsBeforeReboot > 0 &&
                    nNumStarted > info.nMaxAllowedMinerRestartsBeforeReboot)
                {
                    //Need to reboot the system
                    gEventLog.logMessage(EventLogMsgType.ELM_TYP_Error, "Will attempt to REBOOT the rig after " + nNumStarted + " miner restarts");
                    OutputConsoleError("CRITICAL: Will attempt to REBOOT the rig after " + nNumStarted + " miner restarts");

                    Thread.Sleep(3 * 1000);

                    //Force reboot
                    rebootRig(true, "After " + nNumStarted + "attempts to restart miner process");

                    break;
                }
            }
        }