diff --git a/cgminer.c b/cgminer.c index 4207fd0067..1aec1893f7 100644 --- a/cgminer.c +++ b/cgminer.c @@ -824,6 +824,7 @@ static char *set_rr(enum pool_strategy *strategy) * stratum+tcp or by detecting a stratum server response */ bool detect_stratum(struct pool *pool, char *url) { + check_extranonce_option(pool, url); if (!extract_sockaddr(url, &pool->sockaddr_url, &pool->stratum_port)) return false; @@ -6465,6 +6466,7 @@ static void *longpoll_thread(void *userdata); static bool stratum_works(struct pool *pool) { applog(LOG_INFO, "Testing pool %d stratum %s", pool->pool_no, pool->stratum_url); + check_extranonce_option(pool, pool->stratum_url); if (!extract_sockaddr(pool->stratum_url, &pool->sockaddr_url, &pool->stratum_port)) return false; @@ -6572,7 +6574,7 @@ static bool pool_active(struct pool *pool, bool pinging) if (!init) { bool ret = initiate_stratum(pool) && auth_stratum(pool); - + extranonce_subscribe_stratum(pool); if (ret) init_stratum_threads(pool); else diff --git a/miner.h b/miner.h index c3c78feec1..24ef7e24f5 100644 --- a/miner.h +++ b/miner.h @@ -1264,6 +1264,7 @@ struct pool { /* Stratum variables */ char *stratum_url; + bool extranonce_subscribe; char *stratum_port; SOCKETTYPE sock; char *sockbuf; diff --git a/util.c b/util.c index ec99a46980..ef24ba5ad3 100644 --- a/util.c +++ b/util.c @@ -1620,6 +1620,23 @@ double tdiff(struct timeval *end, struct timeval *start) return end->tv_sec - start->tv_sec + (end->tv_usec - start->tv_usec) / 1000000.0; } +void check_extranonce_option(struct pool *pool, char * url) +{ + char extra_op[16],*extra_op_loc; + extra_op_loc = strstr(url,"#"); + if(extra_op_loc && !pool->extranonce_subscribe) + { + strcpy(extra_op, extra_op_loc); + *extra_op_loc = '\0'; + if(!strcmp(extra_op,"#xnsub")) + { + pool->extranonce_subscribe = true; + applog(LOG_DEBUG, "Pool %d extranonce subscribe enabled.", pool->pool_no); + } + } + return; +} + bool extract_sockaddr(char *url, char **sockaddr_url, char **sockaddr_port) { char *url_begin, *url_end, *ipv6_begin, *ipv6_end, *port_start = NULL; @@ -2120,6 +2137,40 @@ static bool parse_diff(struct pool *pool, json_t *val) return true; } +static bool parse_extranonce(struct pool *pool, json_t *val) +{ + int n2size; + char* nonce1; + + nonce1 = json_array_string(val, 0); + if (!valid_hex(nonce1)) { + applog(LOG_INFO, "Failed to get valid nonce1 in parse_extranonce"); + goto out; + } + n2size = json_integer_value(json_array_get(val, 1)); + if (n2size < 2 || n2size > 16) { + applog(LOG_INFO, "Failed to get valid n2size in parse_extranonce"); + free(nonce1); + goto out; + } + + cg_wlock(&pool->data_lock); + pool->nonce1 = nonce1; + pool->n1_len = strlen(nonce1) / 2; + free(pool->nonce1bin); + pool->nonce1bin = 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; + applog(LOG_NOTICE, "Pool %d confirmed mining.extranonce.subscribe with extranonce1 %s extran2size %d", + pool->pool_no, pool->nonce1, pool->n2size); + cg_wunlock(&pool->data_lock); + return true; +out: + return false; +} + static void __suspend_stratum(struct pool *pool) { clear_sockbuf(pool); @@ -2285,6 +2336,11 @@ bool parse_method(struct pool *pool, char *s) goto out_decref; } + if(!strncasecmp(buf, "mining.set_extranonce", 21)) { + ret = parse_extranonce(pool, params); + goto out_decref; + } + if (!strncasecmp(buf, "client.reconnect", 16)) { ret = parse_reconnect(pool, params); goto out_decref; @@ -2784,6 +2840,17 @@ void suspend_stratum(struct pool *pool) mutex_unlock(&pool->stratum_lock); } +void extranonce_subscribe_stratum(struct pool *pool) +{ + char s[RBUFSIZE]; + if(pool->extranonce_subscribe) + { + sprintf(s,"{\"id\": %d, \"method\": \"mining.extranonce.subscribe\", \"params\": []}", swork_id++); + applog(LOG_INFO, "Send extranonce.subscribe for stratum pool %d", pool->pool_no); + stratum_send(pool, s, strlen(s)); + } +} + bool initiate_stratum(struct pool *pool) { bool ret = false, recvd = false, noresume = false, sockd = false; @@ -2931,6 +2998,7 @@ bool restart_stratum(struct pool *pool) goto out; if (!auth_stratum(pool)) goto out; + extranonce_subscribe_stratum(pool); ret = true; out: if (!ret) diff --git a/util.h b/util.h index ea689efcd8..14336ac975 100644 --- a/util.h +++ b/util.h @@ -145,7 +145,9 @@ void _recalloc(void **ptr, size_t old, size_t new, const char *file, const char #define recalloc(ptr, old, new) _recalloc((void *)&(ptr), old, new, __FILE__, __func__, __LINE__) char *recv_line(struct pool *pool); bool parse_method(struct pool *pool, char *s); +void check_extranonce_option(struct pool *pool, char * url); bool extract_sockaddr(char *url, char **sockaddr_url, char **sockaddr_port); +void extranonce_subscribe_stratum(struct pool *pool); bool auth_stratum(struct pool *pool); bool initiate_stratum(struct pool *pool); bool restart_stratum(struct pool *pool);