Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        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);
                    }
                }
            }
        }