stratum: handle optional mining.set_extranonce
allow pools to switch more coins without reconnect Tested ok on a nicehash x11 pool Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
This commit is contained in:
parent
26b9fe3586
commit
5ddc8de9da
110
util.cpp
110
util.cpp
@ -906,11 +906,53 @@ static const char *get_stratum_session_id(json_t *val)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool stratum_parse_extranonce(struct stratum_ctx *sctx, json_t *params, int pndx)
|
||||||
|
{
|
||||||
|
const char* xnonce1;
|
||||||
|
int xn2_size;
|
||||||
|
|
||||||
|
xnonce1 = json_string_value(json_array_get(params, pndx));
|
||||||
|
if (!xnonce1) {
|
||||||
|
applog(LOG_ERR, "Failed to get extranonce1");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
xn2_size = json_integer_value(json_array_get(params, pndx+1));
|
||||||
|
if (!xn2_size) {
|
||||||
|
applog(LOG_ERR, "Failed to get extranonce2_size");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (xn2_size < 2 || xn2_size > 16) {
|
||||||
|
applog(LOG_INFO, "Failed to get valid n2size in parse_extranonce");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&sctx->work_lock);
|
||||||
|
if (sctx->xnonce1)
|
||||||
|
free(sctx->xnonce1);
|
||||||
|
sctx->xnonce1_size = strlen(xnonce1) / 2;
|
||||||
|
sctx->xnonce1 = (uchar*) calloc(1, sctx->xnonce1_size);
|
||||||
|
if (unlikely(!sctx->xnonce1)) {
|
||||||
|
applog(LOG_ERR, "Failed to alloc xnonce1");
|
||||||
|
pthread_mutex_unlock(&sctx->work_lock);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
hex2bin(sctx->xnonce1, xnonce1, sctx->xnonce1_size);
|
||||||
|
sctx->xnonce2_size = xn2_size;
|
||||||
|
pthread_mutex_unlock(&sctx->work_lock);
|
||||||
|
|
||||||
|
if (pndx == 0 && opt_debug) /* pool dynamic change */
|
||||||
|
applog(LOG_DEBUG, "Stratum set nonce %s with extranonce2 size=%d",
|
||||||
|
xnonce1, xn2_size);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
out:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool stratum_subscribe(struct stratum_ctx *sctx)
|
bool stratum_subscribe(struct stratum_ctx *sctx)
|
||||||
{
|
{
|
||||||
char *s, *sret = NULL;
|
char *s, *sret = NULL;
|
||||||
const char *sid, *xnonce1;
|
const char *sid;
|
||||||
int xn2_size;
|
|
||||||
json_t *val = NULL, *res_val, *err_val;
|
json_t *val = NULL, *res_val, *err_val;
|
||||||
json_error_t err;
|
json_error_t err;
|
||||||
bool ret = false, retry = false;
|
bool ret = false, retry = false;
|
||||||
@ -927,7 +969,7 @@ start:
|
|||||||
if (!stratum_send_line(sctx, s))
|
if (!stratum_send_line(sctx, s))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!socket_full(sctx->sock, 30)) {
|
if (!socket_full(sctx->sock, 10)) {
|
||||||
applog(LOG_ERR, "stratum_subscribe timed out");
|
applog(LOG_ERR, "stratum_subscribe timed out");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -959,33 +1001,20 @@ start:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// session id
|
||||||
sid = get_stratum_session_id(res_val);
|
sid = get_stratum_session_id(res_val);
|
||||||
if (opt_debug && !sid)
|
if (opt_debug && sid)
|
||||||
applog(LOG_DEBUG, "Failed to get Stratum session id");
|
applog(LOG_DEBUG, "Stratum session id: %s", sid);
|
||||||
xnonce1 = json_string_value(json_array_get(res_val, 1));
|
|
||||||
if (!xnonce1) {
|
|
||||||
applog(LOG_ERR, "Failed to get extranonce1");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
xn2_size = json_integer_value(json_array_get(res_val, 2));
|
|
||||||
if (!xn2_size) {
|
|
||||||
applog(LOG_ERR, "Failed to get extranonce2_size");
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_lock(&sctx->work_lock);
|
pthread_mutex_lock(&sctx->work_lock);
|
||||||
free(sctx->session_id);
|
if (sctx->session_id)
|
||||||
free(sctx->xnonce1);
|
free(sctx->session_id);
|
||||||
sctx->session_id = sid ? strdup(sid) : NULL;
|
sctx->session_id = sid ? strdup(sid) : NULL;
|
||||||
sctx->xnonce1_size = strlen(xnonce1) / 2;
|
|
||||||
sctx->xnonce1 = (uchar*) malloc(sctx->xnonce1_size);
|
|
||||||
hex2bin(sctx->xnonce1, xnonce1, sctx->xnonce1_size);
|
|
||||||
sctx->xnonce2_size = xn2_size;
|
|
||||||
sctx->next_diff = 1.0;
|
sctx->next_diff = 1.0;
|
||||||
pthread_mutex_unlock(&sctx->work_lock);
|
pthread_mutex_unlock(&sctx->work_lock);
|
||||||
|
|
||||||
if (opt_debug && sid)
|
// sid is param 1, extranonce params are 2 and 3
|
||||||
applog(LOG_DEBUG, "Stratum session id: %s", sctx->session_id);
|
stratum_parse_extranonce(sctx, res_val, 1);
|
||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
@ -1034,6 +1063,9 @@ bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *p
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (json_integer_value(json_object_get(val, "id")) != 2) {
|
||||||
|
applog(LOG_WARNING, "Stratum answer id is not correct!");
|
||||||
|
}
|
||||||
res_val = json_object_get(val, "result");
|
res_val = json_object_get(val, "result");
|
||||||
err_val = json_object_get(val, "error");
|
err_val = json_object_get(val, "error");
|
||||||
|
|
||||||
@ -1045,6 +1077,34 @@ bool stratum_authorize(struct stratum_ctx *sctx, const char *user, const char *p
|
|||||||
|
|
||||||
ret = true;
|
ret = true;
|
||||||
|
|
||||||
|
// subscribe to extranonce (optional)
|
||||||
|
sprintf(s, "{\"id\": 3, \"method\": \"mining.extranonce.subscribe\", \"params\": []}");
|
||||||
|
|
||||||
|
if (!stratum_send_line(sctx, s))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (!socket_full(sctx->sock, 3)) {
|
||||||
|
applog(LOG_ERR, "stratum extranonce subscribe timed out");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
sret = stratum_recv_line(sctx);
|
||||||
|
if (sret) {
|
||||||
|
json_t *extra = JSON_LOADS(sret, &err);
|
||||||
|
free(sret);
|
||||||
|
if (!extra) {
|
||||||
|
applog(LOG_WARNING, "JSON decode failed(%d): %s", err.line, err.text);
|
||||||
|
} else {
|
||||||
|
if (json_integer_value(json_object_get(extra, "id")) != 3) {
|
||||||
|
applog(LOG_WARNING, "Stratum answer id is not correct!");
|
||||||
|
}
|
||||||
|
res_val = json_object_get(extra, "result");
|
||||||
|
if (opt_debug && (!res_val || json_is_false(res_val)))
|
||||||
|
applog(LOG_DEBUG, "extranonce subscribe not supported");
|
||||||
|
json_decref(extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free(s);
|
free(s);
|
||||||
if (val)
|
if (val)
|
||||||
@ -1304,6 +1364,10 @@ bool stratum_handle_method(struct stratum_ctx *sctx, const char *s)
|
|||||||
ret = stratum_set_difficulty(sctx, params);
|
ret = stratum_set_difficulty(sctx, params);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (!strcasecmp(method, "mining.set_extranonce")) {
|
||||||
|
ret = stratum_parse_extranonce(sctx, params, 0);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
if (!strcasecmp(method, "client.reconnect")) {
|
if (!strcasecmp(method, "client.reconnect")) {
|
||||||
ret = stratum_reconnect(sctx, params);
|
ret = stratum_reconnect(sctx, params);
|
||||||
goto out;
|
goto out;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user