Browse Source

Merge branch 'nicehash' into bfgminer

Luke Dashjr 11 years ago
parent
commit
20cdc61219
3 changed files with 121 additions and 15 deletions
  1. 2 2
      miner.c
  2. 3 0
      miner.h
  3. 116 13
      util.c

+ 2 - 2
miner.c

@@ -9588,11 +9588,11 @@ enum test_nonce2_result _test_nonce2(struct work *work, uint32_t nonce, bool che
 		if (pool->stratum_active)
 		{
 			// Some stratum pools are buggy and expect difficulty changes to be immediate retroactively, so if the target has changed, check and submit just in case
-			if (memcmp(pool->swork.target, work->target, sizeof(work->target)))
+			if (memcmp(pool->next_target, work->target, sizeof(work->target)))
 			{
 				applog(LOG_DEBUG, "Stratum pool %u target has changed since work job issued, checking that too",
 				       pool->pool_no);
-				if (hash_target_check_v(work->hash, pool->swork.target))
+				if (hash_target_check_v(work->hash, pool->next_target))
 					high_hash = false;
 			}
 		}

+ 3 - 0
miner.h

@@ -1344,6 +1344,9 @@ struct pool {
 	bool stratum_init;
 	bool stratum_notify;
 	struct stratum_work swork;
+	uint8_t next_target[0x20];
+	char *next_nonce1;
+	int next_n2size;
 	pthread_t stratum_thread;
 	pthread_mutex_t stratum_lock;
 	char *admin_msg;

+ 116 - 13
util.c

@@ -2396,6 +2396,19 @@ static bool parse_notify(struct pool *pool, json_t *val)
 	pool->submit_old = !clean;
 	pool->swork.clean = true;
 	
+	if (pool->next_nonce1)
+	{
+		free(pool->swork.nonce1);
+		pool->n1_len = strlen(pool->next_nonce1) / 2;
+		pool->swork.nonce1 = pool->next_nonce1;
+		pool->next_nonce1 = NULL;
+	}
+	int n2size = pool->swork.n2size = pool->next_n2size;
+	pool->nonce2sz  = (n2size > sizeof(pool->nonce2)) ? sizeof(pool->nonce2) : n2size;
+#ifdef WORDS_BIGENDIAN
+	pool->nonce2off = (n2size < sizeof(pool->nonce2)) ? (sizeof(pool->nonce2) - n2size) : 0;
+#endif
+	
 	hex2bin(&pool->swork.header1[0], bbversion,  4);
 	hex2bin(&pool->swork.header1[4], prev_hash, 32);
 	hex2bin((void*)&pool->swork.ntime, ntime, 4);
@@ -2421,6 +2434,9 @@ static bool parse_notify(struct pool *pool, json_t *val)
 		hex2bin(&bytes_buf(&pool->swork.merkle_bin)[i * 32], json_string_value(json_array_get(arr, i)), 32);
 	pool->swork.merkles = merkles;
 	pool->nonce2 = 0;
+	
+	memcpy(pool->swork.target, pool->next_target, 0x20);
+	
 	cg_wunlock(&pool->data_lock);
 
 	applog(LOG_DEBUG, "Received stratum notify from pool %u with job_id=%s",
@@ -2490,7 +2506,7 @@ static bool parse_diff(struct pool *pool, json_t *val)
 #endif
 
 	cg_wlock(&pool->data_lock);
-	set_target_to_pdiff(pool->swork.target, diff);
+	set_target_to_pdiff(pool->next_target, diff);
 	cg_wunlock(&pool->data_lock);
 
 	applog(LOG_DEBUG, "Pool %d stratum difficulty set to %g", pool->pool_no, diff);
@@ -2498,6 +2514,72 @@ static bool parse_diff(struct pool *pool, json_t *val)
 	return true;
 }
 
+static
+bool stratum_set_extranonce(struct pool * const pool, json_t * const val, json_t * const params)
+{
+	char *nonce1 = NULL;
+	int n2size = 0;
+	json_t *j;
+	
+	if (!json_is_array(params))
+		goto err;
+	switch (json_array_size(params))
+	{
+		default:  // >=2
+			// n2size
+			j = json_array_get(params, 1);
+			if (json_is_number(j))
+			{
+				n2size = json_integer_value(j);
+				if (n2size < 1)
+					goto err;
+			}
+			else
+			if (!json_is_null(j))
+				goto err;
+			// fallthru
+		case 1:
+			// nonce1
+			j = json_array_get(params, 0);
+			if (json_is_string(j))
+				nonce1 = strdup(json_string_value(j));
+			else
+			if (!json_is_null(j))
+				goto err;
+			break;
+		case 0:
+			applog(LOG_WARNING, "Pool %u: No-op mining.set_extranonce?", pool->pool_no);
+			return true;
+	}
+	
+	cg_wlock(&pool->data_lock);
+	if (nonce1)
+	{
+		free(pool->next_nonce1);
+		pool->next_nonce1 = nonce1;
+	}
+	if (n2size)
+		pool->next_n2size = n2size;
+	cg_wunlock(&pool->data_lock);
+	
+	return true;
+
+err:
+	applog(LOG_ERR, "Pool %u: Invalid mining.set_extranonce", pool->pool_no);
+	
+	json_t *id = json_object_get(val, "id");
+	if (id && !json_is_null(id))
+	{
+		char s[RBUFSIZE], *idstr;
+		idstr = json_dumps_ANY(id, 0);
+		sprintf(s, "{\"id\": %s, \"result\": null, \"error\": [20, \"Invalid params\"]}", idstr);
+		free(idstr);
+		stratum_send(pool, s, strlen(s));
+	}
+	
+	return true;
+}
+
 static bool parse_reconnect(struct pool *pool, json_t *val)
 {
 	if (opt_disable_client_reconnect)
@@ -2658,6 +2740,12 @@ bool parse_method(struct pool *pool, char *s)
 		ret = true;
 		goto out;
 	}
+	
+	if (!strncasecmp(buf, "mining.set_extranonce", 21) && stratum_set_extranonce(pool, val, params)) {
+		ret = true;
+		goto out;
+	}
+	
 out:
 	if (val)
 		json_decref(val);
@@ -2688,10 +2776,24 @@ bool auth_stratum(struct pool *pool)
 		if (parse_method(pool, sret))
 			free(sret);
 		else
-			break;
+		{
+			bool unknown = true;
+			val = JSON_LOADS(sret, &err);
+			json_t *j_id = json_object_get(val, "id");
+			if (json_is_string(j_id))
+			{
+				if (!strcmp(json_string_value(j_id), "auth"))
+					break;
+				else
+				if (!strcmp(json_string_value(j_id), "xnsub"))
+					unknown = false;
+			}
+			if (unknown)
+				applog(LOG_WARNING, "Pool %u: Unknown stratum msg: %s", pool->pool_no, sret);
+			free(sret);
+		}
 	}
 
-	val = JSON_LOADS(sret, &err);
 	free(sret);
 	res_val = json_object_get(val, "result");
 	err_val = json_object_get(val, "error");
@@ -2990,14 +3092,9 @@ resend:
 	cg_wlock(&pool->data_lock);
 	free(pool->sessionid);
 	pool->sessionid = sessionid;
-	free(pool->swork.nonce1);
-	pool->swork.nonce1 = nonce1;
-	pool->n1_len = strlen(nonce1) / 2;
-	pool->swork.n2size = n2size;
-	pool->nonce2sz  = (n2size > sizeof(pool->nonce2)) ? sizeof(pool->nonce2) : n2size;
-#ifdef WORDS_BIGENDIAN
-	pool->nonce2off = (n2size < sizeof(pool->nonce2)) ? (sizeof(pool->nonce2) - n2size) : 0;
-#endif
+	free(pool->next_nonce1);
+	pool->next_nonce1 = nonce1;
+	pool->next_n2size = n2size;
 	cg_wunlock(&pool->data_lock);
 
 	if (sessionid)
@@ -3015,10 +3112,16 @@ out:
 		if (!pool->stratum_url)
 			pool->stratum_url = pool->sockaddr_url;
 		pool->stratum_active = true;
-		set_target_to_pdiff(pool->swork.target, 1);
+		set_target_to_pdiff(pool->next_target, 1);
 		if (opt_protocol) {
 			applog(LOG_DEBUG, "Pool %d confirmed mining.subscribe with extranonce1 %s extran2size %d",
-			       pool->pool_no, pool->swork.nonce1, pool->swork.n2size);
+			       pool->pool_no, pool->next_nonce1, pool->next_n2size);
+		}
+		
+		if (uri_get_param_bool(pool->rpc_url, "xnsub", false))
+		{
+			sprintf(s, "{\"id\": \"xnsub\", \"method\": \"mining.extranonce.subscribe\", \"params\": []}");
+			_stratum_send(pool, s, strlen(s), true);
 		}
 	} else {
 		if (recvd)