|
|
@ -1664,6 +1664,39 @@ static bool parse_diff(struct pool *pool, json_t *val) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static bool parse_extranonce(struct pool *pool, json_t *val) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char s[RBUFSIZE], *nonce1; |
|
|
|
|
|
|
|
int n2size; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nonce1 = json_array_string(val, 0); |
|
|
|
|
|
|
|
if (!nonce1) { |
|
|
|
|
|
|
|
// applog(LOG_INFO, "Failed to get nonce1 in ");
|
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
n2size = json_integer_value(json_array_get(val, 1)); |
|
|
|
|
|
|
|
if (!n2size) { |
|
|
|
|
|
|
|
// applog(LOG_INFO, "Failed to get n2size in ");
|
|
|
|
|
|
|
|
free(nonce1); |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cg_wlock(&pool->data_lock); |
|
|
|
|
|
|
|
pool->nonce1 = nonce1; |
|
|
|
|
|
|
|
pool->n1_len = strlen(nonce1) / 2; |
|
|
|
|
|
|
|
free(pool->nonce1bin); |
|
|
|
|
|
|
|
pool->nonce1bin = (unsigned char *)calloc(pool->n1_len, 1); |
|
|
|
|
|
|
|
if (unlikely(!pool->nonce1bin)) |
|
|
|
|
|
|
|
quithere(1, "Failed to calloc pool->nonce1bin"); |
|
|
|
|
|
|
|
hex2bin(pool->nonce1bin, pool->nonce1, pool->n1_len); |
|
|
|
|
|
|
|
pool->n2size = n2size; |
|
|
|
|
|
|
|
cg_wunlock(&pool->data_lock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
applog(LOG_NOTICE, "%s coin change requested", get_pool_name(pool)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void __suspend_stratum(struct pool *pool) |
|
|
|
static void __suspend_stratum(struct pool *pool) |
|
|
|
{ |
|
|
|
{ |
|
|
|
clear_sockbuf(pool); |
|
|
|
clear_sockbuf(pool); |
|
|
@ -1807,6 +1840,12 @@ bool parse_method(struct pool *pool, char *s) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!strncasecmp(buf, "mining.set_extranonce", 21) && parse_extranonce(pool, params)) { |
|
|
|
|
|
|
|
ret = true; |
|
|
|
|
|
|
|
json_decref(val); |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!strncasecmp(buf, "client.reconnect", 16) && parse_reconnect(pool, params)) { |
|
|
|
if (!strncasecmp(buf, "client.reconnect", 16) && parse_reconnect(pool, params)) { |
|
|
|
ret = true; |
|
|
|
ret = true; |
|
|
|
json_decref(val); |
|
|
|
json_decref(val); |
|
|
@ -1828,6 +1867,70 @@ bool parse_method(struct pool *pool, char *s) |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool subscribe_extranonce(struct pool *pool) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
json_t *val = NULL, *res_val, *err_val; |
|
|
|
|
|
|
|
char s[RBUFSIZE], *sret = NULL; |
|
|
|
|
|
|
|
json_error_t err; |
|
|
|
|
|
|
|
bool ret = false; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sprintf(s, "{\"id\": %d, \"method\": \"mining.extranonce.subscribe\", \"params\": []}", |
|
|
|
|
|
|
|
swork_id++); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!stratum_send(pool, s, strlen(s))) |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Parse all data in the queue and anything left should be auth */ |
|
|
|
|
|
|
|
while (42) { |
|
|
|
|
|
|
|
if (!socket_full(pool, DEFAULT_SOCKWAIT / 30)) { |
|
|
|
|
|
|
|
applog(LOG_DEBUG, "Timed out waiting for response extranonce.subscribe"); |
|
|
|
|
|
|
|
/* some pool doesnt send anything, so this is normal */ |
|
|
|
|
|
|
|
ret = true; |
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sret = recv_line(pool); |
|
|
|
|
|
|
|
if (!sret) |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
if (parse_method(pool, sret)) |
|
|
|
|
|
|
|
free(sret); |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val = JSON_LOADS(sret, &err); |
|
|
|
|
|
|
|
free(sret); |
|
|
|
|
|
|
|
res_val = json_object_get(val, "result"); |
|
|
|
|
|
|
|
err_val = json_object_get(val, "error"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!res_val || json_is_false(res_val) || (err_val && !json_is_null(err_val))) { |
|
|
|
|
|
|
|
char *ss; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (err_val) { |
|
|
|
|
|
|
|
ss = (char *)json_string_value(json_array_get(err_val, 1)); |
|
|
|
|
|
|
|
if (opt_extranonce_subscribe && strcmp(ss, "Method 'subscribe' not found for service 'mining.extranonce'") == 0) { |
|
|
|
|
|
|
|
applog(LOG_INFO, "Cannot subscribe to mining.extranonce on %s", get_pool_name(pool)); |
|
|
|
|
|
|
|
ret = true; |
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ss = json_dumps(err_val, JSON_INDENT(3)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
ss = strdup("(unknown reason)"); |
|
|
|
|
|
|
|
applog(LOG_INFO, "%s JSON stratum auth failed: %s", get_pool_name(pool), ss); |
|
|
|
|
|
|
|
free(ss); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret = true; |
|
|
|
|
|
|
|
applog(LOG_INFO, "Stratum extranonce subscribe for %s", get_pool_name(pool)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
out: |
|
|
|
|
|
|
|
json_decref(val); |
|
|
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool auth_stratum(struct pool *pool) |
|
|
|
bool auth_stratum(struct pool *pool) |
|
|
|
{ |
|
|
|
{ |
|
|
|
json_t *val = NULL, *res_val, *err_val; |
|
|
|
json_t *val = NULL, *res_val, *err_val; |
|
|
@ -2458,6 +2561,8 @@ bool restart_stratum(struct pool *pool) |
|
|
|
suspend_stratum(pool); |
|
|
|
suspend_stratum(pool); |
|
|
|
if (!initiate_stratum(pool)) |
|
|
|
if (!initiate_stratum(pool)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
if (opt_extranonce_subscribe && !subscribe_extranonce(pool)) |
|
|
|
|
|
|
|
return false; |
|
|
|
if (!auth_stratum(pool)) |
|
|
|
if (!auth_stratum(pool)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
|