Example #1
0
        private async Task <(Share Share, string nonce, string solution, string headerHash, string nTime)> ProcessShareInternal(
            StratumClient worker, string nonce, string nTime, string solution)
        {
            var context       = worker.GetContextAs <AionWorkerContext>();
            var solutionBytes = solution.HexToByteArray();

            // serialize block-header
            var headerBytes = SerializeHeader(nonce);

            // verify solution
            if (!equihash.Verify210(headerBytes, solutionBytes))
            {
                throw new StratumException(StratumError.Other, "invalid solution");
            }

            // hash block-header
            var headerSolutionBytes = headerBytes.Concat(solutionBytes).ToArray();
            var headerHash          = headerHasher.Digest(headerSolutionBytes);
            var headerHashReversed  = headerHash.ToReverseArray();
            var headerBigInt        = headerHashReversed.ToBigInteger();
            var target = new BigInteger(blockTarget.ToBytes());

            var isBlockCandidate = target > headerBigInt;

            // calc share-diff
            var stratumDifficulty = context.Difficulty > Difficulty ? Difficulty : context.Difficulty;
            var shareDiff         = stratumDifficulty;
            var ratio             = shareDiff / stratumDifficulty;

            var sentTargetInt  = new uint256(AionUtils.diffToTarget(context.Difficulty).HexToByteArray().ReverseArray());
            var sentTarget     = new BigInteger(sentTargetInt.ToBytes());
            var isLowDiffShare = sentTarget <= headerBigInt;

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

            var result = new Share
            {
                BlockHeight                 = (long)BlockTemplate.Height,
                IpAddress                   = worker.RemoteEndpoint?.Address?.ToString(),
                Miner                       = context.MinerName,
                Worker                      = context.WorkerName,
                UserAgent                   = context.UserAgent,
                NetworkDifficulty           = Difficulty,
                Difficulty                  = stratumDifficulty,
                IsBlockCandidate            = isBlockCandidate,
                TransactionConfirmationData = headerHash.ToHexString(),
            };

            if (isBlockCandidate)
            {
                result.BlockReward = AionUtils.calculateReward((long)BlockTemplate.Height);
                result.BlockHash   = headerHashReversed.ToHexString();
            }

            return(result, nonce, solution, BlockTemplate.HeaderHash, nTime);
        }
Example #2
0
        private void EnsureInitialWorkSent(StratumClient client)
        {
            var context = client.GetContextAs <AionWorkerContext>();

            lock (context)
            {
                if (context.IsAuthorized && context.IsAuthorized && !context.IsInitialWorkSent)
                {
                    context.IsInitialWorkSent = true;
                    string newTarget = AionUtils.diffToTarget(context.Difficulty);
                    // update the difficulty
                    (((object[])currentJobParams)[2]) = newTarget;

                    // send intial update
                    client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                }
            }
        }
Example #3
0
        private void EnsureInitialWorkSent(StratumClient client)
        {
            var context = client.GetContextAs <AionWorkerContext>();

            lock (context)
            {
                if (context.IsAuthorized && !context.IsInitialWorkSent)
                {
                    context.IsInitialWorkSent = true;
                    string    newTarget   = AionUtils.diffToTarget(context.Difficulty);
                    ArrayList arrayTarget = new ArrayList();
                    arrayTarget.Add(newTarget);

                    // send intial update
                    client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                    client.Notify(AionStratumMethods.SetTarget, arrayTarget);
                }
            }
        }
Example #4
0
        protected override void OnVarDiffUpdate(StratumClient client, double newDiff)
        {
            base.OnVarDiffUpdate(client, newDiff);

            // apply immediately and notify client
            var context = client.GetContextAs <AionWorkerContext>();

            if (context.HasPendingDifficulty)
            {
                context.ApplyPendingDifficulty();
                string    newTarget   = AionUtils.diffToTarget(newDiff);
                ArrayList targetArray = new ArrayList();
                targetArray.Add(newTarget);

                // send job
                client.Notify(AionStratumMethods.SetDifficulty, new object[] { context.Difficulty });
                client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                client.Notify(AionStratumMethods.SetTarget, targetArray);
            }
        }
Example #5
0
        private void OnNewJob(object jobParams)
        {
            currentJobParams = jobParams;

            logger.Info(() => $"[{LogCat}] Broadcasting job");

            ForEachClient(client =>
            {
                var context = client.GetContextAs <AionWorkerContext>();

                if (context.IsSubscribed && context.IsAuthorized && context.IsInitialWorkSent)
                {
                    // check alive
                    var lastActivityAgo = clock.Now - context.LastActivity;

                    if (poolConfig.ClientConnectionTimeout > 0 &&
                        lastActivityAgo.TotalSeconds > poolConfig.ClientConnectionTimeout)
                    {
                        logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Booting zombie-worker (idle-timeout exceeded)");
                        DisconnectClient(client);
                        return;
                    }

                    // varDiff: if the client has a pending difficulty change, apply it now
                    if (context.ApplyPendingDifficulty())
                    {
                        client.Notify(AionStratumMethods.SetDifficulty, new object[] { context.Difficulty });
                    }

                    string newTarget      = AionUtils.diffToTarget(context.Difficulty);
                    ArrayList arrayTarget = new ArrayList();
                    arrayTarget.Add(newTarget);

                    client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                    client.Notify(AionStratumMethods.SetTarget, arrayTarget);
                }
            });
        }