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); }
public void AddJob(CryptonoteWorkerJob job) { validJobs.Insert(0, job); while (validJobs.Count > 4) { validJobs.RemoveAt(validJobs.Count - 1); } }
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); }
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); } } }
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); }