Пример #1
0
        private void EnsureInitialWorkSent(StratumClient client)
        {
            var       context         = client.ContextAs <AionWorkerContext>();
            ArrayList arrayTarget     = new ArrayList();
            var       sendInitialWork = false;

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

            if (sendInitialWork)
            {
                // send intial update
                // await client.NotifyAsync(AionStratumMethods.MiningNotify, currentJobParams);
                // await client.NotifyAsync(AionStratumMethods.SetTarget, arrayTarget);
                client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                client.Notify(AionStratumMethods.SetTarget, arrayTarget);
            }
        }
Пример #2
0
        private async Task <string> getLatestNonce()
        {
            var latest = await daemon.ExecuteCmdSingleAsync <string>(logger, AionCommands.GetTransactionCount, new[] { poolConfig.Address });

            if (AionUtils.fromHex(latest.Response).Equals(latestNonce) || usedLatestNonce)
            {
                latestNonce     = latestNonce + 1;
                usedLatestNonce = false;
            }
            else
            {
                latestNonce     = AionUtils.fromHex(latest.Response);
                usedLatestNonce = true;
            }

            return(AionUtils.AppendHexStart(latestNonce.ToString("X")));
        }
Пример #3
0
        protected void OnNewJobAsync(object jobParams)
        {
            currentJobParams = jobParams;

            logger.Debug(() => $"Broadcasting job");

            // logger.Info(() => "!!! src/Miningcore/Blockchain/Aion/AionPool.cs/OnNewJobAsync");
            ForEachClient(client =>
            {
                var context = client.ContextAs <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(() => $"Booting zombie-worker (idle-timeout exceeded)");
                        DisconnectClient(client);
                        return;
                    }

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

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

                    // await client.NotifyAsync(AionStratumMethods.MiningNotify, currentJobParams);
                    // await client.NotifyAsync(AionStratumMethods.SetTarget, arrayTarget);
                    client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                    client.Notify(AionStratumMethods.SetTarget, arrayTarget);
                }
            });
        }
Пример #4
0
        protected override async Task OnVarDiffUpdateAsync(StratumClient client, double newDiff)
        {
            await base.OnVarDiffUpdateAsync(client, newDiff);

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

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

                // send job
                // await client.NotifyAsync(AionStratumMethods.MiningNotify, currentJobParams);
                // await client.NotifyAsync(AionStratumMethods.SetTarget, targetArray);
                client.Notify(AionStratumMethods.MiningNotify, currentJobParams);
                client.Notify(AionStratumMethods.SetTarget, targetArray);
            }
        }
Пример #5
0
        private async Task <DaemonResponse <string> > SendTransactionPrivateKey(Balance balance)
        {
            logger.Info(() => $"[{LogCategory}] Sending {FormatAmount(balance.Amount)} to {balance.Address} using the private key.");
            var latestNonce = await getLatestNonce();

            var txData = new AionTransaction
            {
                Nonce     = AionUtils.AppendHexStart(latestNonce),
                To        = balance.Address,
                Value     = AionUtils.AppendHexStart(((BigInteger)Math.Floor(balance.Amount * AionConstants.Wei)).ToString("x")),
                Data      = "",
                Gas       = AionUtils.AppendHexStart(new BigInteger(22000).ToString("x")),
                GasPrice  = AionUtils.AppendHexStart(new BigInteger(10000000000).ToString("x")),
                Timestamp = AionUtils.AppendHexStart(DateTime.Now.Ticks.ToString("x2")),
                Type      = "0x01"
            };

            txData.Sign(extraConfig.PrivateKey);
            string serializedTx = txData.Serialize();

            return(await daemon.ExecuteCmdSingleAsync <string>(logger, AionCommands.SendRawTx, new[] { serializedTx }));
        }
Пример #6
0
        private (Share Share, string nonce, string solution, string headerHash, string nTime) ProcessShareInternal(
            StratumClient worker, string nonce, string nTime, string solution)
        {
            var context       = worker.ContextAs <AionWorkerContext>();
            var solutionBytes = solution.HexToByteArray();
            // serialize block-header
            var headerBytes = SerializeHeader(nonce);

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

            // hash block-header
            var         headerSolutionBytes = headerBytes.Concat(solutionBytes).ToArray();
            Span <byte> headerHash          = stackalloc byte[32];

            headerHasher.Digest(headerSolutionBytes, headerHash);
            var headerHashReversed = headerHash.ToNewReverseArray();
            var headerValue        = headerHashReversed.ToBigInteger();
            var target             = new BigInteger(blockTarget.ToBytes());

            var isBlockCandidate = target > headerValue;

            logger.Debug(() => $"context.Difficulty:{context.Difficulty} Difficulty: {Difficulty}");
            // 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).HexToReverseByteArray());
            var sentTarget     = new BigInteger(sentTargetInt.ToBytes());
            var isLowDiffShare = sentTarget <= headerValue;

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