Commit 5c7a32fde83d6d2afe9dcf0a600503a26a8761af

Con Kolivas 2013-04-08T21:26:10

Rationalise and simplify the share diff and block solve detection to a common site.

diff --git a/cgminer.c b/cgminer.c
index cd8e6c1..559e22a 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -242,7 +242,7 @@ static char datestamp[40];
 static char blocktime[32];
 struct timeval block_timeval;
 static char best_share[8] = "0";
-double current_diff;
+double current_diff = 0xFFFFFFFFFFFFFFFF;
 static char block_diff[8];
 uint64_t best_diff = 0;
 
@@ -2266,52 +2266,6 @@ void clear_logwin(void)
 }
 #endif
 
-/* Returns true if the regenerated work->hash solves a block */
-static bool solves_block(const struct work *work)
-{
-	uint32_t *hash32 = (uint32_t *)(work->hash);
-	uint32_t difficulty = 0;
-	uint32_t diffbytes = 0;
-	uint32_t diffvalue = 0;
-	uint32_t diffcmp[8];
-	int diffshift = 0;
-	int i;
-
-	difficulty = swab32(*((uint32_t *)(work->data + 72)));
-
-	diffbytes = ((difficulty >> 24) & 0xff) - 3;
-	diffvalue = difficulty & 0x00ffffff;
-
-	diffshift = (diffbytes % 4) * 8;
-	if (diffshift == 0) {
-		diffshift = 32;
-		diffbytes--;
-	}
-
-	memset(diffcmp, 0, 32);
-	diffbytes >>= 2;
-	/* Sanity check looking for overflow */
-	if (unlikely(diffbytes > 6))
-		return false;
-	diffcmp[diffbytes + 1] = diffvalue >> (32 - diffshift);
-	diffcmp[diffbytes] = diffvalue << diffshift;
-
-	for (i = 7; i >= 0; i--) {
-		if (hash32[i] > diffcmp[i])
-			return false;
-		if (hash32[i] < diffcmp[i])
-			return true;
-	}
-
-	// https://en.bitcoin.it/wiki/Block says: "numerically below"
-	// https://en.bitcoin.it/wiki/Target says: "lower than or equal to"
-	// code in bitcoind 0.3.24 main.cpp CheckWork() says: if (hash > hashTarget) return false;
-	if (hash32[0] == diffcmp[0])
-		return true;
-	else
-		return false;
-}
-
 static void enable_pool(struct pool *pool)
 {
 	if (pool->enabled != POOL_ENABLED) {
@@ -2461,34 +2415,6 @@ share_result(json_t *val, json_t *res, json_t *err, const struct work *work,
 	}
 }
 
-static const uint64_t diffone = 0xFFFF000000000000ull;
-
-static uint64_t share_diff(const struct work *work)
-{
-	uint64_t *data64, d64;
-	char rhash[32];
-	uint64_t ret;
-
-	swab256(rhash, work->hash);
-	if (opt_scrypt)
-		data64 = (uint64_t *)(rhash + 2);
-	else
-		data64 = (uint64_t *)(rhash + 4);
-	d64 = be64toh(*data64);
-	if (unlikely(!d64))
-		d64 = 1;
-	ret = diffone / d64;
-	cg_wlock(&control_lock);
-	if (ret > best_diff) {
-		best_diff = ret;
-		suffix_string(best_diff, best_share, 0);
-	}
-	if (ret > work->pool->best_diff)
-		work->pool->best_diff = ret;
-	cg_wunlock(&control_lock);
-	return ret;
-}
-
 static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit)
 {
 	char *hexstr = NULL;
@@ -2583,15 +2509,13 @@ static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit)
 		int intdiff = floor(work->work_difficulty);
 		char diffdisp[16], *outhash;
 		unsigned char rhash[32];
-		uint64_t sharediff;
 
 		swab256(rhash, work->hash);
 		if (opt_scrypt)
 			outhash = bin2hex(rhash + 2, 4);
 		else
 			outhash = bin2hex(rhash + 4, 4);
-		sharediff = share_diff(work);
-		suffix_string(sharediff, diffdisp, 0);
+		suffix_string(work->share_diff, diffdisp, 0);
 		sprintf(hashshow, "%s Diff %s/%d%s", outhash, diffdisp, intdiff,
 			work->block? " BLOCK!" : "");
 		free(outhash);
@@ -2733,6 +2657,7 @@ static inline struct pool *select_pool(bool lagging)
 }
 
 static double DIFFEXACTONE = 26959946667150639794667015087019630673637144422540572481103610249215.0;
+static const uint64_t diffone = 0xFFFF000000000000ull;
 
 /*
  * Calculate the work share difficulty
@@ -3261,6 +3186,32 @@ static bool stale_work(struct work *work, bool share)
 	return false;
 }
 
+static uint64_t share_diff(const struct work *work)
+{
+	uint64_t *data64, d64;
+	char rhash[32];
+	uint64_t ret;
+
+	swab256(rhash, work->hash);
+	if (opt_scrypt)
+		data64 = (uint64_t *)(rhash + 2);
+	else
+		data64 = (uint64_t *)(rhash + 4);
+	d64 = be64toh(*data64);
+	if (unlikely(!d64))
+		d64 = 1;
+	ret = diffone / d64;
+	cg_wlock(&control_lock);
+	if (ret > best_diff) {
+		best_diff = ret;
+		suffix_string(best_diff, best_share, 0);
+	}
+	if (ret > work->pool->best_diff)
+		work->pool->best_diff = ret;
+	cg_wunlock(&control_lock);
+	return ret;
+}
+
 static void regen_hash(struct work *work)
 {
 	uint32_t *data32 = (uint32_t *)(work->data);
@@ -3273,15 +3224,16 @@ static void regen_hash(struct work *work)
 	sha2(hash1, 32, (unsigned char *)(work->hash));
 }
 
-static void check_solve(struct work *work)
+static void rebuild_hash(struct work *work)
 {
 	if (opt_scrypt)
 		scrypt_outputhash(work);
 	else
 		regen_hash(work);
 
-	work->block = solves_block(work);
-	if (unlikely(work->block)) {
+	work->share_diff = share_diff(work);
+	if (unlikely(work->share_diff >= current_diff)) {
+		work->block = true;
 		work->pool->solved++;
 		found_blocks++;
 		work->mandatory = true;
@@ -3304,7 +3256,7 @@ static void *submit_work_thread(void *userdata)
 
 	applog(LOG_DEBUG, "Creating extra submit work thread");
 
-	check_solve(work);
+	rebuild_hash(work);
 
 	if (stale_work(work, true)) {
 		if (opt_submit_stale)
@@ -4757,7 +4709,6 @@ static void stratum_share_result(json_t *val, json_t *res_val, json_t *err_val,
 				 struct stratum_share *sshare)
 {
 	struct work *work = sshare->work;
-	uint64_t sharediff = share_diff(work);
 	char hashshow[65];
 	uint32_t *hash32;
 	char diffdisp[16];
@@ -4765,7 +4716,7 @@ static void stratum_share_result(json_t *val, json_t *res_val, json_t *err_val,
 
 	hash32 = (uint32_t *)(work->hash);
 	intdiff = floor(work->work_difficulty);
-	suffix_string(sharediff, diffdisp, 0);
+	suffix_string(work->share_diff, diffdisp, 0);
 	sprintf(hashshow, "%08lx Diff %s/%d%s", (unsigned long)htole32(hash32[6]), diffdisp, intdiff,
 		work->block? " BLOCK!" : "");
 	share_result(val, res_val, err_val, work, hashshow, false, "");
diff --git a/miner.h b/miner.h
index 9aa8741..b4b71ce 100644
--- a/miner.h
+++ b/miner.h
@@ -1119,7 +1119,8 @@ struct work {
 	unsigned char	target[32];
 	unsigned char	hash[32];
 
-	double	device_diff;
+	double		device_diff;
+	uint64_t	share_diff;
 
 	int		rolls;