Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
        }