From 6e70908b30c18bd044dec1adffe78be53d9c11e3 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 27 Jan 2016 19:44:23 +1100 Subject: [PATCH] Set a bkey bool on connecting remote/node/passthroughs flagging them capable of receiving bkey data --- src/connector.c | 26 +++++++++++++++++++++++--- src/generator.c | 6 ++++-- src/stratifier.c | 44 +++++++++++++++++++++++++++++++++++--------- 3 files changed, 62 insertions(+), 14 deletions(-) diff --git a/src/connector.c b/src/connector.c index 54ae59f5..69f0d3a3 100644 --- a/src/connector.c +++ b/src/connector.c @@ -78,6 +78,9 @@ struct client_instance { /* The size of the socket send buffer */ int sendbufsize; + + /* Does this client accept bkeys */ + bool bkey; }; struct sender_send { @@ -989,7 +992,7 @@ static void passthrough_client(ckpool_t *ckp, cdata_t *cdata, client_instance_t LOGINFO("Connector adding passthrough client %"PRId64, client->id); client->passthrough = true; - ASPRINTF(&buf, "{\"result\": true}\n"); + ASPRINTF(&buf, "{\"result\":true,\"bkey\":true}\n"); send_client(cdata, client->id, buf); if (!ckp->rmem_warn) set_recvbufsize(ckp, client->fd, 1048576); @@ -1004,7 +1007,7 @@ static void remote_server(ckpool_t *ckp, cdata_t *cdata, client_instance_t *clie LOGWARNING("Connector adding client %"PRId64" %s as remote trusted server", client->id, client->address_name); client->remote = true; - ASPRINTF(&buf, "{\"result\": true}\n"); + ASPRINTF(&buf, "{\"result\":true,\"bkey\":true}\n"); send_client(cdata, client->id, buf); if (!ckp->rmem_warn) set_recvbufsize(ckp, client->fd, 1048576); @@ -1028,8 +1031,9 @@ static bool connect_upstream(ckpool_t *ckp, connsock_t *cs) if (!ckp->wmem_warn) cs->sendbufsiz = set_sendbufsize(ckp, cs->fd, 1048576); - JSON_CPACK(req, "{ss,s[s]}", + JSON_CPACK(req, "{ss,sb,s[s]}", "method", "mining.remote", + "bkey", true, "params", PACKAGE"/"VERSION); res = send_json_msg(cs, req); json_decref(req); @@ -1435,6 +1439,22 @@ retry: } remote_server(ckp, cdata, client); dec_instance_ref(cdata, client); + } else if (cmdmatch(buf, "bkeyclient")) { + client_instance_t *client; + + ret = sscanf(buf, "bkeyclient=%"PRId64, &client_id); + if (ret < 0) { + LOGDEBUG("Connector failed to parse bkeyclient command: %s", buf); + goto retry; + } + client = ref_client_by_id(cdata, client_id); + if (unlikely(!client)) { + LOGINFO("Connector failed to find client id %"PRId64" to set bkey", client_id); + goto retry; + } + LOGINFO("Set bkey on client %"PRId64, client_id); + client->bkey = true; + dec_instance_ref(cdata, client); } else if (cmdmatch(buf, "getxfd")) { int fdno = -1; diff --git a/src/generator.c b/src/generator.c index f5fa7f2d..35d3e11e 100644 --- a/src/generator.c +++ b/src/generator.c @@ -705,8 +705,9 @@ static bool passthrough_stratum(connsock_t *cs, proxy_instance_t *proxi) bool res, ret = false; float timeout = 10; - JSON_CPACK(req, "{ss,s[s]}", + JSON_CPACK(req, "{ss,sb,s[s]}", "method", "mining.passthrough", + "bkey", true, "params", PACKAGE"/"VERSION); res = send_json_msg(cs, req); json_decref(req); @@ -747,8 +748,9 @@ static bool node_stratum(connsock_t *cs, proxy_instance_t *proxi) bool res, ret = false; float timeout = 10; - JSON_CPACK(req, "{ss,s[s]}", + JSON_CPACK(req, "{ss,sb,s[s]}", "method", "mining.node", + "bkey", true, "params", PACKAGE"/"VERSION); res = send_json_msg(cs, req); diff --git a/src/stratifier.c b/src/stratifier.c index b1543e7e..c0bda047 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -313,6 +313,7 @@ struct stratum_instance { int subproxyid; /* Which subproxy */ bool remote; /* Is this a trusted remote server */ + bool bkey; /* Does this client accept bkeys */ }; struct share { @@ -5624,10 +5625,11 @@ static void add_remote_server(sdata_t *sdata, stratum_instance_t *client) /* Enter with client holding ref count */ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *client, - const int64_t client_id, json_t *id_val, json_t *method_val, - json_t *params_val) + const int64_t client_id, const json_t *val, json_t *id_val, + json_t *method_val, json_t *params_val) { const char *method; + json_t *bkey_val; char buf[256]; /* Random broken clients send something not an integer as the id so we @@ -5648,7 +5650,7 @@ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *clie } if (cmdmatch(method, "mining.subscribe")) { - json_t *val, *result_val; + json_t *sval, *result_val; if (unlikely(client->subscribed)) { LOGNOTICE("Client %"PRId64" %s trying to subscribe twice", @@ -5661,11 +5663,11 @@ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *clie LOGWARNING("parse_subscribe returned NULL result_val"); return; } - val = json_object(); - json_object_set_new_nocheck(val, "result", result_val); - json_object_set_nocheck(val, "id", id_val); - json_object_set_new_nocheck(val, "error", json_null()); - stratum_add_send(sdata, val, client_id, SM_SUBSCRIBERESULT); + sval = json_object(); + json_object_set_new_nocheck(sval, "result", result_val); + json_object_set_nocheck(sval, "id", id_val); + json_object_set_new_nocheck(sval, "error", json_null()); + stratum_add_send(sdata, sval, client_id, SM_SUBSCRIBERESULT); if (likely(client->subscribed)) init_client(sdata, client, client_id); return; @@ -5679,6 +5681,14 @@ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *clie client_id, client->address, client->server); connector_drop_client(ckp, client_id); } else { + bkey_val = json_object_get(val, "bkey"); + if (bkey_val) { + client->bkey = json_is_true(bkey_val); + if (client->bkey) { + snprintf(buf, 255, "bkeyclient=%"PRId64, client_id); + send_proc(ckp->connector, buf); + } + } add_remote_server(sdata, client); snprintf(buf, 255, "remote=%"PRId64, client_id); send_proc(ckp->connector, buf); @@ -5695,6 +5705,14 @@ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *clie connector_drop_client(ckp, client_id); drop_client(ckp, sdata, client_id); } else { + bkey_val = json_object_get(val, "bkey"); + if (bkey_val) { + client->bkey = json_is_true(bkey_val); + if (client->bkey) { + snprintf(buf, 255, "bkeyclient=%"PRId64, client_id); + send_proc(ckp->connector, buf); + } + } add_mining_node(ckp, sdata, client); snprintf(buf, 255, "passthrough=%"PRId64, client_id); send_proc(ckp->connector, buf); @@ -5713,6 +5731,14 @@ static void parse_method(ckpool_t *ckp, sdata_t *sdata, stratum_instance_t *clie * is a passthrough and to manage its messages accordingly. No * data from this client id should ever come back to this * stratifier after this so drop the client in the stratifier. */ + bkey_val = json_object_get(val, "bkey"); + if (bkey_val) { + client->bkey = json_is_true(bkey_val); + if (client->bkey) { + snprintf(buf, 255, "bkeyclient=%"PRId64, client_id); + send_proc(ckp->connector, buf); + } + } LOGNOTICE("Adding passthrough client %"PRId64" %s", client_id, client->address); snprintf(buf, 255, "passthrough=%"PRId64, client_id); send_proc(ckp->connector, buf); @@ -6158,7 +6184,7 @@ static void parse_instance_msg(ckpool_t *ckp, sdata_t *sdata, smsg_t *msg, strat if (!(++delays % 50)) LOGWARNING("%d Second delay waiting for bitcoind at startup", delays / 10); } - parse_method(ckp, sdata, client, client_id, id_val, method, params); + parse_method(ckp, sdata, client, client_id, val, id_val, method, params); } static void srecv_process(ckpool_t *ckp, char *buf)