Beispiel #1
0
        /// <summary>
        /// This is the main entry point to the thread.
        /// </summary>
        private void ThreadEntry()
        {
            try
            {
                // Reset some values
                BytesRead  = 0;
                ScoopsRead = 0;
                ulong utilisedStorage = 0;

                // Get which files to mine
                string[]     files      = Directory.GetFiles(_directory, "*_*_*_*");
                byte[]       readBuffer = null;
                List <Scoop> scoops     = new List <Scoop>(500);
                Stopwatch    swTotal    = new Stopwatch();
                swTotal.Start();

                // Process each file
                foreach (string file in files)
                {
                    // Get handle to file and ensure it is valid
                    Stopwatch sw = new Stopwatch();
                    sw.Start();
                    string[] fileParts = Path.GetFileName(file).Split(new char[] { '_' }, 4);
                    ulong    accountId;
                    ulong    startNonce;
                    ulong    numberOfNonces;
                    ulong    staggerSize;
                    if (!ulong.TryParse(fileParts[0], out accountId))
                    {
                        Logger.Error("Unable to parse account ID from " + file);
                        continue;
                    }
                    if (!ulong.TryParse(fileParts[1], out startNonce))
                    {
                        Logger.Error("Unable to parse start nonce from " + file);
                        continue;
                    }
                    if (!ulong.TryParse(fileParts[2], out numberOfNonces))
                    {
                        Logger.Error("Unable to parse number of nonces from " + file);
                        continue;
                    }
                    if (!ulong.TryParse(fileParts[3], out staggerSize))
                    {
                        Logger.Error("Unable to parse stagger size from " + file);
                        continue;
                    }
                    if (staggerSize != numberOfNonces)
                    {
                        Logger.Error("Unoptimised file, will not process " + file);
                        continue;
                    }
                    long     expectedSize = (long)(Plot.PLOT_SIZE * numberOfNonces);
                    FileInfo fi           = new FileInfo(file);
                    if (fi.Length != expectedSize)
                    {
                        Logger.Error("Plot file is not expected size, skipping " + file);
                        continue;
                    }
                    utilisedStorage += (ulong)expectedSize;

                    // Now we have a good plot file let's take our scoop and for each nonce process it
                    uint desiredBufferSize = (uint)(Plot.SCOOP_SIZE * numberOfNonces);
                    try
                    {
                        using (FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            // Create our reading buffers
                            uint remainingToRead = desiredBufferSize;
                            uint bufferSize      = desiredBufferSize > Configuration.MemoryLimitPerReader ? Configuration.MemoryLimitPerReader : desiredBufferSize;
                            if (readBuffer == null || readBuffer.Length < bufferSize)
                            {
                                readBuffer = new byte[bufferSize];
                            }

                            // Move to begining for optimized read
                            long offset = (long)(_scoop * desiredBufferSize);
                            stream.Seek(offset, SeekOrigin.Begin);

                            // Keep reading in large chunks up to maximum memory permitted and then handover to have deadline calculated elsewhere
                            ulong currentNonce = startNonce;
                            while (remainingToRead > 0)
                            {
                                uint read = (uint)stream.Read(readBuffer, 0, (int)(remainingToRead > bufferSize ? bufferSize : remainingToRead));
                                BytesRead       += read;
                                remainingToRead -= read;
                                scoops.Clear();
                                for (uint bufferOffset = 0; bufferOffset < read; bufferOffset += Plot.SCOOP_SIZE, currentNonce++)
                                {
                                    scoops.Add(new Scoop(_miningInfo.BlockHeight, currentNonce, accountId, readBuffer, bufferOffset));
                                    ScoopsRead++;
                                }

                                // Notify our callers
                                ScoopsDiscovered?.Invoke(this, new ScoopsDiscoveredEventArgs(scoops));

                                // Return if we're done
                                if (!_isAlive)
                                {
                                    break;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Logger.Error("Error whilst processing " + file, ex);
                    }
                    sw.Stop();
                    double secs = sw.Elapsed.TotalSeconds;
                    double bps  = desiredBufferSize / secs;
                    double mbps = bps / 1000 / 1000;
                    Logger.Debug(String.Format("Processed {0} in {1} secs = {2} MBps", file, secs, mbps));

                    // Return if we're done
                    if (!_isAlive)
                    {
                        break;
                    }
                }
                Logger.Info(String.Format("Read {0} {3}GB in {1} secs = {2} MBps", _directory, swTotal.Elapsed.TotalSeconds, (BytesRead / 1000 / 1000 / swTotal.Elapsed.TotalSeconds), (decimal)BytesRead / 1000m / 1000m / 1000m));
                UtilisedStorage = utilisedStorage / 1000000000m;
            }
            catch (Exception ex)
            {
                Logger.Error("Failure enumerating \"" + _directory + "\": " + ex.Message);
            }
            _isAlive      = false;
            _miningThread = null;
        }
 /// <summary>
 /// Handle new scoops being discovered and pass it over to the plot checker.
 /// </summary>
 /// <param name="sender">
 /// The event sender.
 /// </param>
 /// <param name="e">
 /// The event arguments.
 /// </param>
 private void PlotReaderOnScoopsDiscovered(object sender, ScoopsDiscoveredEventArgs e)
 {
     ScoopsDiscovered?.Invoke(this, e);
 }