Calculate diff from target accurately for all 256 bits.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
diff --git a/cgminer.c b/cgminer.c
index ca2a4cc..b58476d 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];