Browse Source

Protect pool name with lock

Disconnect from pool, if auth is failed

handle mining.set_extranonce method

subscribe for mining.extranonce

Allow disable extranonce subscribe

Send subscribe request before auth

Change mining.set_extranonce method as stratum notification

Set extranonce.subscribe timeout to 2sec

Some tweaks for extranonce

Handle pool response, who send errors in invalid format

Move no-extranonce-subscribe parameter to a pool config

Include pool.h

Set the pool idle and switch pool, if need

Mark pool as idle if stratum restart is failed

Conflicts:
	sgminer.c
djm34
elbandi 11 years ago committed by Jan Berdajs
parent
commit
91a26c46b7
  1. 5
      api.c
  2. 2
      miner.h
  3. 18
      sgminer.c
  4. 110
      util.c

5
api.c

@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
#include "compat.h"
#include "miner.h"
#include "pool.h"
#include "util.h"
#include "pool.h"
@ -1817,7 +1818,9 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m @@ -1817,7 +1818,9 @@ static void poolstatus(struct io_data *io_data, __maybe_unused SOCKETTYPE c, __m
lp = (char *)NO;
root = api_add_int(root, "POOL", &i, false);
root = api_add_string(root, "Name", get_pool_name(pool), false);
mutex_lock(&pool->stratum_lock);
root = api_add_string(root, "Name", get_pool_name(pool), true);
mutex_unlock(&pool->stratum_lock);
root = api_add_escape(root, "URL", pool->rpc_url, false);
root = api_add_string(root, "Algorithm", pool->algorithm.name, false);
root = api_add_string(root, "Description", pool->description, false);

2
miner.h

@ -1075,6 +1075,7 @@ extern int nDevs; @@ -1075,6 +1075,7 @@ extern int nDevs;
extern int hw_errors;
extern bool use_syslog;
extern bool opt_quiet;
extern bool opt_extranonce_subscribe;
extern struct thr_info *control_thr;
extern struct thr_info **mining_thr;
extern struct cgpu_info gpus[MAX_GPUDEVICES];
@ -1172,6 +1173,7 @@ struct pool { @@ -1172,6 +1173,7 @@ struct pool {
char *name;
char *description;
int prio;
bool extranonce_subscribe;
int accepted, rejected;
int seq_rejects;
int seq_getfails;

18
sgminer.c

@ -559,6 +559,7 @@ struct pool *add_pool(void) @@ -559,6 +559,7 @@ struct pool *add_pool(void)
pool->rpc_proxy = NULL;
pool->quota = 1;
adjust_quota_gcd();
pool->extranonce_subscribe = true;
pool->description = "";
@ -968,6 +969,16 @@ static char *set_userpass(const char *arg) @@ -968,6 +969,16 @@ static char *set_userpass(const char *arg)
return NULL;
}
static char *set_no_extranonce_subscribe(char *arg)
{
struct pool *pool = get_current_pool();
applog(LOG_DEBUG, "Disable extranonce subscribe on %d", pool->pool_no);
opt_set_invbool(&pool->extranonce_subscribe);
return NULL;
}
static char *set_pool_priority(char *arg)
{
struct pool *pool = get_current_pool();
@ -1363,6 +1374,9 @@ static struct opt_table opt_config_table[] = { @@ -1363,6 +1374,9 @@ static struct opt_table opt_config_table[] = {
OPT_WITHOUT_ARG("--no-submit-stale",
opt_set_invbool, &opt_submit_stale,
"Don't submit shares if they are detected as stale"),
OPT_WITHOUT_ARG("--no-extranonce-subscribe",
set_no_extranonce_subscribe, NULL,
"Disable 'extranonce' stratum subscribe"),
OPT_WITH_ARG("--pass|-p",
set_pass, NULL, NULL,
"Password for bitcoin JSON-RPC server"),
@ -4347,6 +4361,8 @@ void write_config(FILE *fcfg) @@ -4347,6 +4361,8 @@ void write_config(FILE *fcfg)
pool->rpc_proxy ? "|" : "",
json_escape(pool->rpc_url));
}
if (!pool->extranonce_subscribe)
fprintf(fcfg, ",\n\t\t\"no-extranonce-subscribe\" : true");
fprintf(fcfg, ",\n\t\t\"user\" : \"%s\"", json_escape(pool->rpc_user));
fprintf(fcfg, ",\n\t\t\"pass\" : \"%s\"", json_escape(pool->rpc_pass));
/* Using get_pool_name() here is unsafe if opt_incognito is true. */
@ -5734,7 +5750,7 @@ retry_stratum: @@ -5734,7 +5750,7 @@ retry_stratum:
bool init = pool_tset(pool, &pool->stratum_init);
if (!init) {
bool ret = initiate_stratum(pool) && auth_stratum(pool);
bool ret = initiate_stratum(pool) && (!pool->extranonce_subscribe || subscribe_extranonce(pool)) && auth_stratum(pool);
if (ret)
init_stratum_threads(pool);

110
util.c

@ -1669,6 +1669,37 @@ static bool parse_diff(struct pool *pool, json_t *val) @@ -1669,6 +1669,37 @@ static bool parse_diff(struct pool *pool, json_t *val)
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) {
return false;
}
n2size = json_integer_value(json_array_get(val, 1));
if (!n2size) {
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 extranonce change requested", get_pool_name(pool));
return true;
}
static void __suspend_stratum(struct pool *pool)
{
clear_sockbuf(pool);
@ -1814,6 +1845,12 @@ bool parse_method(struct pool *pool, char *s) @@ -1814,6 +1845,12 @@ bool parse_method(struct pool *pool, char *s)
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)) {
ret = true;
json_decref(val);
@ -1835,6 +1872,77 @@ bool parse_method(struct pool *pool, char *s) @@ -1835,6 +1872,77 @@ bool parse_method(struct pool *pool, char *s)
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 the response */
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 = __json_array_string(err_val, 1);
if (!ss)
ss = (char *)json_string_value(err_val);
if (ss && (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;
}
if (ss && (strcmp(ss, "Unrecognized request provided") == 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)
{
json_t *val = NULL, *res_val, *err_val;
@ -2465,6 +2573,8 @@ bool restart_stratum(struct pool *pool) @@ -2465,6 +2573,8 @@ bool restart_stratum(struct pool *pool)
suspend_stratum(pool);
if (!initiate_stratum(pool))
return false;
if (pool->extranonce_subscribe && !subscribe_extranonce(pool))
return false;
if (!auth_stratum(pool))
return false;

Loading…
Cancel
Save