From db1b2b45a491e155354d408a446e30e69f82c062 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 18 May 2014 14:46:24 +1000 Subject: [PATCH] Parse the mining difficulty when proxying and store it in the stratifier as the current workbase diff. Update notify and diff in stratifier when a change is deteced. --- src/generator.c | 44 ++++++++++++++++++++++++++++++++++++++++---- src/stratifier.c | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/src/generator.c b/src/generator.c index 5a0688ff..a7d1a608 100644 --- a/src/generator.c +++ b/src/generator.c @@ -63,7 +63,9 @@ struct proxy_instance { int id; /* Message id for sending stratum messages */ bool no_sessionid; /* Doesn't support session id resume on subscribe */ bool no_params; /* Doesn't want any parameters on subscribe */ - bool notified; /* Received template for work */ + + bool notified; /* Received new template for work */ + bool diffed; /* Received new diff */ pthread_mutex_t notify_lock; notify_instance_t *notify_instances; @@ -445,7 +447,6 @@ out: return ret; } -#define parse_diff(a, b) true #define parse_reconnect(a, b) true #define send_version(a, b) true #define show_message(a, b) true @@ -519,6 +520,17 @@ out: return ret; } +static bool parse_diff(proxy_instance_t *proxi, json_t *val) +{ + double diff = json_number_value(json_array_get(val, 0)); + + if (diff == 0 || diff == proxi->diff) + return true; + proxi->diff = diff; + proxi->diffed = true; + return true; +} + static bool parse_method(proxy_instance_t *proxi, const char *msg) { json_t *val = NULL, *method, *err_val, *params; @@ -688,6 +700,19 @@ static void send_notify(proxy_instance_t *proxi, int sockd) close(sockd); } +static void send_diff(proxy_instance_t *proxi, int sockd) +{ + json_t *json_msg; + char *msg; + + json_msg = json_pack("{sf}", "diff", proxi->diff); + msg = json_dumps(json_msg, 0); + json_decref(json_msg); + send_unix_msg(sockd, msg); + free(msg); + close(sockd); +} + static int proxy_loop(proc_instance_t *pi, connsock_t *cs, proxy_instance_t *proxi) { unixsock_t *us = &pi->us; @@ -698,7 +723,6 @@ static int proxy_loop(proc_instance_t *pi, connsock_t *cs, proxy_instance_t *pro /* We're not subscribed and authorised so tell the stratifier to * retrieve the first subscription. */ send_proc(ckp->stratifier, "subscribe"); - send_proc(ckp->stratifier, "notify"); retry: sockd = accept(us->sockd, NULL, NULL); @@ -724,6 +748,8 @@ retry: send_subscribe(proxi, sockd); } else if (!strncasecmp(buf, "getnotify", 9)) { send_notify(proxi, sockd); + } else if (!strncasecmp(buf, "getdiff", 7)) { + send_diff(proxi, sockd); } else if (!strncasecmp(buf, "ping", 4)) { LOGDEBUG("Proxy received ping request"); send_unix_msg(sockd, "pong"); @@ -757,6 +783,7 @@ static void *proxy_recv(void *arg) { proxy_instance_t *proxi = (proxy_instance_t *)arg; connsock_t *cs = proxi->cs; + ckpool_t *ckp = proxi->ckp; rename_proc("proxyrecv"); @@ -769,8 +796,17 @@ static void *proxy_recv(void *arg) reconnect_stratum(cs, proxi); continue; } - if (parse_method(proxi, cs->buf)) + if (parse_method(proxi, cs->buf)) { + if (proxi->notified) { + send_proc(ckp->stratifier, "notify"); + proxi->notified = false; + } + if (proxi->diffed) { + send_proc(ckp->stratifier, "diff"); + proxi->diffed = false; + } continue; + } LOGWARNING("Unhandled stratum message: %s", cs->buf); } return NULL; diff --git a/src/stratifier.c b/src/stratifier.c index 119843ed..0049fdca 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -538,6 +538,7 @@ static void update_notify(ckpool_t *ckp) memcpy(wb->enonce1constbin, proxy_base.enonce1bin, proxy_base.enonce1constlen); wb->enonce1varlen = wb->enonce2constlen = proxy_base.enonce2constlen; wb->enonce2varlen = proxy_base.enonce2varlen; + wb->diff = proxy_base.diff; ck_runlock(&workbase_lock); add_base(ckp, wb, &new_block); @@ -545,6 +546,29 @@ static void update_notify(ckpool_t *ckp) stratum_broadcast_update(new_block | clean); } +static void update_diff(ckpool_t *ckp) +{ + json_t *val; + double diff; + char *buf; + + buf = send_recv_proc(ckp->generator, "getdiff"); + if (unlikely(!buf)) { + LOGWARNING("Failed to get diff from generator in update_diff"); + return; + } + + LOGDEBUG("Update diff: %s", buf); + val = json_loads(buf, 0, NULL); + dealloc(buf); + json_dblcpy(&diff, val, "diff"); + json_decref(val); + + ck_wlock(&workbase_lock); + proxy_base.diff = diff; + ck_wunlock(&workbase_lock); +} + /* Enter with instance_lock held */ static stratum_instance_t *__instance_by_id(int id) { @@ -705,13 +729,12 @@ static int stratum_loop(ckpool_t *ckp, proc_instance_t *pi) char *buf = NULL; fd_set readfds; -reset: if (ckp->proxy) to = NULL; - else { - timeout.tv_sec = ckp->update_interval; + else to = &timeout; - } +reset: + timeout.tv_sec = ckp->update_interval; retry: FD_ZERO(&readfds); FD_SET(us->sockd, &readfds); @@ -764,11 +787,14 @@ retry: /* Proxifier has a new subscription */ if (!update_subscribe(ckp)) goto out; - goto reset; + goto retry; } else if (!strncasecmp(buf, "notify", 6)) { /* Proxifier has a new notify ready */ update_notify(ckp); - goto reset; + goto retry; + } else if (!strncasecmp(buf, "diff", 4)) { + update_diff(ckp); + goto retry; } else if (!strncasecmp(buf, "dropclient", 10)) { int client_id; @@ -874,7 +900,8 @@ static json_t *parse_subscribe(int client_id, json_t *params_val) if (buf && strlen(buf)) client->useragent = strdup(buf); if (arr_size > 1) { - /* This would be the session id for reconnect */ + /* This would be the session id for reconnect, it will + * not work for clients on a proxied connection. */ buf = json_string_value(json_array_get(params_val, 1)); LOGDEBUG("Found old session id %s", buf); /* Add matching here */