From dcfb734ec6d3bd3f253d12ba832650345f27f3ad Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 2 Jan 2017 14:43:19 +1100 Subject: [PATCH] Send upstream blocks to remote servers to be submitted locally. --- src/connector.c | 17 +------- src/stratifier.c | 103 ++++++++++++++++++++++++++++++++++------------- src/stratifier.h | 1 + 3 files changed, 77 insertions(+), 44 deletions(-) diff --git a/src/connector.c b/src/connector.c index e469e690..3cf780cf 100644 --- a/src/connector.c +++ b/src/connector.c @@ -1142,19 +1142,6 @@ out: free(buf); } -static void parse_remote_submitblock(ckpool_t *ckp, const json_t *val, const char *buf) -{ - const char *gbt_block = json_string_value(json_object_get(val, "submitblock")); - - if (unlikely(!gbt_block)) { - LOGWARNING("Failed to find submitblock data from upstream submitblock method %s", - buf); - return; - } - LOGWARNING("Submitting possible upstream block!"); - send_proc(ckp->generator, gbt_block); -} - static void ping_upstream(cdata_t *cdata) { char *buf; @@ -1212,8 +1199,8 @@ static void *urecv_process(void *arg) parse_upstream_auth(ckp, val); else if (!safecmp(method, stratum_msgs[SM_WORKINFO])) parse_upstream_workinfo(ckp, val); - else if (!safecmp(method, "submitblock")) - parse_remote_submitblock(ckp, val, cs->buf); + else if (!safecmp(method, stratum_msgs[SM_BLOCK])) + parse_upstream_block(ckp, val); else if (!safecmp(method, "pong")) LOGDEBUG("Received upstream pong"); else diff --git a/src/stratifier.c b/src/stratifier.c index 364615e7..23d5446e 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -5578,6 +5578,63 @@ static void add_submit(ckpool_t *ckp, stratum_instance_t *client, const double d stratum_send_diff(sdata, client); } +static void add_remote_blockdata(ckpool_t *ckp, json_t *val, const int cblen, const char *coinbase, + const uchar *data) +{ + char *buf; + + json_set_string(val, "name", ckp->name); + json_set_int(val, "cblen", cblen); + buf = bin2hex(coinbase, cblen); + json_set_string(val, "coinbasehex", buf); + free(buf); + buf = bin2hex(data, 80); + json_set_string(val, "swaphex", buf); + free(buf); +} + +static void +downstream_block(ckpool_t *ckp, sdata_t *sdata, const json_t *val, const int cblen, + const char *coinbase, const uchar *data, int64_t client_id) +{ + json_t *block_val = json_deep_copy(val); + stratum_instance_t *client; + ckmsg_t *bulk_send = NULL; + int messages = 0; + + /* Strip unnecessary fields and add extra fields needed */ + strip_fields(ckp, block_val); + json_set_string(block_val, "method", stratum_msgs[SM_BLOCK]); + add_remote_blockdata(ckp, block_val, cblen, coinbase, data); + + ck_rlock(&sdata->instance_lock); + DL_FOREACH(sdata->remote_instances, client) { + ckmsg_t *client_msg; + json_t *json_msg; + smsg_t *msg; + + /* Don't send remote workinfo back to same remote */ + if (client->id == client_id) + continue; + json_msg = json_deep_copy(block_val); + client_msg = ckalloc(sizeof(ckmsg_t)); + msg = ckzalloc(sizeof(smsg_t)); + msg->json_msg = json_msg; + msg->client_id = client->id; + client_msg->data = msg; + DL_APPEND(bulk_send, client_msg); + messages++; + } + ck_runlock(&sdata->instance_lock); + + json_decref(block_val); + + if (bulk_send) { + LOGINFO("Sending block to %d remote servers", messages); + ssend_bulk_postpone(sdata, bulk_send, messages); + } +} + /* We should already be holding the workbase_lock. Needs to be entered with * client holding a ref count. */ static void @@ -5635,19 +5692,12 @@ test_blocksolve(const stratum_instance_t *client, const workbase_t *wb, const uc mutex_unlock(&sdata->block_lock); if (ckp->remote) { - char *buf; - - json_set_string(val, "name", ckp->name); - json_set_int(val, "cblen", cblen); - buf = bin2hex(coinbase, cblen); - json_set_string(val, "coinbasehex", buf); - free(buf); - buf = bin2hex(data, 80); - json_set_string(val, "swaphex", buf); - free(buf); + add_remote_blockdata(ckp, val, cblen, coinbase, data); upstream_json_msgtype(ckp, val, SM_BLOCK); - } else + } else { + downstream_block(ckp, sdata, val, cblen, coinbase, data, 0); ckdbq_add(ckp, ID_BLOCK, val); + } } /* Needs to be entered with client holding a ref count. */ @@ -6739,22 +6789,6 @@ static void parse_remote_workers(sdata_t *sdata, json_t *val, const char *buf) LOGDEBUG("Adding %d remote workers to user %s", workers, username); } -/* This is here to support older trusted nodes submitting blocks this way but - * we no longer do it. */ -static void parse_remote_blocksubmit(ckpool_t *ckp, json_t *val, const char *buf) -{ - char *gbt_block; - - json_strdup(&gbt_block, val, "submitblock"); - if (unlikely(!gbt_block)) { - LOGWARNING("Failed to get submitblock data from remote message %s", buf); - return; - } - LOGWARNING("Submitting possible downstream block!"); - generator_submitblock(ckp, gbt_block + 12); - free(gbt_block); -} - /* Attempt to submit a remote block locally by recreating it from its workinfo * in addition to sending it to ckdb */ static void parse_remote_block(ckpool_t *ckp, sdata_t *sdata, json_t *val, const char *buf) @@ -6818,6 +6852,9 @@ static void parse_remote_block(ckpool_t *ckp, sdata_t *sdata, json_t *val, const stratum_broadcast_message(sdata, msg); free(msg); out_add: + if (CKP_STANDALONE(ckp)) + return; + /* Make a duplicate for use by ckdbq_add */ val = json_deep_copy(val); remap_workinfo_id(sdata, val); @@ -6825,6 +6862,16 @@ out_add: ckdbq_add(ckp, ID_BLOCK, val); } +void parse_upstream_block(ckpool_t *ckp, json_t *val) +{ + char *buf; + sdata_t *sdata = ckp->sdata; + + buf = json_dumps(val, 0); + parse_remote_block(ckp, sdata, val, buf); + free(buf); +} + static void send_remote_pong(sdata_t *sdata, stratum_instance_t *client) { json_t *json_msg; @@ -6907,8 +6954,6 @@ static void parse_trusted_msg(ckpool_t *ckp, sdata_t *sdata, json_t *val, stratu parse_remote_block(ckp, sdata, val, buf); else if (!safecmp(method, "workers")) parse_remote_workers(sdata, val, buf); - else if (!safecmp(method, "submitblock")) - parse_remote_blocksubmit(ckp, val, buf); else if (!safecmp(method, "ping")) send_remote_pong(sdata, client); else diff --git a/src/stratifier.h b/src/stratifier.h index 6e32e6ff..ca2d1482 100644 --- a/src/stratifier.h +++ b/src/stratifier.h @@ -14,6 +14,7 @@ void parse_remote_txns(ckpool_t *ckp, const json_t *val); #define parse_upstream_txns(ckp, val) parse_remote_txns(ckp, val) void parse_upstream_auth(ckpool_t *ckp, json_t *val); void parse_upstream_workinfo(ckpool_t *ckp, json_t *val); +void parse_upstream_block(ckpool_t *ckp, json_t *val); char *stratifier_stats(ckpool_t *ckp, void *data); void stratifier_add_recv(ckpool_t *ckp, json_t *val); void stratifier_block_solve(ckpool_t *ckp, const char *blockhash);