private void OnSuggestDifficulty(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <BitcoinWorkerContext>(); client.Respond(true, request.Id); try { var requestedDiff = (double)Convert.ChangeType(request.Params, TypeCode.Double); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; if (requestedDiff > poolEndpoint.Difficulty) { context.SetDifficulty(requestedDiff); client.Notify(BitcoinStratumMethods.SetDifficulty, new object[] { context.Difficulty }); logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Difficulty set to {requestedDiff} as requested by miner"); } } catch (Exception ex) { logger.Error(ex, () => $"[{LogCat}] Unable to convert suggested difficulty {request.Params}"); } }
private MoneroJobParams CreateWorkerJob(StratumClient client) { var context = client.GetContextAs <MoneroWorkerContext>(); var job = new MoneroWorkerJob(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 MoneroJobParams { JobId = job.Id, Blob = blob, Target = target }; // update context lock (context) { context.AddJob(job); } return(result); }
protected virtual async Task OnSubmitAsync(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <BitcoinWorkerContext>(); try { if (request.Id == null) { throw new StratumException(StratumError.MinusOne, "missing request id"); } var requestAge = clock.Now - tsRequest.Timestamp.UtcDateTime; if (requestAge > maxShareAge) { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Dropping stale share submission request (not client's fault)"); return; } context.LastActivity = clock.Now; if (!context.IsAuthorized) { throw new StratumException(StratumError.UnauthorizedWorker, "Unauthorized worker"); } else if (!context.IsSubscribed) { throw new StratumException(StratumError.NotSubscribed, "Not subscribed"); } var requestParams = request.ParamsAs <string[]>(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; var share = await manager.SubmitShareAsync(client, requestParams, poolEndpoint.Difficulty); client.Respond(true, request.Id); messageBus.SendMessage(new ClientShare(client, share)); logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Share accepted: D={Math.Round(share.Difficulty, 3)}"); if (share.IsBlockCandidate) { poolStats.LastPoolBlockTime = clock.Now; } context.Stats.ValidShares++; UpdateVarDiff(client); } catch (StratumException ex) { client.RespondError(ex.Code, ex.Message, request.Id, false); context.Stats.InvalidShares++; logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Share rejected: {ex.Code}"); ConsiderBan(client, context, poolConfig.Banning); } }
private void OnGetWork(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <EthereumWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } object[] newJobParams = (object[])currentJobParams; var header = newJobParams[2]; var seed = newJobParams[1]; var target = EthereumUtils.GetTargetHex(new BigInteger(context.Difficulty * EthereumConstants.StratumDiffFactor)); client.Respond(new object[] { header, seed, target }, request.Id); context.IsInitialWorkSent = true; var requestParams = request.ParamsAs <string[]>(); var workerValue = requestParams?.Length > 0 ? requestParams[0] : null; // log association if (!string.IsNullOrEmpty(context.WorkerName)) { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] recieved GetWork command for {context.MinerName}.{context.WorkerName} from {client.RemoteEndpoint.Address}"); } else { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] received GetWork command for {context.MinerName} from {client.RemoteEndpoint.Address}"); } }
private void OnSubscribe(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <EthereumWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } var requestParams = request.ParamsAs <string[]>(); manager.PrepareWorker(client); var data = new object[] { new object[] { EthereumStratumMethods.MiningNotify, client.ConnectionId, EthereumConstants.EthereumStratumVersion }, context.ExtraNonce1 } .ToArray(); client.Respond(data, request.Id); // setup worker context context.IsSubscribed = true; context.IsNiceHashClient = true; //context.UserAgent = requestParams[0].Trim(); }
protected void UpdateVarDiff(StratumClient client, bool isIdleUpdate = false) { var context = client.GetContextAs <WorkerContextBase>(); if (context.VarDiff != null) { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Updating VarDiff" + (isIdleUpdate ? " [idle]" : string.Empty)); VarDiffManager varDiffManager; var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; lock (varDiffManagers) { if (!varDiffManagers.TryGetValue(poolEndpoint, out varDiffManager)) { varDiffManager = new VarDiffManager(poolEndpoint.VarDiff, clock); varDiffManagers[poolEndpoint] = varDiffManager; } } lock (context.VarDiff) { StartVarDiffIdleUpdate(client, poolEndpoint); var newDiff = varDiffManager.Update(context.VarDiff, context.Difficulty, isIdleUpdate); if (newDiff != null) { logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] VarDiff update to {Math.Round(newDiff.Value, 2)}"); OnVarDiffUpdate(client, newDiff.Value); } } } }
protected override async Task OnRequestAsync(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <MoneroWorkerContext>(); switch (request.Method) { case MoneroStratumMethods.Login: OnLogin(client, tsRequest); break; case MoneroStratumMethods.GetJob: OnGetJob(client, tsRequest); break; case MoneroStratumMethods.Submit: await OnSubmitAsync(client, tsRequest); break; case MoneroStratumMethods.KeepAlive: // recognize activity context.LastActivity = clock.Now; break; default: logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Unsupported RPC request: {JsonConvert.SerializeObject(request, serializerSettings)}"); client.RespondError(StratumError.Other, $"Unsupported request {request.Method}", request.Id); break; } }
public override (Share Share, string BlockHex) ProcessShare(StratumClient worker, string extraNonce2, string nTime, string solution) { Assertion.RequiresNonNull(worker, nameof(worker)); Assertion.Requires<ArgumentException>(!string.IsNullOrEmpty(extraNonce2), $"{nameof(extraNonce2)} must not be empty"); Assertion.Requires<ArgumentException>(!string.IsNullOrEmpty(nTime), $"{nameof(nTime)} must not be empty"); Assertion.Requires<ArgumentException>(!string.IsNullOrEmpty(solution), $"{nameof(solution)} must not be empty"); var context = worker.GetContextAs<BitcoinWorkerContext>(); if (nTime.Length != 8) throw new StratumException(StratumError.Other, "incorrect size of ntime"); var nTimeInt = uint.Parse(nTime.HexToByteArray().ReverseArray().ToHexString(), NumberStyles.HexNumber); if (nTimeInt < BlockTemplate.CurTime || nTimeInt > ((DateTimeOffset) clock.Now).ToUnixTimeSeconds() + 7200) throw new StratumException(StratumError.Other, "ntime out of range"); var nonce = context.ExtraNonce1 + extraNonce2; if (nonce.Length != 64) throw new StratumException(StratumError.Other, "incorrect size of extraNonce2"); if (solution.Length != 2694) throw new StratumException(StratumError.Other, "incorrect size of solution"); if (!RegisterSubmit(nonce, solution)) throw new StratumException(StratumError.DuplicateShare, "duplicate share"); return ProcessShareInternal(worker, nonce, nTimeInt, solution); }
protected override void OnSubscribe(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <BitcoinWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } var requestParams = request.ParamsAs <string[]>(); var data = new object[] { client.ConnectionId, } .Concat(manager.GetSubscriberData(client)) .ToArray(); client.Respond(data, request.Id); // setup worker context context.IsSubscribed = true; context.UserAgent = requestParams?.Length > 0 ? requestParams[0].Trim() : null; }
private void OnGetJob(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <MoneroWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.MinusOne, "missing request id", request.Id); return; } var getJobRequest = request.ParamsAs <MoneroGetJobRequest>(); // validate worker if (client.ConnectionId != getJobRequest?.WorkerId || !context.IsAuthorized) { client.RespondError(StratumError.MinusOne, "unauthorized", request.Id); return; } // respond var job = CreateWorkerJob(client); client.Respond(job, request.Id); }
protected virtual void OnSubscribe(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } var context = client.GetContextAs <BitcoinWorkerContext>(); var requestParams = request.ParamsAs <string[]>(); var data = new object[] { new object[] { new object[] { BitcoinStratumMethods.SetDifficulty, client.ConnectionId }, new object[] { BitcoinStratumMethods.MiningNotify, client.ConnectionId } } } .Concat(manager.GetSubscriberData(client)) .ToArray(); client.Respond(data, request.Id); context.IsSubscribed = true; context.UserAgent = requestParams?.Length > 0 ? requestParams[0].Trim() : null; client.Notify(BitcoinStratumMethods.SetDifficulty, new object[] { context.Difficulty }); client.Notify(BitcoinStratumMethods.MiningNotify, currentJobParams); }
private void OnAuthorize(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <EthereumWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } var requestParams = request.ParamsAs <string[]>(); var workerValue = requestParams?.Length > 0 ? requestParams[0] : null; //var password = requestParams?.Length > 1 ? requestParams[1] : null; // extract worker/miner var split = workerValue?.Split('.'); var minerName = split?.FirstOrDefault()?.Trim(); var workerName = split?.Skip(1).LastOrDefault()?.Trim(); // assumes that workerName is an address context.IsAuthorized = !string.IsNullOrEmpty(minerName) && manager.ValidateAddress(minerName); context.MinerName = minerName; context.WorkerName = workerName; // respond client.Respond(context.IsAuthorized, request.Id); EnsureInitialWorkSent(client); // log association logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] = {workerValue} = {client.RemoteEndpoint.Address}"); }
protected virtual (Share Share, string BlockHex) ProcessShareInternal(StratumClient worker, string extraNonce2, uint nTime, uint nonce) { var context = worker.GetContextAs <BitcoinWorkerContext>(); var extraNonce1 = context.ExtraNonce1; var coinbase = SerializeCoinbase(extraNonce1, extraNonce2); var coinbaseHash = coinbaseHasher.Digest(coinbase); var headerBytes = SerializeHeader(coinbaseHash, nTime, nonce); var headerHash = headerHasher.Digest(headerBytes, (ulong)nTime); var headerValue = new uint256(headerHash); var shareDiff = (double)new BigRational(BitcoinConstants.Diff1, headerHash.ToBigInteger()) * shareMultiplier; var stratumDifficulty = context.Difficulty; var ratio = shareDiff / stratumDifficulty; var isBlockCandidate = headerValue <= blockTargetValue; if (!isBlockCandidate && ratio < 0.99) { if (context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) { ratio = shareDiff / context.PreviousDifficulty.Value; if (ratio < 0.99) { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } stratumDifficulty = context.PreviousDifficulty.Value; } else { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } } var result = new Share { BlockHeight = BlockTemplate.Height, NetworkDifficulty = Difficulty * shareMultiplier, Difficulty = stratumDifficulty, }; if (isBlockCandidate) { result.IsBlockCandidate = true; result.BlockReward = rewardToPool.ToDecimal(MoneyUnit.BTC); result.BlockHash = blockHasher.Digest(headerBytes, nTime).ToHexString(); var blockBytes = SerializeBlock(headerBytes, coinbase); var blockHex = blockBytes.ToHexString(); return(result, blockHex); } return(result, null); }
private void OnLogin(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <MoneroWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.MinusOne, "missing request id", request.Id); return; } var loginRequest = request.ParamsAs <MoneroLoginRequest>(); if (string.IsNullOrEmpty(loginRequest?.Login)) { client.RespondError(StratumError.MinusOne, "missing login", request.Id); return; } // extract worker/miner/paymentid var split = loginRequest.Login.Split('.'); context.MinerName = split[0]; context.WorkerName = split.Length > 1 ? split[1] : null; context.UserAgent = loginRequest.UserAgent; // extract paymentid var index = context.MinerName.IndexOf('#'); if (index != -1) { context.PaymentId = context.MinerName.Substring(index + 1); context.MinerName = context.MinerName.Substring(0, index); } // validate login var result = manager.ValidateAddress(context.MinerName); context.IsSubscribed = result; context.IsAuthorized = result; if (!context.IsAuthorized) { client.RespondError(StratumError.MinusOne, "invalid login", request.Id); return; } // respond var loginResponse = new MoneroLoginResponse { Id = client.ConnectionId, Job = CreateWorkerJob(client) }; client.Respond(loginResponse, request.Id); // log association logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] = {loginRequest.Login} = {client.RemoteEndpoint.Address}"); }
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); }
protected virtual (Share Share, string BlockHex) ProcessShareInternal(StratumClient worker, string nonce, uint nTime, string solution) { var context = worker.GetContextAs<BitcoinWorkerContext>(); var solutionBytes = solution.HexToByteArray(); var headerBytes = SerializeHeader(nTime, nonce); if (!equihash.Verify(headerBytes, solutionBytes.Skip(3).ToArray())) throw new StratumException(StratumError.Other, "invalid solution"); var headerSolutionBytes = headerBytes.Concat(solutionBytes).ToArray(); var headerHash = headerHasher.Digest(headerSolutionBytes, (ulong) nTime); var headerHashReversed = headerHash.ToReverseArray(); var headerValue = new uint256(headerHash); var shareDiff = (double) new BigRational(coinbaseTxConfig.Diff1b, headerHash.ToBigInteger()) * shareMultiplier; var stratumDifficulty = context.Difficulty; var ratio = shareDiff / stratumDifficulty; var isBlockCandidate = headerValue <= blockTargetValue; if (!isBlockCandidate && ratio < 0.99) { if (context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) { ratio = shareDiff / context.PreviousDifficulty.Value; if (ratio < 0.99) throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); stratumDifficulty = context.PreviousDifficulty.Value; } else throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } var result = new Share { BlockHeight = BlockTemplate.Height, NetworkDifficulty = Difficulty, Difficulty = stratumDifficulty, }; if (isBlockCandidate) { result.IsBlockCandidate = true; result.BlockReward = rewardToPool.ToDecimal(MoneyUnit.BTC); result.BlockHash = headerHashReversed.ToHexString(); var blockBytes = SerializeBlock(headerBytes, coinbaseInitial, solutionBytes); var blockHex = blockBytes.ToHexString(); return (result, blockHex); } return (result, null); }
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); }
protected override async Task OnAuthorizeAsync(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { await base.OnAuthorizeAsync(client, tsRequest); var context = client.GetContextAs <BitcoinWorkerContext>(); if (context.IsAuthorized) { client.Notify(ZCashStratumMethods.SetTarget, new object[] { EncodeTarget(context.Difficulty) }); client.Notify(BitcoinStratumMethods.MiningNotify, currentJobParams); } }
private void OnSubmitLogin(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; var context = client.GetContextAs <EthereumWorkerContext>(); if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } var requestParams = request.ParamsAs <string[]>(); if (requestParams == null || requestParams.Length < 1 || requestParams.Any(string.IsNullOrEmpty)) { client.RespondError(StratumError.MinusOne, "invalid request", request.Id); return; } manager.PrepareWorker(client); client.Respond(true, request.Id); // setup worker context context.IsSubscribed = true; context.IsAuthorized = true; context.MinerName = requestParams[0].Trim(); var workerValue = requestParams?.Length > 0 ? requestParams[0] : null; // extract worker/miner var workerParts = workerValue?.Split('.'); var minerName = workerParts?.Length > 0 ? workerParts[0].Trim() : null; var workerName = workerParts?.Length > 1 ? workerParts[1].Trim() : null; if (!string.IsNullOrEmpty(minerName)) { context.MinerName = minerName.ToLower(); } if (!string.IsNullOrEmpty(workerName)) { context.WorkerName = workerName; } // log association if (!string.IsNullOrEmpty(context.WorkerName)) { logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] recieved SubmitLogin command for {context.MinerName}.{context.WorkerName} from {client.RemoteEndpoint.Address}"); } else { logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] recieved SubmitLogin command for {context.MinerName} from {client.RemoteEndpoint.Address}"); } }
protected virtual async Task OnAuthorizeAsync(StratumClient client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } var context = client.GetContextAs <BitcoinWorkerContext>(); var requestParams = request.ParamsAs <string[]>(); var workerValue = requestParams?.Length > 0 ? requestParams[0] : null; var password = requestParams?.Length > 1 ? requestParams[1] : null; var passParts = password?.Split(PasswordControlVarsSeparator); var split = workerValue?.Split('.'); var minerName = split?.FirstOrDefault()?.Trim(); var workerName = split?.Skip(1).FirstOrDefault()?.Trim() ?? string.Empty; context.IsAuthorized = !string.IsNullOrEmpty(minerName) && await manager.ValidateAddressAsync(minerName); context.MinerName = minerName; context.WorkerName = workerName; if (context.IsAuthorized) { client.Respond(context.IsAuthorized, request.Id); logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] = {workerValue} = {client.RemoteEndpoint.Address}"); var staticDiff = GetStaticDiffFromPassparts(passParts); if (staticDiff.HasValue && (context.VarDiff != null && staticDiff.Value >= context.VarDiff.Config.MinDiff || context.VarDiff == null && staticDiff.Value > context.Difficulty)) { context.VarDiff = null; context.SetDifficulty(staticDiff.Value); client.Notify(BitcoinStratumMethods.SetDifficulty, new object[] { context.Difficulty }); } } else { client.RespondError(StratumError.UnauthorizedWorker, "Authorization failed", request.Id, context.IsAuthorized); logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Banning unauthorized worker for 60 sec"); banManager.Ban(client.RemoteEndpoint.Address, TimeSpan.FromSeconds(60)); DisconnectClient(client); } }
protected override void DisconnectClient(StratumClient client) { var context = client.GetContextAs <WorkerContextBase>(); if (context.VarDiff != null) { lock (context.VarDiff) { context.VarDiff.Dispose(); } } base.DisconnectClient(client); }
protected override void OnVarDiffUpdate(StratumClient client, double newDiff) { var context = client.GetContextAs <BitcoinWorkerContext>(); context.EnqueueNewDifficulty(newDiff); if (context.HasPendingDifficulty) { context.ApplyPendingDifficulty(); client.Notify(BitcoinStratumMethods.SetDifficulty, new object[] { context.Difficulty }); client.Notify(BitcoinStratumMethods.MiningNotify, currentJobParams); } }
protected override void OnVarDiffUpdate(StratumClient client, double newDiff) { base.OnVarDiffUpdate(client, newDiff); var context = client.GetContextAs <EthereumWorkerContext>(); if (context.HasPendingDifficulty) { context.ApplyPendingDifficulty(); client.Notify(EthereumStratumMethods.SetDifficulty, new object[] { context.Difficulty }); client.Notify(EthereumStratumMethods.MiningNotify, currentJobParams); } }
protected override void OnVarDiffUpdate(StratumClient client, double newDiff) { var context = client.GetContextAs <BitcoinWorkerContext>(); context.EnqueueNewDifficulty(newDiff); // apply immediately and notify client if (context.HasPendingDifficulty) { context.ApplyPendingDifficulty(); client.Notify(ZCashStratumMethods.SetTarget, new object[] { EncodeTarget(context.Difficulty) }); client.Notify(BitcoinStratumMethods.MiningNotify, currentJobParams); } }
private void EnsureInitialWorkSent(StratumClient client) { var context = client.GetContextAs <EthereumWorkerContext>(); lock (context) { if (context.IsAuthorized && context.IsAuthorized && !context.IsInitialWorkSent) { context.IsInitialWorkSent = true; client.Notify(EthereumStratumMethods.SetDifficulty, new object[] { context.Difficulty }); client.Notify(EthereumStratumMethods.MiningNotify, currentJobParams); } } }
public override object[] GetSubscriberData(StratumClient worker) { Assertion.RequiresNonNull(worker, nameof(worker)); var context = worker.GetContextAs <BitcoinWorkerContext>(); context.ExtraNonce1 = extraNonceProvider.Next(); var responseData = new object[] { context.ExtraNonce1 }; return(responseData); }
public async Task <Share> SubmitShareAsync(StratumClient worker, string[] request, double stratumDifficulty, double stratumDifficultyBase) { Contract.RequiresNonNull(worker, nameof(worker)); Contract.RequiresNonNull(request, nameof(request)); logger.LogInvoke(LogCat, new[] { worker.ConnectionId }); var context = worker.GetContextAs <AionWorkerContext>(); var miner = request[0]; var jobId = request[1]; var time = request[2]; var nonce = request[3]; var soln = request[4]; AionJob job; // stale? lock (jobLock) { if (!validJobs.TryGetValue(jobId, out job)) { throw new StratumException(StratumError.MinusOne, "stale share"); } } // validate & process var(share, fullNonceHex, solution, headerHash, nTime) = await job.ProcessShare(worker, nonce, time, soln); // enrich share with common data share.PoolId = poolConfig.Id; share.Source = clusterConfig.ClusterName; share.Created = clock.Now; // if block candidate, submit & check if accepted by network if (share.IsBlockCandidate) { logger.Info(() => $"[{LogCat}] Submitting block {share.BlockHeight}"); share.IsBlockCandidate = await SubmitBlockAsync(share, fullNonceHex, headerHash, solution, nTime); if (share.IsBlockCandidate) { logger.Info(() => $"[{LogCat}] Daemon accepted block {share.BlockHeight} submitted by {context.MinerName}"); } } return(share); }
public virtual object[] GetSubscriberData(StratumClient worker) { Assertion.RequiresNonNull(worker, nameof(worker)); var context = worker.GetContextAs <BitcoinWorkerContext>(); context.ExtraNonce1 = extraNonceProvider.Next(); var responseData = new object[] { context.ExtraNonce1, BitcoinConstants.ExtranoncePlaceHolderLength - ExtranonceBytes, }; return(responseData); }
protected override void OnVarDiffUpdate(StratumClient client, double newDiff) { base.OnVarDiffUpdate(client, newDiff); // apply immediately and notify client var context = client.GetContextAs <MoneroWorkerContext>(); if (context.HasPendingDifficulty) { context.ApplyPendingDifficulty(); // re-send job var job = CreateWorkerJob(client); client.Notify(MoneroStratumMethods.JobNotify, job); } }
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(); // send job client.Notify(AionStratumMethods.SetDifficulty, new object[] { context.Difficulty }); client.Notify(AionStratumMethods.MiningNotify, currentJobParams); } }