Пример #1
0
        private MoneroJobParams CreateWorkerJob(StratumClient <MoneroWorkerContext> client)
        {
            var job = new MoneroWorkerJob(NextJobId(), client.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 MoneroJobParams
            {
                JobId  = job.Id,
                Blob   = blob,
                Target = target
            };

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

            return(result);
        }
Пример #2
0
        public void AddJob(MoneroWorkerJob job)
        {
            ValidJobs.Add(job);

            while (ValidJobs.Count > 4)
                ValidJobs.RemoveAt(0);
        }
Пример #3
0
        public void PrepareWorkerJob(MoneroWorkerJob workerJob, out string blob, out string target)
        {
            workerJob.Height     = BlockTemplate.Height;
            workerJob.ExtraNonce = ++extraNonce;

            blob   = EncodeBlob(workerJob.ExtraNonce);
            target = EncodeTarget(workerJob.Difficulty);
        }
Пример #4
0
        public void PrepareWorkerJob(MoneroWorkerJob workerJob, out string blob, out string target)
        {
            blob   = null;
            target = null;

            var job = currentJob;

            job?.PrepareWorkerJob(workerJob, out blob, out target);
        }
Пример #5
0
        public void PrepareWorkerJob(MoneroWorkerJob workerJob, out string blob, out string target)
        {
            blob   = null;
            target = null;

            lock (jobLock)
            {
                currentJob?.PrepareWorkerJob(workerJob, out blob, out target);
            }
        }
Пример #6
0
        public async Task <Share> SubmitShareAsync(StratumClient worker,
                                                   MoneroSubmitShareRequest request, MoneroWorkerJob workerJob, double stratumDifficultyBase)
        {
            Contract.RequiresNonNull(worker, nameof(worker));
            Contract.RequiresNonNull(request, nameof(request));

            logger.LogInvoke(LogCat, new[] { worker.ConnectionId });
            var context = worker.GetContextAs <MoneroWorkerContext>();

            var job = currentJob;

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

            // validate & process
            var(share, blobHex, blobHash) = 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.MinerName;
            share.Worker            = context.WorkerName;
            share.PayoutInfo        = context.PaymentId;
            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(() => $"[{LogCat}] Submitting block {share.BlockHeight} [{blobHash.Substring(0, 6)}]");

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

                if (share.IsBlockCandidate)
                {
                    logger.Info(() => $"[{LogCat}] Daemon accepted block {share.BlockHeight} [{blobHash.Substring(0, 6)}] submitted by {context.MinerName}");
                    blockSubmissionSubject.OnNext(Unit.Default);

                    share.TransactionConfirmationData = blobHash;
                }

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

            return(share);
        }
Пример #7
0
        public void PrepareWorkerJob(MoneroWorkerJob 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);
        }
Пример #8
0
        public void PrepareWorkerJob(MoneroWorkerJob 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);
                }
            }
        }
Пример #9
0
        public async Task <IShare> SubmitShareAsync(StratumClient <MoneroWorkerContext> worker,
                                                    MoneroSubmitShareRequest request, MoneroWorkerJob workerJob, double stratumDifficultyBase)
        {
            MoneroJob job;

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

                job = currentJob;
            }

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

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

                share.IsBlockCandidate = await SubmitBlockAsync(share);

                if (share.IsBlockCandidate)
                {
                    logger.Info(() => $"[{LogCat}] Daemon accepted block {share.BlockHeight} [{share.BlobHash.Substring(0, 6)}]");

                    share.TransactionConfirmationData = share.BlobHash;
                }

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

            // enrich share with common data
            share.PoolId            = poolConfig.Id;
            share.IpAddress         = worker.RemoteEndpoint.Address.ToString();
            share.Miner             = worker.Context.MinerName;
            share.Worker            = worker.Context.WorkerName;
            share.PayoutInfo        = worker.Context.PaymentId;
            share.UserAgent         = worker.Context.UserAgent;
            share.NetworkDifficulty = job.BlockTemplate.Difficulty;
            share.Created           = clock.UtcNow;

            return(share);
        }