From 3f3dc7f4f30591ec2ba57f4860e30e817cf8dc44 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 24 Apr 2015 19:58:40 +1000 Subject: [PATCH] Implement a stratum mining.term call which notifies the stratifier this client is terminating and use it to signal upstream pools when passthrough subclients have disconnected --- src/connector.c | 31 ++++++++++++++++++++++++------- src/stratifier.c | 7 +++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/connector.c b/src/connector.c index ed68155d..35dd0bd2 100644 --- a/src/connector.c +++ b/src/connector.c @@ -274,13 +274,25 @@ static int drop_client(cdata_t *cdata, client_instance_t *client) return fd; } +/* For sending the drop command to the upstream pool in passthrough mode */ +static void generator_drop_client(ckpool_t *ckp, const client_instance_t *client) +{ + json_t *val; + char *s; + + JSON_CPACK(val, "{si,sI:ss:si:ss:s[]}", "id", 42, "client_id", client->id, "address", + client->address_name, "server", client->server, "method", "mining.term", + "params"); + s = json_dumps(val, 0); + json_decref(val); + send_proc(ckp->generator, s); + free(s); +} + static void stratifier_drop_client(ckpool_t *ckp, const client_instance_t *client) { char buf[256]; - /* The stratifier is not in use in passthrough mode */ - if (ckp->passthrough || client->passthrough) - return; sprintf(buf, "dropclient=%"PRId64, client->id); send_proc(ckp->stratifier, buf); } @@ -295,7 +307,10 @@ static int invalidate_client(ckpool_t *ckp, cdata_t *cdata, client_instance_t *c int ret; ret = drop_client(cdata, client); - stratifier_drop_client(ckp, client); + if (!ckp->passthrough && !client->passthrough) + stratifier_drop_client(ckp, client); + else if (ckp->passthrough) + generator_drop_client(ckp, client); /* Cull old unused clients lazily when there are no more reference * counts for them. */ @@ -784,10 +799,10 @@ static char *connector_stats(cdata_t *cdata) static int connector_loop(proc_instance_t *pi, cdata_t *cdata) { - int64_t client_id64, client_id; unix_msg_t *umsg = NULL; ckpool_t *ckp = pi->ckp; uint8_t test_cycle = 0; + int64_t client_id; char *buf; int ret = 0; @@ -827,12 +842,14 @@ retry: } else if (cmdmatch(buf, "dropclient")) { client_instance_t *client; - ret = sscanf(buf, "dropclient=%"PRId64, &client_id64); + ret = sscanf(buf, "dropclient=%"PRId64, &client_id); if (ret < 0) { LOGDEBUG("Connector failed to parse dropclient command: %s", buf); goto retry; } - client_id = client_id64 & 0xffffffffll; + /* A passthrough client, we can't drop this yet */ + if (client_id > 0xffffffffll) + goto retry; client = ref_client_by_id(cdata, client_id); if (unlikely(!client)) { LOGINFO("Connector failed to find client id %"PRId64" to drop", client_id); diff --git a/src/stratifier.c b/src/stratifier.c index 5d483fcb..1b50a2cb 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -3460,6 +3460,13 @@ static void parse_method(sdata_t *sdata, stratum_instance_t *client, const int64 ckmsgq_add(sdata->stxnq, jp); return; } + + if (cmdmatch(method, "mining.term")) { + LOGDEBUG("Mining terminate requested from %"PRId64" %s", client_id, client->address); + drop_client(sdata, client_id); + return; + } + /* Unhandled message here */ LOGINFO("Unhandled client %"PRId64" %s method %s", client_id, client->address, method); return;