private async Task <bool> SubmitBlockAsync(EthereumShare share) { //var response = await daemon.ExecuteCmdAnyAsync<SubmitResponse>(EC.SubmitBlock, new[] {share.BlobHex}); //if (response.Error != null || response?.Response?.Status != "OK") //{ // var error = response.Error?.Message ?? response.Response?.Status; // logger.Warn(() => $"[{LogCat}] Block {share.BlockHeight} [{share.BlobHash.Substring(0, 6)}] submission failed with: {error}"); // return false; //} return(true); }
private async Task <bool> SubmitBlockAsync(EthereumShare share) { // submit work var response = await daemon.ExecuteCmdAnyAsync <object>(EC.SubmitWork, new[] { share.FullNonceHex, share.HeaderHash, share.MixHash }); if (response.Error != null || (bool?)response.Response == false) { var error = response.Error?.Message ?? response?.Response?.ToString(); logger.Warn(() => $"[{LogCat}] Block {share.BlockHeight} submission failed with: {error}"); return(false); } return(true); }
public async Task <EthereumShare> ProcessShareAsync(StratumClient worker, string nonce, EthashFull ethash) { // duplicate nonce? lock (workerNonces) { RegisterNonce(worker, nonce); } // assemble full-nonce var context = worker.GetContextAs <EthereumWorkerContext>(); var fullNonceHex = context.ExtraNonce1 + nonce; var fullNonce = ulong.Parse(fullNonceHex, NumberStyles.HexNumber); // get dag for block var dag = await ethash.GetDagAsync(BlockTemplate.Height); // compute if (!dag.Compute(BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes)) { throw new StratumException(StratumError.MinusOne, "bad hash"); } resultBytes.ReverseArray(); // test if share meets at least workers current difficulty var resultValue = new uint256(resultBytes); var resultValueBig = resultBytes.ToBigInteger(); var shareDiff = (double)BigInteger.Divide(EthereumConstants.BigMaxValue, resultValueBig) / EthereumConstants.Pow2x32; var stratumDifficulty = context.Difficulty; var ratio = shareDiff / stratumDifficulty; var isBlockCandidate = resultValue <= blockTarget; if (!isBlockCandidate && ratio < 0.99) { // check if share matched the previous difficulty from before a vardiff retarget if (context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) { ratio = shareDiff / context.PreviousDifficulty.Value; if (ratio < 0.99) { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } // use previous difficulty stratumDifficulty = context.PreviousDifficulty.Value; } else { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } } // create share var share = new EthereumShare { BlockHeight = (long)BlockTemplate.Height, IpAddress = worker.RemoteEndpoint?.Address?.ToString(), Miner = context.MinerName, Worker = context.WorkerName, UserAgent = context.UserAgent, FullNonceHex = "0x" + fullNonceHex, HeaderHash = BlockTemplate.Header, MixHash = mixDigest.ToHexString(true), IsBlockCandidate = isBlockCandidate, Difficulty = stratumDifficulty * EthereumConstants.Pow2x32, BlockHash = mixDigest.ToHexString(true) // OW: is this correct? }; if (share.IsBlockCandidate) { share.TransactionConfirmationData = $"{mixDigest.ToHexString(true)}:{share.FullNonceHex}"; } return(share); }