Browse Source

Propagate workinfo and blocks to all connected nodes as well allowing complex mixed remote server and node infrastructures.

master
Con Kolivas 8 years ago
parent
commit
be33c087b9
  1. 107
      src/stratifier.c

107
src/stratifier.c

@ -958,8 +958,7 @@ static void send_node_workinfo(ckpool_t *ckp, sdata_t *sdata, const workbase_t *
wb_val = json_object(); wb_val = json_object();
ck_rlock(&sdata->instance_lock); json_set_int(wb_val, "jobid", wb->mapped_id);
json_set_int(wb_val, "jobid", wb->id);
json_set_string(wb_val, "target", wb->target); json_set_string(wb_val, "target", wb->target);
json_set_double(wb_val, "diff", wb->diff); json_set_double(wb_val, "diff", wb->diff);
json_set_int(wb_val, "version", wb->version); json_set_int(wb_val, "version", wb->version);
@ -982,6 +981,7 @@ static void send_node_workinfo(ckpool_t *ckp, sdata_t *sdata, const workbase_t *
json_set_int(wb_val, "coinb2len", wb->coinb2len); json_set_int(wb_val, "coinb2len", wb->coinb2len);
json_set_string(wb_val, "coinb2", wb->coinb2); json_set_string(wb_val, "coinb2", wb->coinb2);
ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->node_instances, client) { DL_FOREACH(sdata->node_instances, client) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
smsg_t *msg; smsg_t *msg;
@ -1103,7 +1103,7 @@ static void add_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb, bool *new_bl
ck_wlock(&sdata->workbase_lock); ck_wlock(&sdata->workbase_lock);
ckp_sdata->workbases_generated++; ckp_sdata->workbases_generated++;
if (!ckp->proxy) if (!ckp->proxy)
wb->id = sdata->workbase_id++; wb->mapped_id = wb->id = sdata->workbase_id++;
else else
sdata->workbase_id = wb->id; sdata->workbase_id = wb->id;
if (strncmp(wb->prevhash, sdata->lasthash, 64)) { if (strncmp(wb->prevhash, sdata->lasthash, 64)) {
@ -1798,8 +1798,12 @@ static void check_incomplete_wbs(ckpool_t *ckp, sdata_t *sdata)
static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb) static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
{ {
stratum_instance_t *client;
ckmsg_t *bulk_send = NULL;
workbase_t *tmp, *tmpa; workbase_t *tmp, *tmpa;
json_t *val; json_t *val, *wb_val;
int messages = 0;
int64_t skip;
ts_realtime(&wb->gentime); ts_realtime(&wb->gentime);
@ -1832,13 +1836,7 @@ static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
/* Replace jobid with mapped id */ /* Replace jobid with mapped id */
json_set_int64(val, "jobid", wb->mapped_id); json_set_int64(val, "jobid", wb->mapped_id);
/* If this is the upstream pool, send a copy of this to all OTHER remote wb_val = json_deep_copy(val);
* trusted servers as well */
if (!ckp->remote) {
json_t *wb_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 unnecessary fields and add extra fields needed */
strip_fields(ckp, wb_val); strip_fields(ckp, wb_val);
@ -1846,13 +1844,16 @@ static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
json_set_string(wb_val, "txn_hashes", wb->txn_hashes); json_set_string(wb_val, "txn_hashes", wb->txn_hashes);
json_set_int(wb_val, "merkles", wb->merkles); json_set_int(wb_val, "merkles", wb->merkles);
skip = subclient(wb->client_id);
/* Send a copy of this to all OTHER remote trusted servers as well */
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
DL_FOREACH(sdata->remote_instances, client) { DL_FOREACH(sdata->remote_instances, client) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
json_t *json_msg; json_t *json_msg;
smsg_t *msg; smsg_t *msg;
/* Don't send remote workinfo back to same remote */ /* Don't send remote workinfo back to the source remote */
if (client->id == wb->client_id) if (client->id == wb->client_id)
continue; continue;
json_msg = json_deep_copy(wb_val); json_msg = json_deep_copy(wb_val);
@ -1865,6 +1866,24 @@ static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
DL_APPEND(bulk_send, client_msg); DL_APPEND(bulk_send, client_msg);
messages++; messages++;
} }
DL_FOREACH(sdata->node_instances, client) {
ckmsg_t *client_msg;
json_t *json_msg;
smsg_t *msg;
/* Don't send node workinfo back to the source node */
if (client->id == skip)
continue;
json_msg = json_deep_copy(wb_val);
json_set_string(json_msg, "node.method", stratum_msgs[SM_WORKINFO]);
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); ck_runlock(&sdata->instance_lock);
json_decref(wb_val); json_decref(wb_val);
@ -1873,7 +1892,6 @@ static void add_remote_base(ckpool_t *ckp, sdata_t *sdata, workbase_t *wb)
LOGINFO("Sending remote workinfo to %d other remote servers", messages); LOGINFO("Sending remote workinfo to %d other remote servers", messages);
ssend_bulk_postpone(sdata, bulk_send, messages); ssend_bulk_postpone(sdata, bulk_send, messages);
} }
}
ckdbq_add(ckp, ID_WORKINFO, val); ckdbq_add(ckp, ID_WORKINFO, val);
} }
@ -2022,32 +2040,20 @@ static void add_remote_blockdata(ckpool_t *ckp, json_t *val, const int cblen, co
free(buf); free(buf);
} }
/* Entered with workbase readcount, grabs instance lock */ /* Entered with workbase readcount, grabs instance_lock. client_id is where the
static void send_node_block(ckpool_t *ckp, sdata_t *sdata, const char *enonce1, const char *nonce, * block originated. */
const char *nonce2, const uint32_t ntime32, const int64_t jobid, static void send_nodes_block(sdata_t *sdata, const json_t *block_val, const int64_t client_id)
const double diff, const int64_t client_id,
const char *coinbase, const int cblen, const uchar *data)
{ {
stratum_instance_t *client; stratum_instance_t *client;
int64_t skip, messages = 0;
ckmsg_t *bulk_send = NULL; ckmsg_t *bulk_send = NULL;
int messages = 0;
int64_t skip;
/* Don't send the block back to a remote node if that's where it was /* Don't send the block back to a remote node if that's where it was
* found. */ * found. */
skip = subclient(client_id); skip = subclient(client_id);
ck_rlock(&sdata->instance_lock); ck_rlock(&sdata->instance_lock);
if (sdata->node_instances) {
json_t *val = json_object();
json_set_string(val, "node.method", stratum_msgs[SM_BLOCK]);
json_set_string(val, "enonce1", enonce1);
json_set_string(val, "nonce", nonce);
json_set_string(val, "nonce2", nonce2);
json_set_uint32(val, "ntime32", ntime32);
json_set_int64(val, "jobid", jobid);
json_set_double(val, "diff", diff);
add_remote_blockdata(ckp, val, cblen, coinbase, data);
DL_FOREACH(sdata->node_instances, client) { DL_FOREACH(sdata->node_instances, client) {
ckmsg_t *client_msg; ckmsg_t *client_msg;
json_t *json_msg; json_t *json_msg;
@ -2055,7 +2061,8 @@ static void send_node_block(ckpool_t *ckp, sdata_t *sdata, const char *enonce1,
if (client->id == skip) if (client->id == skip)
continue; continue;
json_msg = json_deep_copy(val); json_msg = json_deep_copy(block_val);
json_set_string(json_msg, "node.method", stratum_msgs[SM_BLOCK]);
client_msg = ckalloc(sizeof(ckmsg_t)); client_msg = ckalloc(sizeof(ckmsg_t));
msg = ckzalloc(sizeof(smsg_t)); msg = ckzalloc(sizeof(smsg_t));
msg->json_msg = json_msg; msg->json_msg = json_msg;
@ -2064,14 +2071,35 @@ static void send_node_block(ckpool_t *ckp, sdata_t *sdata, const char *enonce1,
DL_APPEND(bulk_send, client_msg); DL_APPEND(bulk_send, client_msg);
messages++; messages++;
} }
json_decref(val);
}
ck_runlock(&sdata->instance_lock); ck_runlock(&sdata->instance_lock);
if (bulk_send) { if (bulk_send) {
LOGNOTICE("Sending block to mining nodes"); LOGNOTICE("Sending block to %d mining nodes", messages);
ssend_bulk_prepend(sdata, bulk_send, messages); ssend_bulk_prepend(sdata, bulk_send, messages);
} }
}
/* Entered with workbase readcount. */
static void send_node_block(ckpool_t *ckp, sdata_t *sdata, const char *enonce1, const char *nonce,
const char *nonce2, const uint32_t ntime32, const int64_t jobid,
const double diff, const int64_t client_id,
const char *coinbase, const int cblen, const uchar *data)
{
if (sdata->node_instances) {
json_t *val = json_object();
json_set_string(val, "enonce1", enonce1);
json_set_string(val, "nonce", nonce);
json_set_string(val, "nonce2", nonce2);
json_set_uint32(val, "ntime32", ntime32);
json_set_int64(val, "jobid", jobid);
json_set_double(val, "diff", diff);
add_remote_blockdata(ckp, val, cblen, coinbase, data);
send_nodes_block(sdata, val, client_id);
json_decref(val);
}
} }
/* Process a block into a message for the generator to submit. Must hold /* Process a block into a message for the generator to submit. Must hold
@ -2237,9 +2265,6 @@ static void submit_node_block(ckpool_t *ckp, sdata_t *sdata, json_t *val)
LOGWARNING("Failed to find workbase with jobid %"PRId64" in node method block", id); LOGWARNING("Failed to find workbase with jobid %"PRId64" in node method block", id);
goto out; goto out;
} }
enonce1len = wb->enonce1constlen + wb->enonce1varlen;
enonce1bin = alloca(enonce1len);
hex2bin(enonce1bin, enonce1, enonce1len);
/* Get parameters if upstream pool supports them with new format */ /* Get parameters if upstream pool supports them with new format */
json_get_string(&coinbasehex, val, "coinbasehex"); json_get_string(&coinbasehex, val, "coinbasehex");
@ -2256,6 +2281,9 @@ static void submit_node_block(ckpool_t *ckp, sdata_t *sdata, json_t *val)
} else { } else {
/* Rebuild the old way if we can if the upstream pool is using /* Rebuild the old way if we can if the upstream pool is using
* the old format only */ * the old format only */
enonce1len = wb->enonce1constlen + wb->enonce1varlen;
enonce1bin = alloca(enonce1len);
hex2bin(enonce1bin, enonce1, enonce1len);
coinbase = alloca(wb->coinb1len + wb->enonce1constlen + wb->enonce1varlen + wb->enonce2varlen + wb->coinb2len); coinbase = alloca(wb->coinb1len + wb->enonce1constlen + wb->enonce1varlen + wb->enonce2varlen + wb->coinb2len);
/* Fill in the hashes */ /* Fill in the hashes */
share_diff(coinbase, enonce1bin, wb, nonce2, ntime32, nonce, hash, swap, &cblen); share_diff(coinbase, enonce1bin, wb, nonce2, ntime32, nonce, hash, swap, &cblen);
@ -5889,7 +5917,6 @@ test_blocksolve(const stratum_instance_t *client, const workbase_t *wb, const uc
diff, client->id, coinbase, cblen, data); diff, client->id, coinbase, cblen, data);
val = json_object(); val = json_object();
// JSON_CPACK(val, "{si,ss,ss,sI,ss,ss,sI,ss,ss,ss,sI,sf,ss,ss,ss,ss}",
json_set_int(val, "height", wb->height); json_set_int(val, "height", wb->height);
json_set_string(val,"blockhash", blockhash); json_set_string(val,"blockhash", blockhash);
json_set_string(val,"confirmed", "n"); json_set_string(val,"confirmed", "n");
@ -5903,6 +5930,7 @@ test_blocksolve(const stratum_instance_t *client, const workbase_t *wb, const uc
json_set_string(val, "enonce1", client->enonce1); json_set_string(val, "enonce1", client->enonce1);
json_set_string(val, "nonce2", nonce2); json_set_string(val, "nonce2", nonce2);
json_set_string(val, "nonce", nonce); json_set_string(val, "nonce", nonce);
json_set_uint32(val, "ntime32", ntime32);
json_set_int64(val, "reward", wb->coinbasevalue); json_set_int64(val, "reward", wb->coinbasevalue);
json_set_double(val, "diff", diff); json_set_double(val, "diff", diff);
json_set_string(val, "createdate", cdfield); json_set_string(val, "createdate", cdfield);
@ -7084,6 +7112,9 @@ static void parse_remote_block(ckpool_t *ckp, sdata_t *sdata, json_t *val, const
sha256(swap, 80, hash1); sha256(swap, 80, hash1);
sha256(hash1, 32, hash); sha256(hash1, 32, hash);
gbt_block = process_block(wb, coinbase, cblen, swap, hash, flip32, blockhash); gbt_block = process_block(wb, coinbase, cblen, swap, hash, flip32, blockhash);
/* Note nodes use jobid of the mapped_id instead of workinfoid */
json_set_int64(val, "jobid", wb->mapped_id);
send_nodes_block(sdata, val, client_id);
/* We rely on the remote server to give us the ID_BLOCK /* We rely on the remote server to give us the ID_BLOCK
* responses, so only use this response to determine if we * responses, so only use this response to determine if we
* should reset the best shares. */ * should reset the best shares. */

Loading…
Cancel
Save