protected virtual async Task OnSubmitAsync(StratumClient <BitcoinWorkerContext> client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; try { if (request.Id == null) { throw new StratumException(StratumError.MinusOne, "missing request id"); } // check age of submission (aged submissions are usually caused by high server load) var requestAge = clock.UtcNow - tsRequest.Timestamp.UtcDateTime; if (requestAge > maxShareAge) { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Dropping stale share submission request (not client's fault)"); return; } // check worker state client.Context.LastActivity = clock.UtcNow; // validate worker if (!client.Context.IsAuthorized) { throw new StratumException(StratumError.UnauthorizedWorker, "Unauthorized worker"); } else if (!client.Context.IsSubscribed) { throw new StratumException(StratumError.NotSubscribed, "Not subscribed"); } // submit var requestParams = request.ParamsAs <string[]>(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; var share = await manager.SubmitShareAsync(client, requestParams, poolEndpoint.Difficulty); // success client.Respond(true, request.Id); shareSubject.OnNext(Tuple.Create((object)client, share)); logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Share accepted: D={Math.Round(share.Difficulty * manager.ShareMultiplier, 3)}"); // update pool stats if (share.IsBlockCandidate) { poolStats.LastPoolBlockTime = clock.UtcNow; } // update client stats client.Context.Stats.ValidShares++; } catch (StratumException ex) { client.RespondError(ex.Code, ex.Message, request.Id, false); // update client stats client.Context.Stats.InvalidShares++; logger.Info(() => $"[{LogCat}] [{client.ConnectionId}] Share rejected: {ex.Code}"); // banning if (poolConfig.Banning?.Enabled == true) { ConsiderBan(client, client.Context, poolConfig.Banning); } } }
private async Task OnSubmitAsync(StratumClient <BitcoinWorkerContext> client, Timestamped <JsonRpcRequest> tsRequest) { var request = tsRequest.Value; if (request.Id == null) { client.RespondError(StratumError.Other, "missing request id", request.Id); return; } // check age of submission (aged submissions are usually caused by high server load) var requestAge = DateTime.UtcNow - tsRequest.Timestamp.UtcDateTime; if (requestAge > maxShareAge) { logger.Debug(() => $"[{LogCat}] [{client.ConnectionId}] Dropping stale share submission request (not client's fault)"); return; } // check worker state client.Context.LastActivity = DateTime.UtcNow; if (!client.Context.IsAuthorized) { client.RespondError(StratumError.UnauthorizedWorker, "Unauthorized worker", request.Id); } else if (!client.Context.IsSubscribed) { client.RespondError(StratumError.NotSubscribed, "Not subscribed", request.Id); } else { UpdateVarDiff(client, manager.BlockchainStats.NetworkDifficulty, true); try { // submit var requestParams = request.ParamsAs <string[]>(); var poolEndpoint = poolConfig.Ports[client.PoolEndpoint.Port]; var share = await manager.SubmitShareAsync(client, requestParams, client.Context.Difficulty, poolEndpoint.Difficulty); // success client.Respond(true, request.Id); // record it shareSubject.OnNext(share); // update pool stats if (share.IsBlockCandidate) { poolStats.LastPoolBlockTime = DateTime.UtcNow; } // update client stats client.Context.Stats.ValidShares++; // telemetry validSharesSubject.OnNext(share); } catch (StratumException ex) { client.RespondError(ex.Code, ex.Message, request.Id, false); // update client stats client.Context.Stats.InvalidShares++; // telemetry invalidSharesSubject.OnNext(Unit.Default); // banning if (poolConfig.Banning?.Enabled == true) { ConsiderBan(client, client.Context, poolConfig.Banning); } } } }