diff --git a/cgminer.c b/cgminer.c index a896cfc7..d01bab50 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3173,7 +3173,7 @@ static void *submit_work_thread(void *userdata) * once and the stratum pool supports sessionid for mining * resume. */ while (time(NULL) < sshare->sshare_time + 120) { - bool session_match; + bool has_sessionid; if (likely(stratum_send(pool, s, strlen(s)))) { if (pool_tclear(pool, &pool->submit_fail)) @@ -3192,11 +3192,11 @@ static void *submit_work_thread(void *userdata) } mutex_lock(&pool->pool_lock); - session_match = pool->sessionid && work->sessionid && !strcmp(pool->sessionid, work->sessionid); + has_sessionid = pool->sessionid != NULL; mutex_unlock(&pool->pool_lock); - if (!session_match) { - applog(LOG_DEBUG, "Failed to session match stratum share"); + if (!has_sessionid) { + applog(LOG_DEBUG, "No session id for resubmitting stratum share"); break; } /* Retry every 5 seconds */ @@ -4602,7 +4602,7 @@ out: return ret; } -static void clear_stratum_shares(struct pool *pool) +void clear_stratum_shares(struct pool *pool) { struct stratum_share *sshare, *tmpshare; int cleared = 0; diff --git a/miner.h b/miner.h index 689e76da..eb4244ff 100644 --- a/miner.h +++ b/miner.h @@ -720,6 +720,7 @@ extern pthread_mutex_t restart_lock; extern pthread_cond_t restart_cond; extern void thread_reportin(struct thr_info *thr); +extern void clear_stratum_shares(struct pool *pool); extern int restart_wait(unsigned int mstime); extern void kill_work(void); diff --git a/util.c b/util.c index 48d3bd9e..4df0a657 100644 --- a/util.c +++ b/util.c @@ -1221,7 +1221,7 @@ static bool parse_reconnect(struct pool *pool, json_t *val) applog(LOG_NOTICE, "Reconnect requested from pool %d to %s", pool->pool_no, address); - if (!initiate_stratum(pool) || !auth_stratum(pool)) + if (!restart_stratum(pool)) return false; return true; @@ -1513,15 +1513,88 @@ out: return ret; } -/* Placeholder for real resume function in the future */ -static bool resume_stratum(struct pool *pool) +static void reset_sessionid(struct pool *pool) { mutex_lock(&pool->pool_lock); free(pool->sessionid); pool->sessionid = NULL; mutex_unlock(&pool->pool_lock); +} - return false; +/* Placeholder for real resume function in the future */ +static bool resume_stratum(struct pool *pool) +{ + json_t *val = NULL, *err_val, *res_val; + char s[RBUFSIZE], *sret = NULL; + json_error_t err; + bool ret = false; + + if (!setup_stratum_curl(pool)) + goto out; + + mutex_lock(&pool->pool_lock); + sprintf(s, "{\"id\": %d, \"method\": \"mining.resume\", \"params\": [\"%s\"]}", swork_id++, pool->sessionid); + mutex_unlock(&pool->pool_lock); + + if (!__stratum_send(pool, s, strlen(s))) { + applog(LOG_DEBUG, "Failed to send s in resume_stratum"); + goto out; + } + + if (!socket_full(pool, true)) { + applog(LOG_DEBUG, "Timed out waiting for response in resume_stratum"); + goto out; + } + + sret = recv_line(pool); + if (!sret) + goto out; + + val = JSON_LOADS(sret, &err); + free(sret); + if (!val) { + applog(LOG_INFO, "JSON decode failed(%d): %s", err.line, err.text); + goto out; + } + + res_val = json_object_get(val, "result"); + err_val = json_object_get(val, "error"); + + /* If there is an error, assume resume support is not there or broken */ + if (!res_val || json_is_null(res_val) || + (err_val && !json_is_null(err_val))) { + char *ss; + + if (err_val) + ss = json_dumps(err_val, JSON_INDENT(3)); + else + ss = strdup("(unknown reason)"); + + applog(LOG_INFO, "JSON-RPC decode failed: %s", ss); + + free(ss); + + reset_sessionid(pool); + goto out; + } + + if (json_is_true(res_val)) { + applog(LOG_NOTICE, "Resumed stratum connection to pool %d", pool->pool_no); + pool->stratum_active = true; + ret = true; + } else { + applog(LOG_NOTICE, "Unable to resume old stratum connection to pool %d", pool->pool_no); + reset_sessionid(pool); + clear_stratum_shares(pool); + json_decref(val); + + return initiate_stratum(pool); + } +out: + if (val) + json_decref(val); + + return ret; } bool restart_stratum(struct pool *pool) @@ -1532,10 +1605,13 @@ bool restart_stratum(struct pool *pool) resume = pool->sessionid != NULL; mutex_unlock(&pool->pool_lock); - if (resume && !resume_stratum(pool)) - return false; - else if (!initiate_stratum(pool)) - return false; + if (resume) { + if (!resume_stratum(pool)) + return false; + } else { + if (!initiate_stratum(pool)) + return false; + } if (!auth_stratum(pool)) return false; return true;