Commit e49bd98196b9ee4b77822e49b610da808fb16b7f

Con Kolivas 2012-08-07T19:56:43

Use the scrypt CPU code to confirm results from OCL code, and mark failures as HW errors, making it easier to tune scrypt parameters.

diff --git a/Makefile.am b/Makefile.am
index 013fd34..42b7a33 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -45,6 +45,10 @@ cgminer_SOURCES += ocl.c ocl.h findnonce.c findnonce.h
 cgminer_SOURCES += adl.c adl.h adl_functions.h
 cgminer_SOURCES += *.cl
 
+if HAS_SCRYPT
+cgminer_SOURCES += scrypt.c
+endif
+
 if HAS_CPUMINE
 # original CPU related sources, unchanged
 cgminer_SOURCES	+= \
@@ -56,10 +60,6 @@ cgminer_SOURCES	+= \
 # the CPU portion extracted from original main.c
 cgminer_SOURCES += driver-cpu.h driver-cpu.c
 
-if HAS_SCRYPT
-cgminer_SOURCES += scrypt.c
-endif
-
 if HAS_YASM
 AM_CFLAGS	= -DHAS_YASM
 if HAVE_x86_64
diff --git a/findnonce.c b/findnonce.c
index a11333a..9980a70 100644
--- a/findnonce.c
+++ b/findnonce.c
@@ -17,6 +17,7 @@
 #include <string.h>
 
 #include "findnonce.h"
+#include "scrypt.h"
 
 const uint32_t SHA256_K[64] = {
 	0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
@@ -173,7 +174,7 @@ struct pc_data {
 	pthread_t pth;
 };
 
-static void send_nonce(struct pc_data *pcd, cl_uint nonce)
+static void send_sha_nonce(struct pc_data *pcd, cl_uint nonce)
 {
 	dev_blk_ctx *blk = &pcd->work->blk;
 	struct thr_info *thr = pcd->thr;
@@ -220,6 +221,19 @@ static void send_nonce(struct pc_data *pcd, cl_uint nonce)
 	}
 }
 
+static void send_scrypt_nonce(struct pc_data *pcd, uint32_t nonce)
+{
+	struct thr_info *thr = pcd->thr;
+	struct work *work = pcd->work;
+
+	if (scrypt_test(work->data, work->target, nonce))
+		submit_nonce(thr, pcd->work, nonce);
+	else {
+		applog(LOG_INFO, "Scrypt error, review settings");
+		thr->cgpu->hw_errors++;
+	}
+}
+
 static void *postcalc_hash(void *userdata)
 {
 	struct pc_data *pcd = (struct pc_data *)userdata;
@@ -233,13 +247,11 @@ static void *postcalc_hash(void *userdata)
 
 		if (nonce) {
 			applog(LOG_DEBUG, "OCL NONCE %u", nonce);
-#ifdef USE_SCRYPT
 			if (opt_scrypt)
-				submit_nonce(thr, pcd->work, nonce);
+				send_scrypt_nonce(pcd, nonce);
 			else
-#endif
-				send_nonce(pcd, nonce);
-		nonces++;
+				send_sha_nonce(pcd, nonce);
+			nonces++;
 		}
 	}
 
diff --git a/scrypt.c b/scrypt.c
index 4334bcf..70c3fd3 100644
--- a/scrypt.c
+++ b/scrypt.c
@@ -407,19 +407,32 @@ static uint32_t scrypt_1024_1_1_256_sp(const uint32_t* input, char* scratchpad)
 	return PBKDF2_SHA256_80_128_32(input, X);
 }
 
-bool scanhash_scrypt(struct thr_info *thr, const unsigned char *pmidstate, unsigned char *pdata,
-	unsigned char *phash1, unsigned char *phash,
-	const unsigned char *ptarget,
-	uint32_t max_nonce, uint32_t *last_nonce,
-	uint32_t n)
+/* Used externally as confirmation of correct OCL code */
+bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
+{
+	uint32_t tmp_hash7, Htarg = ((const uint32_t *)ptarget)[7];
+	char *scratchbuf;
+	uint32_t data[20];
+
+	be32enc_vect(data, (const uint32_t *)pdata, 19);
+	data[19] = byteswap(nonce);
+	scratchbuf = alloca(131584);
+	tmp_hash7 = scrypt_1024_1_1_256_sp(data, scratchbuf);
+
+	return (tmp_hash7 <= Htarg);
+}
+
+bool scanhash_scrypt(struct thr_info *thr, const unsigned char __maybe_unused *pmidstate,
+		     unsigned char *pdata, unsigned char __maybe_unused *phash1,
+		     unsigned char __maybe_unused *phash, const unsigned char *ptarget,
+		     uint32_t max_nonce, uint32_t *last_nonce, uint32_t n)
 {
 	uint32_t *nonce = (uint32_t *)(pdata + 76);
-	unsigned char *scratchbuf;
+	char *scratchbuf;
 	uint32_t data[20];
 	uint32_t tmp_hash7;
 	uint32_t Htarg = ((const uint32_t *)ptarget)[7];
 	bool ret = false;
-	int i;
 
 	be32enc_vect(data, (const uint32_t *)pdata, 19);
 
@@ -446,7 +459,7 @@ bool scanhash_scrypt(struct thr_info *thr, const unsigned char *pmidstate, unsig
 			break;
 		}
 	}
-out_ret:
+
 	free(scratchbuf);;
 	return ret;
 }
diff --git a/scrypt.h b/scrypt.h
new file mode 100644
index 0000000..45dd46b
--- /dev/null
+++ b/scrypt.h
@@ -0,0 +1,13 @@
+#ifndef SCRYPT_H
+#define SCRYPT_H
+
+#ifdef USE_SCRYPT
+extern bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce);
+#else /* USE_SCRYPT */
+static inline bool scrypt_test(unsigned char *pdata, const unsigned char *ptarget, uint32_t nonce)
+{
+	return false;
+}
+#endif /* USE_SCRYPT */
+
+#endif /* SCRYPT_H */