Exemplo n.º 1
0
        public override void Configure(PoolConfig poolConfig, ClusterConfig clusterConfig)
        {
            extraPoolConfig = poolConfig.Extra.SafeExtensionDataAs <EthereumPoolConfigExtra>();

            // extract standard daemon endpoints
            daemonEndpoints = poolConfig.Daemons
                              .Where(x => string.IsNullOrEmpty(x.Category))
                              .ToArray();

            base.Configure(poolConfig, clusterConfig);

            if (poolConfig.EnableInternalStratum == true)
            {
                // ensure dag location is configured
                var dagDir = !string.IsNullOrEmpty(extraPoolConfig?.DagDir) ?
                             Environment.ExpandEnvironmentVariables(extraPoolConfig.DagDir) :
                             Dag.GetDefaultDagDirectory();

                // create it if necessary
                Directory.CreateDirectory(dagDir);

                // setup ethash
                ethash = new EthashFull(3, dagDir);
            }
        }
        public override void Configure(PoolConfig poolConfig, XPoolConfig clusterConfig)
        {
            extraPoolConfig = poolConfig.Extra.SafeExtensionDataAs <EthereumPoolConfigExtra>();


            daemonEndpoints = poolConfig.Daemons
                              .Where(x => string.IsNullOrEmpty(x.Category))
                              .ToArray();

            base.Configure(poolConfig, clusterConfig);

            if (poolConfig.EnableInternalStratum == true)
            {
                var dagDir = !string.IsNullOrEmpty(extraPoolConfig?.DagDir) ?
                             Environment.ExpandEnvironmentVariables(extraPoolConfig.DagDir) :
                             Dag.GetDefaultDagDirectory();


                Directory.CreateDirectory(dagDir);


                ethash = new EthashFull(3, dagDir);
            }
        }
Exemplo n.º 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);
        }
Exemplo n.º 4
0
        public async ValueTask <(Share Share, string FullNonceHex, string HeaderHash, string MixHash)> ProcessShareAsync(
            StratumClient worker, string nonce, EthashFull ethash, CancellationToken ct)
        {
            // duplicate nonce?
            lock (workerNonces)
            {
                RegisterNonce(worker, nonce);
            }

            // assemble full-nonce
            var context = worker.ContextAs <EthereumWorkerContext>();

            var fullNonceHex = nonce.StartsWith("0x") ? nonce.Substring(2) : nonce;

            if (context.IsNiceHashClient && !string.IsNullOrEmpty(context.ExtraNonce1))
            {
                fullNonceHex = context.ExtraNonce1 + fullNonceHex;
            }

            if (!ulong.TryParse(fullNonceHex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var fullNonce))
            {
                throw new StratumException(StratumError.MinusOne, "bad nonce " + fullNonceHex);
            }

            // get dag for block
            var dag = await ethash.GetDagAsync(BlockTemplate.Height, logger, ct);

            // compute
            if (!dag.Compute(logger, BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes))
            {
                throw new StratumException(StratumError.MinusOne, "bad hash");
            }

            // test if share meets at least workers current difficulty
            resultBytes.ReverseInPlace();
            var resultValue       = new uint256(resultBytes);
            var resultValueBig    = resultBytes.AsSpan().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 Share
            {
                BlockHeight      = (long)BlockTemplate.Height,
                IpAddress        = worker.RemoteEndpoint?.Address?.ToString(),
                Miner            = context.Miner,
                Worker           = context.Worker,
                UserAgent        = context.UserAgent,
                IsBlockCandidate = isBlockCandidate,
                Difficulty       = stratumDifficulty * EthereumConstants.Pow2x32,
                BlockHash        = mixDigest.ToHexString(true)
            };

            if (share.IsBlockCandidate)
            {
                fullNonceHex = "0x" + fullNonceHex;
                var headerHash = BlockTemplate.Header;
                var mixHash    = mixDigest.ToHexString(true);

                share.TransactionConfirmationData = $"{mixDigest.ToHexString(true)}:{fullNonceHex}";

                return(share, fullNonceHex, headerHash, mixHash);
            }

            return(share, null, null, null);
        }
Exemplo n.º 5
0
        public async Task <(Share Share, string FullNonceHex, string HeaderHash, string MixHash)> ProcessShareAsync(StratumClient worker, string nonce, EthashFull ethash)
        {
            lock (workerNonces)
            {
                RegisterNonce(worker, nonce);
            }

            var context      = worker.GetContextAs <EthereumWorkerContext>();
            var fullNonceHex = context.ExtraNonce1 + nonce;

            if (!ulong.TryParse(fullNonceHex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var fullNonce))
            {
                throw new StratumException(StratumError.MinusOne, "bad nonce " + fullNonceHex);
            }

            var dag = await ethash.GetDagAsync(BlockTemplate.Height, logger);

            if (!dag.Compute(logger, BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes))
            {
                throw new StratumException(StratumError.MinusOne, "bad hash");
            }

            resultBytes.ReverseArray();

            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)
            {
                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})");
                    }

                    stratumDifficulty = context.PreviousDifficulty.Value;
                }

                else
                {
                    throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})");
                }
            }

            var share = new Share
            {
                BlockHeight      = (long)BlockTemplate.Height,
                IpAddress        = worker.RemoteEndpoint?.Address?.ToString(),
                Miner            = context.MinerName,
                Worker           = context.WorkerName,
                UserAgent        = context.UserAgent,
                IsBlockCandidate = isBlockCandidate,
                Difficulty       = stratumDifficulty * EthereumConstants.Pow2x32,
                BlockHash        = mixDigest.ToHexString(true)
            };

            if (share.IsBlockCandidate)
            {
                fullNonceHex = "0x" + fullNonceHex;
                var headerHash = BlockTemplate.Header;
                var mixHash    = mixDigest.ToHexString(true);

                share.TransactionConfirmationData = $"{mixDigest.ToHexString(true)}:{fullNonceHex}";

                return(share, fullNonceHex, headerHash, mixHash);
            }

            return(share, null, null, null);
        }
Exemplo n.º 6
0
        public async Task <(Share Share, string FullNonceHex, string HeaderHash, string MixHash)> ProcessShareAsync(StratumClient worker, string nonce, EthashFull ethash)
        {
            // duplicate nonce?
            //lock (workerNonces)
            //{
            //    RegisterNonce(worker, nonce);
            //}

            // assemble full-nonce
            var context      = worker.GetContextAs <EthereumWorkerContext>();
            var fullNonceHex = nonce.StartsWith("0x") ? nonce.Substring(2) : nonce;

            if (context.IsNiceHashClient && !string.IsNullOrEmpty(context.ExtraNonce1))
            {
                fullNonceHex = context.ExtraNonce1 + fullNonceHex;
            }

            if (!ulong.TryParse(fullNonceHex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var fullNonce))
            {
                throw new StratumException(StratumError.Other, "bad nonce " + fullNonceHex);
            }

            // get dag for block
            var dag = await ethash.GetDagAsync(BlockTemplate.Height, logger);

            // compute
            if (!dag.Compute(logger, BlockTemplate.Header.HexToByteArray(), fullNonce, out var mixDigest, out var resultBytes))
            {
                throw new StratumException(StratumError.Other, "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);
            var stratumDifficulty = context.Difficulty * EthereumConstants.StratumDiffFactor;
            var ratio             = shareDiff / stratumDifficulty;
            var isBlockCandidate  = resultValue <= blockTarget;

            if (!isBlockCandidate && ratio < 0.98)
            {
                throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})");
            }

            // create share
            var share = new Share
            {
                BlockHeight      = (long)BlockTemplate.Height,
                IpAddress        = worker.RemoteEndpoint?.Address?.ToString(),
                Miner            = context.MinerName,
                Worker           = context.WorkerName,
                UserAgent        = context.UserAgent,
                IsBlockCandidate = isBlockCandidate,
                Difficulty       = stratumDifficulty,
                BlockHash        = mixDigest.ToHexString(true)
            };

            if (share.IsBlockCandidate)
            {
                var headerHash = BlockTemplate.Header;
                var mixHash    = mixDigest.ToHexString(true);

                share.TransactionConfirmationData = $"{mixDigest.ToHexString(true)}:{nonce}";

                return(share, fullNonceHex, headerHash, mixHash);
            }

            return(share, null, null, null);
        }