diff --git a/src/stratifier.c b/src/stratifier.c index 38ef3bc4..c79893e6 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -261,6 +261,7 @@ struct stratum_instance { tv_t last_share; tv_t last_decay; time_t first_invalid; /* Time of first invalid in run of non stale rejects */ + time_t upstream_invalid; /* As first_invalid but for upstream responses */ time_t start_time; char address[INET6_ADDRSTRLEN]; @@ -4973,23 +4974,24 @@ out: /* Is this the first in a run of invalids? */ if (client->first_invalid < client->last_share.tv_sec || !client->first_invalid) client->first_invalid = now_t; - else if (client->first_invalid && client->first_invalid < now_t - 180) { + else if (client->first_invalid && client->first_invalid < now_t - 180 && client->reject < 3) { LOGNOTICE("Client %"PRId64" rejecting for 180s, disconnecting", client->id); - stratum_send_message(sdata, client, "Disconnecting for continuous invalid shares"); + if (ckp->node) + connector_drop_client(ckp, client->id); + else + stratum_send_message(sdata, client, "Disconnecting for continuous invalid shares"); client->reject = 3; - } else if (client->first_invalid && client->first_invalid < now_t - 120) { + } else if (client->first_invalid && client->first_invalid < now_t - 120 && client->reject < 2) { LOGNOTICE("Client %"PRId64" rejecting for 120s, reconnecting", client->id); stratum_send_message(sdata, client, "Reconnecting for continuous invalid shares"); - client->reject = 2; reconnect_client(sdata, client); - } else if (client->first_invalid && client->first_invalid < now_t - 60) { - if (!client->reject) { - LOGINFO("Client %"PRId64" rejecting for 60s, sending update", client->id); - update_client(client, client->id); - client->reject = 1; - } + client->reject = 2; + } else if (client->first_invalid && client->first_invalid < now_t - 60 && !client->reject) { + LOGNOTICE("Client %"PRId64" rejecting for 60s, sending update", client->id); + update_client(client, client->id); + client->reject = 1; } - } else { + } else if (client->reject < 3) { client->first_invalid = 0; client->reject = 0; } @@ -5326,6 +5328,28 @@ static void free_smsg(smsg_t *msg) free(msg); } +/* Even though we check the results locally in node mode, check the upstream + * results in case of runs of invalids. */ +static void parse_share_result(ckpool_t *ckp, stratum_instance_t *client, json_t *val) +{ + time_t now_t; + ts_t now; + + if (likely(json_is_true(val))) { + client->upstream_invalid = 0; + return; + } + ts_realtime(&now); + now_t = now.tv_sec; + if (client->upstream_invalid < client->last_share.tv_sec || !client->upstream_invalid) + client->upstream_invalid = now_t; + else if (client->upstream_invalid && client->upstream_invalid < now_t - 150) { + LOGNOTICE("Client %"PRId64" upstream rejects for 150s, disconnecting", client->id); + connector_drop_client(ckp, client->id); + client->reject = 3; + } +} + static void parse_diff(stratum_instance_t *client, json_t *val) { double diff = json_number_value(json_array_get(val, 0)); @@ -5408,6 +5432,9 @@ static void node_client_msg(ckpool_t *ckp, json_t *val, const char *buf, stratum jp = create_json_params(client->id, method, params, id_val); ckmsgq_add(sdata->sshareq, jp); break; + case SM_SHARERESULT: + parse_share_result(ckp, client, res_val); + break; case SM_DIFF: parse_diff(client, params); break;