diff --git a/src/generator.c b/src/generator.c index b3fdbd36..b818df38 100644 --- a/src/generator.c +++ b/src/generator.c @@ -30,6 +30,7 @@ struct notify_instance { char *jobid; char *coinbase1; char *coinbase2; + int coinb1len; int merkles; char merklehash[16][68]; char nbit[12]; @@ -428,9 +429,17 @@ static json_t *json_result(json_t *val) return res_val; } +/* Return the error value if one exists */ +static json_t *json_errval(json_t *val) +{ + json_t *err_val = json_object_get(val, "error"); + + return err_val; +} + /* Parse a string and return the json value it contains, if any, and the * result in res_val. Return NULL if no result key is found. */ -static json_t *json_msg_result(char *msg, json_t **res_val) +static json_t *json_msg_result(char *msg, json_t **res_val, json_t **err_val) { json_error_t err; json_t *val; @@ -442,11 +451,7 @@ static json_t *json_msg_result(char *msg, json_t **res_val) goto out; } *res_val = json_result(val); - if (!*res_val) { - LOGWARNING("No json result found"); - json_decref(val); - val = NULL; - } + *err_val = json_errval(val); out: return val; @@ -491,8 +496,9 @@ static bool parse_subscribe(connsock_t *cs, proxy_instance_t *proxi) goto out; } LOGDEBUG("parse_subscribe received %s", cs->buf); - val = json_msg_result(cs->buf, &res_val); - if (!val) { + /* Ignore err_val here stored in &tmp */ + val = json_msg_result(cs->buf, &res_val, &tmp); + if (!val || !res_val) { LOGWARNING("Failed to get a json result in parse_subscribe, got: %s", cs->buf); goto out; } @@ -526,10 +532,6 @@ static bool parse_subscribe(connsock_t *cs, proxy_instance_t *proxi) goto out; } string = json_string_value(tmp); - if (strlen(string) < 1) { - LOGWARNING("Invalid string length for enonce1 in parse_subscribe"); - goto out; - } old = proxi->enonce1; proxi->enonce1 = strdup(string); free(old); @@ -632,7 +634,7 @@ out: static bool passthrough_stratum(connsock_t *cs, proxy_instance_t *proxi) { - json_t *req, *val = NULL, *res_val; + json_t *req, *val = NULL, *res_val, *err_val; bool ret = false; JSON_CPACK(req, "{s:s,s:[s]}", @@ -648,8 +650,10 @@ static bool passthrough_stratum(connsock_t *cs, proxy_instance_t *proxi) LOGWARNING("Failed to receive line in passthrough_stratum"); goto out; } - val = json_msg_result(cs->buf, &res_val); - if (!val) { + /* Ignore err_val here since we should always get a result from an + * upstream passthrough server */ + val = json_msg_result(cs->buf, &res_val, &err_val); + if (!val || !res_val) { LOGWARNING("Failed to get a json result in passthrough_stratum, got: %s", cs->buf); goto out; @@ -706,6 +710,7 @@ static bool parse_notify(proxy_instance_t *proxi, json_t *val) LOGDEBUG("Job ID %s", job_id); ni->coinbase1 = coinbase1; LOGDEBUG("Coinbase1 %s", coinbase1); + ni->coinb1len = strlen(coinbase1) / 2; ni->coinbase2 = coinbase2; LOGDEBUG("Coinbase2 %s", coinbase2); memcpy(ni->prevhash, prev_hash, 65); @@ -916,7 +921,7 @@ out: static bool auth_stratum(connsock_t *cs, proxy_instance_t *proxi) { - json_t *val = NULL, *res_val, *req; + json_t *val = NULL, *res_val, *req, *err_val; bool ret; JSON_CPACK(req, "{s:i,s:s,s:[s,s]}", @@ -945,17 +950,26 @@ static bool auth_stratum(connsock_t *cs, proxy_instance_t *proxi) ret = parse_method(proxi, cs->buf); } while (ret); - val = json_msg_result(cs->buf, &res_val); + val = json_msg_result(cs->buf, &res_val, &err_val); if (!val) { LOGWARNING("Failed to get a json result in auth_stratum, got: %s", cs->buf); goto out; } - ret = json_is_true(res_val); - if (!ret) { - LOGWARNING("Failed to authorise in auth_stratum"); + if (err_val && !json_is_null(err_val)) { + LOGWARNING("Failed to authorise in auth_stratum due to err_val, got: %s", cs->buf); goto out; } + if (res_val) { + ret = json_is_true(res_val); + if (!ret) { + LOGWARNING("Failed to authorise in auth_stratum"); + goto out; + } + } else { + /* No result and no error but successful val means auth success */ + ret = true; + } LOGINFO("Auth success in auth_stratum"); out: if (val) @@ -991,8 +1005,8 @@ static void send_notify(proxy_instance_t *proxi, int sockd) for (i = 0; i < ni->merkles; i++) json_array_append_new(merkle_arr, json_string(&ni->merklehash[i][0])); /* Use our own jobid instead of the server's one for easy lookup */ - JSON_CPACK(json_msg, "{sisssssssosssssssb}", - "jobid", ni->id, "prevhash", ni->prevhash, + JSON_CPACK(json_msg, "{si,ss,si,ss,ss,so,ss,ss,ss,sb}", + "jobid", ni->id, "prevhash", ni->prevhash, "coinb1len", ni->coinb1len, "coinbase1", ni->coinbase1, "coinbase2", ni->coinbase2, "merklehash", merkle_arr, "bbversion", ni->bbversion, "nbit", ni->nbit, "ntime", ni->ntime, diff --git a/src/stratifier.c b/src/stratifier.c index be03f2fb..0e697a18 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -112,8 +112,8 @@ struct workbase { json_t *merkle_array; /* Template variables, lengths are binary lengths! */ - char coinb1[256]; // coinbase1 - uchar coinb1bin[128]; + char *coinb1; // coinbase1 + uchar *coinb1bin; int coinb1len; // length of above char enonce1const[32]; // extranonce1 section that is constant @@ -306,6 +306,10 @@ static void generate_coinbase(ckpool_t *ckp, workbase_t *wb) int len, ofs = 0; ts_t now; + /* Set fixed length coinb1 arrays to be more than enough */ + wb->coinb1 = ckzalloc(256); + wb->coinb1bin = ckzalloc(128); + /* Strings in wb should have been zero memset prior. Generate binary * templates first, then convert to hex */ memcpy(wb->coinb1bin, scriptsig_header_bin, 41); @@ -418,6 +422,8 @@ static void clear_workbase(workbase_t *wb) free(wb->txn_data); free(wb->txn_hashes); free(wb->logdir); + free(wb->coinb1bin); + free(wb->coinb1); free(wb->coinb2bin); free(wb->coinb2); json_decref(wb->merkle_array); @@ -797,8 +803,10 @@ static void update_notify(ckpool_t *ckp) json_int64cpy(&wb->id, val, "jobid"); json_strcpy(wb->prevhash, val, "prevhash"); + json_intcpy(&wb->coinb1len, val, "coinb1len"); + wb->coinb1bin = ckalloc(wb->coinb1len); + wb->coinb1 = ckalloc(wb->coinb1len * 2 + 1); json_strcpy(wb->coinb1, val, "coinbase1"); - wb->coinb1len = strlen(wb->coinb1) / 2; hex2bin(wb->coinb1bin, wb->coinb1, wb->coinb1len); wb->height = get_sernumber(wb->coinb1bin + 42); json_strdup(&wb->coinb2, val, "coinbase2");