From 8abe9d4e394e1afac8b61a1450a4e3bb4bdc40bd Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 1 Nov 2013 23:30:29 +1100 Subject: [PATCH] Calculate diff from target accurately for all 256 bits. --- cgminer.c | 66 +++++++++++++++++++++++++++---------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/cgminer.c b/cgminer.c index ca2a4cc3..b58476d5 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1755,7 +1755,7 @@ void free_work(struct work *work) } static void gen_hash(unsigned char *data, unsigned char *hash, int len); -static void calc_diff(struct work *work, int known); +static void calc_diff(struct work *work, double known); char *workpadding = "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"; #ifdef HAVE_LIBCURL @@ -3067,40 +3067,46 @@ out: return pool; } -static double DIFFEXACTONE = 26959946667150639794667015087019630673637144422540572481103610249215.0; -static const uint64_t diffone = 0xFFFF000000000000ull; +/* truediffone == 0x00000000FFFF0000000000000000000000000000000000000000000000000000 + * Generate a 256 bit binary LE target by cutting up diff into 64 bit sized + * portions or vice versa. */ +static const double truediffone = 26959535291011309493156476344723991336010898738574164086137773096960.0; +static const double bits192 = 6277101735386680763835789423207666416102355444464034512896.0; +static const double bits128 = 340282366920938463463374607431768211456.0; +static const double bits64 = 18446744073709551616.0; /* - * Calculate the work share difficulty + * Calculate the work->work_difficulty based on the work->target */ -static void calc_diff(struct work *work, int known) +static void calc_diff(struct work *work, double known) { struct cgminer_pool_stats *pool_stats = &(work->pool->cgminer_pool_stats); double difficulty; int intdiff; - if (opt_scrypt) { - uint64_t *data64, d64; - char rtarget[32]; - - swab256(rtarget, work->target); - data64 = (uint64_t *)(rtarget + 2); - d64 = be64toh(*data64); - if (unlikely(!d64)) - d64 = 1; - work->work_difficulty = diffone / d64; - } else if (!known) { - double targ = 0; - int i; + if (known) + work->work_difficulty = known; + else { + double d64, dcut64; + uint64_t *data64; - for (i = 31; i >= 0; i--) { - targ *= 256; - targ += work->target[i]; - } + d64 = truediffone; + if (opt_scrypt) + d64 *= (double)65536; - work->work_difficulty = DIFFEXACTONE / (targ ? : DIFFEXACTONE); - } else - work->work_difficulty = known; + data64 = (uint64_t *)(work->target + 24); + dcut64 = le64toh(*data64); + + data64 = (uint64_t *)(work->target + 16); + dcut64 += le64toh(*data64) * bits64; + + data64 = (uint64_t *)(work->target + 8); + dcut64 += le64toh(*data64) * bits128; + + data64 = (uint64_t *)(work->target); + dcut64 += le64toh(*data64) * bits192; + work->work_difficulty = d64 / dcut64; + } difficulty = work->work_difficulty; pool_stats->last_diff = difficulty; @@ -3710,6 +3716,8 @@ static bool stale_work(struct work *work, bool share) return false; } +static const uint64_t diffone = 0xFFFF000000000000ull; + static uint64_t share_diff(const struct work *work) { uint64_t *data64, d64, ret; @@ -5912,14 +5920,6 @@ static void gen_hash(unsigned char *data, unsigned char *hash, int len) sha256(hash1, 32, hash); } -/* truediffone == 0x00000000FFFF0000000000000000000000000000000000000000000000000000 - * Generate a 256 bit binary LE target by cutting up diff into 64 bit sized - * portions. */ -static double truediffone = 26959535291011309493156476344723991336010898738574164086137773096960.0; -static double bits192 = 6277101735386680763835789423207666416102355444464034512896.0; -static double bits128 = 340282366920938463463374607431768211456.0; -static double bits64 = 18446744073709551616.0; - void set_target(unsigned char *dest_target, double diff) { unsigned char target[32];