Commit be4705a003e7a764ce114acc17c0c88a4e18c4a2

Con Kolivas 2013-02-15T23:05:29

Provide support for mining.resume with stratum, currently re-authorising after successful resumption pending finalising of the protocol process.

diff --git a/cgminer.c b/cgminer.c
index a896cfc..d01bab5 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 689e76d..eb4244f 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 48d3bd9..4df0a65 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;