diff --git a/README b/README index 00ba59271c..4f364210c3 100644 --- a/README +++ b/README @@ -829,6 +829,27 @@ quotas in a configuration file they would be specified thus: } ] +--- +NICEHASH XNSUB + +You can use your miner with last extranonce support for nicehash by adding #xnsub at the address end, like this: + +./cgminer -o stratum+tcp://stratum.solo.nicehash.com:3334/#xnsub -u 17EWiYuSD4RZoCzQ6YS2CPqxi6NQPDthxk.github -p thanks --gekko-2pac-freq 200 + +or, in your cgminer.conf file: + +{ +"pools" : [ + { + "url" : "stratum+tcp://stratum.solo.nicehash.com:3334/#xnsub", + "user" : "17EWiYuSD4RZoCzQ6YS2CPqxi6NQPDthxk.github", + "pass" : "thanks" + } +], + +"kernel-path" : "/usr/local/bin", +"gekko-2pac-freq" : "200" +} --- SOLO MINING diff --git a/cgminer.c b/cgminer.c index 2011f36674..99bbb1de44 100644 --- a/cgminer.c +++ b/cgminer.c @@ -957,7 +957,7 @@ static char *set_rr(enum pool_strategy *strategy) bool detect_stratum(struct pool *pool, char *url) { bool ret = false; - + check_extranonce_option(pool, url); if (!extract_sockaddr(url, &pool->sockaddr_url, &pool->stratum_port)) goto out; @@ -6847,6 +6847,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; @@ -6953,6 +6954,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 634694659f..8339210ad6 100644 --- a/miner.h +++ b/miner.h @@ -1292,6 +1292,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 1bbf829734..a9d81365b4 100644 --- a/util.c +++ b/util.c @@ -1646,6 +1646,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; @@ -2190,7 +2207,39 @@ 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); @@ -2362,6 +2411,11 @@ bool parse_method(struct pool *pool, char *s) ret = parse_diff(pool, params); 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); @@ -2860,6 +2914,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; @@ -3016,6 +3081,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 3dc72b9801..dfd5948f14 100644 --- a/util.h +++ b/util.h @@ -152,7 +152,9 @@ void ckrecalloc(void **ptr, size_t old, size_t new, const char *file, const char #define recalloc(ptr, old, new) ckrecalloc((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);