diff --git a/cgminer.c b/cgminer.c index c56a77696a..104ab1a093 100644 --- a/cgminer.c +++ b/cgminer.c @@ -4129,7 +4129,7 @@ bool submit_work_sync(struct thr_info *thr, const struct work *work_in) return false; } -bool hashtest(const struct work *work) +bool hashtest(const struct work *work, bool do_fulltest) { uint32_t *data32 = (uint32_t *)(work->data); unsigned char swap[128]; @@ -4150,7 +4150,10 @@ bool hashtest(const struct work *work) memcpy((void*)work->hash, hash2, 32); - return fulltest(work->hash, work->target); + if (do_fulltest) + return fulltest(work->hash, work->target); + else + return (hash2_32[7] == 0); } @@ -4168,7 +4171,7 @@ bool test_nonce(struct work *work, uint32_t nonce) work->data[64 + 12 + 2] = (nonce >> 16) & 0xff; work->data[64 + 12 + 3] = (nonce >> 24) & 0xff; - return hashtest(work); + return hashtest(work, true); } bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) @@ -4182,6 +4185,40 @@ bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce) return submit_work_sync(thr, work); } +/* + * Check a 1diff sha256 nonce + * If it doesn't hash to 1diff, then it was a HW error + * This is only for devices that produce 1diff sha256 nonces + */ +bool submit_nonce_1diff(struct thr_info *thr, struct work *work, uint32_t nonce) +{ + // not for scrypt - code bug + if (opt_scrypt) { + applog(LOG_ERR, "ERROR: submit_nonce_1diff() called with scrypt"); + return true; + } + + work->data[64 + 12 + 0] = (nonce >> 0) & 0xff; + work->data[64 + 12 + 1] = (nonce >> 8) & 0xff; + work->data[64 + 12 + 2] = (nonce >> 16) & 0xff; + work->data[64 + 12 + 3] = (nonce >> 24) & 0xff; + + if (!hashtest(work, false)) { + applog(LOG_WARNING, "%s%d: invalid nonce - HW error", + thr->cgpu->api->name, thr->cgpu->device_id); + hw_errors++; + thr->cgpu->hw_errors++; + return true; + } + + if (!fulltest(work->hash, work->target)) { + applog(LOG_INFO, "Share below target"); + return true; + } + + return submit_work_sync(thr, work); +} + static inline bool abandon_work(struct work *work, struct timeval *wdiff, uint64_t hashes) { if (wdiff->tv_sec > opt_scantime || diff --git a/driver-icarus.c b/driver-icarus.c index f1cf9d17d6..12236261c9 100644 --- a/driver-icarus.c +++ b/driver-icarus.c @@ -712,7 +712,7 @@ static int64_t icarus_scanhash(struct thr_info *thr, struct work *work, nonce = swab32(nonce); #endif - submit_nonce(thr, work, nonce); + submit_nonce_1diff(thr, work, nonce); hash_count = (nonce & info->nonce_mask); hash_count++; diff --git a/miner.h b/miner.h index f87612aba5..3fa511bfec 100644 --- a/miner.h +++ b/miner.h @@ -824,6 +824,7 @@ struct modminer_fpga_state { extern void get_datestamp(char *, struct timeval *); extern bool test_nonce(struct work *work, uint32_t nonce); bool submit_nonce(struct thr_info *thr, struct work *work, uint32_t nonce); +bool submit_nonce_1diff(struct thr_info *thr, struct work *work, uint32_t nonce); extern void tailsprintf(char *f, const char *fmt, ...); extern void wlogprint(const char *f, ...); extern int curses_int(const char *query);