private void ProcessShare(Miner m, object id, string jobid, string minernonce) { string mixhash; double d; jobid = jobid.ToLower(); minernonce = minernonce.ToLower(); if (minernonce.Length != 16 - (Config.ConfigData.StratumExtranonceSize * 2)) { return; } Logging.Log(3, "Received share for job: " + jobid + " xn: " + m.extraNonce + " nonce: " + minernonce); if (jobid != currentJob.uniqueID) { // report stale share Logging.Log(3, "Received share is stale!"); m.SendShareResultFailed(id, "Stale share."); // maybe "uncle"? Job j = jobQueue.Find(jobid); if (j != null && j.seedHash == currentSeed) { d = ShareCheckWrapper.getShareDiff(j.headerHash, m.extraNonce + minernonce, out mixhash); if (d >= j.difficulty) { Logging.Log(1, "Submitting possible uncle, nonce: " + m.extraNonce + minernonce); WalletShare ws = new WalletShare(m.extraNonce + minernonce, j.headerHash, mixhash); bool result; if (!Wallet.SubmitWork(walletUri, ws, out result)) { pendingShares.Push(ws); // failed to send, save this share and send once wallet is online again } } } return; } // verify for duplicate share foreach (string n in m.receivedNonces) { if (n == minernonce) { // report duplicate share Logging.Log(3, "Received share is duplicate!"); m.SendShareResultFailed(id, "Duplicate share."); return; } } // verify share diff d = ShareCheckWrapper.getShareDiff(currentJob.headerHash, m.extraNonce + minernonce, out mixhash); Logging.Log(3, "Share diff: " + d.ToString("F4") + "/" + m.difficulty.ToString("F4")); if (d < m.difficulty) { // report low diff share Logging.Log(3, "Received share is above target!"); m.SendShareResultFailed(id, "Share above target."); return; } else if (d >= currentJob.difficulty) { // submit to wallet Logging.Log(1, "Submitting share to the wallet, nonce: " + m.extraNonce + minernonce + " diff: " + d.ToString("F4") + "/" + currentJob.difficulty.ToString("F4")); WalletShare ws = new WalletShare(m.extraNonce + minernonce, currentJob.headerHash, mixhash); bool result; if (!Wallet.SubmitWork(walletUri, ws, out result)) { pendingShares.Push(ws); // failed to send, save this share and send once wallet is online again } } speedMeasure.AddShare(m.difficulty); // report OK share Logging.Log(3, "Received share is OK!"); m.SendShareResultOK(id); // save share m.receivedNonces.Add(minernonce); }
private void ProcessWallet() { DateTime before_q = DateTime.Now; string[] workdata = Wallet.GetWork(walletUri); DateTime after_q = DateTime.Now; if (workdata != null && workdata.Length == 3) { // work data received successfully Logging.Log(5, "Received Eth workdata: seedhash=" + workdata[1] + ", headerhash=" + workdata[0] + ", target=" + workdata[2]); Logging.Log(5, "RPC time: " + (after_q - before_q).TotalMilliseconds.ToString("F0") + " ms"); double walletDiff = ShareCheckWrapper.getHashDiff(workdata[2]); Job j = new Job(workdata[1], workdata[0], walletDiff); if (!(j ^ currentJob)) { j.AdjustID(); Logging.Log(1, "New eth work, job id: " + j.uniqueID + ", wallet diff: " + walletDiff.ToString("F4")); // new job provided jobQueue.FixedEnqueue(j); currentJob = j; // determine miner diff double minerDiff = Config.ConfigData.StratumDifficulty; if (currentJob.difficulty < minerDiff) { minerDiff = currentJob.difficulty; } //Logging.Log(2, "Setting miner diff to: " + minerDiff.ToString("F4")); // dispatch job to miners lock (locker) { foreach (Miner m in miners) { if (m.isAuthorized && m.isSubscribed) { m.SetDifficultyAndJob(minerDiff, currentJob); } } } } // verify current seed if (currentSeed != currentJob.seedHash) { int res = ShareCheckWrapper.loadDAGFile(currentJob.seedHash, Config.ConfigData.DAGFolder + "\\"); switch (res) { case 0: currentSeed = currentJob.seedHash; Logging.Log(1, "Loaded DAG file: " + currentJob.seedHash.Substring(0, 16)); break; case 1: Logging.Log(1, "DAG load failed: invalid seedhash: " + currentJob.seedHash.Substring(0, 16)); break; case 2: Logging.Log(1, "DAG load failed: DAG file does not exist: " + currentJob.seedHash.Substring(0, 16)); break; case 3: Logging.Log(1, "DAG load failed: DAG file size is zero: " + currentJob.seedHash.Substring(0, 16)); break; case 4: Logging.Log(1, "DAG load failed: not enough memory?"); break; case 5: Logging.Log(1, "DAG load failed: cannot read DAG file: " + currentJob.seedHash.Substring(0, 16)); break; default: break; } } // now that wallet is 100% on, dispatch all queued wallet shares while (pendingShares.Count > 0) { WalletShare ws = pendingShares.Pop(); bool result; if (!Wallet.SubmitWork(walletUri, ws, out result)) { pendingShares.Push(ws); // wallet off again, save again and try later break; } } } }