private CryptonoteJobParams CreateWorkerJob(StratumClient client)
        {
            var context = client.ContextAs <CryptonoteWorkerContext>();
            var job     = new CryptonoteWorkerJob(NextJobId(), context.Difficulty);

            manager.PrepareWorkerJob(job, out var blob, out var target);

            // should never happen
            if (string.IsNullOrEmpty(blob) || string.IsNullOrEmpty(blob))
            {
                return(null);
            }

            var result = new CryptonoteJobParams
            {
                JobId  = job.Id,
                Blob   = blob,
                Target = target,
                Height = job.Height,
            };

            // update context
            lock (context)
            {
                context.AddJob(job);
            }

            return(result);
        }
Example #2
0
        public void AddJob(CryptonoteWorkerJob job)
        {
            validJobs.Insert(0, job);

            while (validJobs.Count > 4)
            {
                validJobs.RemoveAt(validJobs.Count - 1);
            }
        }
Example #3
0
        public void PrepareWorkerJob(CryptonoteWorkerJob workerJob, out string blob, out string target)
        {
            workerJob.Height     = BlockTemplate.Height;
            workerJob.ExtraNonce = (uint)Interlocked.Increment(ref extraNonce);

            if (extraNonce < 0)
            {
                extraNonce = 0;
            }

            blob   = EncodeBlob(workerJob.ExtraNonce);
            target = EncodeTarget(workerJob.Difficulty);
        }
Example #4
0
        public void PrepareWorkerJob(CryptonoteWorkerJob workerJob, out string blob, out string target)
        {
            blob   = null;
            target = null;

            var job = currentJob;

            if (job != null)
            {
                lock (job)
                {
                    job.PrepareWorkerJob(workerJob, out blob, out target);
                }
            }
        }
Example #5
0
        public async ValueTask <Share> SubmitShareAsync(StratumClient worker,
                                                        CryptonoteSubmitShareRequest request, CryptonoteWorkerJob workerJob, double stratumDifficultyBase, CancellationToken ct)
        {
            Contract.RequiresNonNull(worker, nameof(worker));
            Contract.RequiresNonNull(request, nameof(request));

            logger.LogInvoke(new[] { worker.ConnectionId });
            var context = worker.ContextAs <CryptonoteWorkerContext>();

            var job = currentJob;

            if (workerJob.Height != job?.BlockTemplate.Height)
            {
                throw new StratumException(StratumError.MinusOne, "block expired");
            }

            // validate & process
            var(share, blobHex) = job.ProcessShare(request.Nonce, workerJob.ExtraNonce, request.Hash, worker);

            // enrich share with common data
            share.PoolId            = poolConfig.Id;
            share.IpAddress         = worker.RemoteEndpoint.Address.ToString();
            share.Miner             = context.Miner;
            share.Worker            = context.Worker;
            share.UserAgent         = context.UserAgent;
            share.Source            = clusterConfig.ClusterName;
            share.NetworkDifficulty = job.BlockTemplate.Difficulty;
            share.Created           = clock.Now;

            // if block candidate, submit & check if accepted by network
            if (share.IsBlockCandidate)
            {
                logger.Info(() => $"Submitting block {share.BlockHeight} [{share.BlockHash.Substring(0, 6)}]");

                share.IsBlockCandidate = await SubmitBlockAsync(share, blobHex, share.BlockHash);

                if (share.IsBlockCandidate)
                {
                    logger.Info(() => $"Daemon accepted block {share.BlockHeight} [{share.BlockHash.Substring(0, 6)}] submitted by {context.Miner}");

                    OnBlockFound();

                    share.TransactionConfirmationData = share.BlockHash;
                }

                else
                {
                    // clear fields that no longer apply
                    share.TransactionConfirmationData = null;
                }
            }

            return(share);
        }