Check the stratum pool difference has not changed compared to the work diff when testing whether a share meets the target or not and retarget if necessary.
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 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
diff --git a/cgminer.c b/cgminer.c
index b1c2867..a78b1a2 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -4475,15 +4475,39 @@ static void gen_hash(unsigned char *data, unsigned char *hash, int len)
sha2(hash1, 32, hash, false);
}
+static void set_work_target(struct work *work, int diff)
+{
+ unsigned char rtarget[33], target[33];
+ uint8_t *data8;
+ int i, j;
+
+ /* Scale to any diff by setting number of bits according to diff */
+ hex2bin(rtarget, "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32);
+ data8 = (uint8_t *)(rtarget + 4);
+ for (i = 1, j = 0; i < diff; i++, j++) {
+ int byte = j / 8;
+ int bit = j % 8;
+
+ data8[byte] &= ~(128 >> bit);
+ }
+ swab256(target, rtarget);
+ if (opt_debug) {
+ char *htarget = bin2hex(target, 32);
+
+ if (likely(htarget)) {
+ applog(LOG_DEBUG, "Generated target %s", htarget);
+ free(htarget);
+ }
+ }
+ memcpy(work->target, target, 256);
+}
+
static void gen_stratum_work(struct pool *pool, struct work *work)
{
unsigned char *coinbase, merkle_root[33], merkle_sha[65], *merkle_hash;
- int len, cb1_len, n1_len, cb2_len, i, j;
- unsigned char rtarget[33], target[33];
char header[257], hash1[129], *nonce2;
+ int len, cb1_len, n1_len, cb2_len, i;
uint32_t *data32, *swap32;
- uint8_t *data8;
- int diff;
mutex_lock(&pool->pool_lock);
@@ -4529,7 +4553,9 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
strcat(header, "00000000"); /* nonce */
strcat(header, "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000");
- diff = pool->swork.diff;
+ /* Store the stratum work diff to check it still matches the pool's
+ * stratum diff when submitting shares */
+ work->sdiff = pool->swork.diff;
/* Copy parameters required for share submission */
sprintf(work->job_id, "%s", pool->swork.job_id);
@@ -4552,25 +4578,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
if (unlikely(!hex2bin(work->hash1, hash1, 64)))
quit(1, "Failed to convert hash1 in gen_stratum_work");
- /* Scale to any diff by setting number of bits according to diff */
- hex2bin(rtarget, "00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 32);
- data8 = (uint8_t *)(rtarget + 4);
- for (i = 1, j = 0; i < diff; i++, j++) {
- int byte = j / 8;
- int bit = j % 8;
-
- data8[byte] &= ~(128 >> bit);
- }
- swab256(target, rtarget);
- if (opt_debug) {
- char *htarget = bin2hex(target, 32);
-
- if (likely(htarget)) {
- applog(LOG_DEBUG, "Generated target %s", htarget);
- free(htarget);
- }
- }
- memcpy(work->target, target, 256);
+ set_work_target(work, work->sdiff);
work->pool = pool;
work->stratum = true;
@@ -4579,7 +4587,7 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
work->longpoll = false;
work->getwork_mode = GETWORK_MODE_STRATUM;
work->work_block = work_block;
- calc_diff(work, diff);
+ calc_diff(work, work->sdiff);
gettimeofday(&work->tv_staged, NULL);
}
@@ -4698,7 +4706,7 @@ err_out:
return false;
}
-static bool hashtest(struct thr_info *thr, const struct work *work)
+static bool hashtest(struct thr_info *thr, struct work *work)
{
uint32_t *data32 = (uint32_t *)(work->data);
unsigned char swap[128];
@@ -4706,7 +4714,8 @@ static bool hashtest(struct thr_info *thr, const struct work *work)
unsigned char hash1[32];
unsigned char hash2[32];
uint32_t *hash2_32 = (uint32_t *)hash2;
- int i;
+ struct pool *pool = work->pool;
+ int i, diff;
for (i = 0; i < 80 / 4; i++)
swap32[i] = swab32(data32[i]);
@@ -4727,6 +4736,17 @@ static bool hashtest(struct thr_info *thr, const struct work *work)
return false;
}
+ if (work->stratum) {
+ mutex_lock(&pool->pool_lock);
+ diff = pool->swork.diff;
+ mutex_unlock(&pool->pool_lock);
+
+ if (unlikely(work->sdiff != diff)) {
+ applog(LOG_DEBUG, "Share needs retargetting to match pool");
+ set_work_target(work, diff);
+ }
+ }
+
bool test = fulltest(work->hash, work->target);
if (!test)
applog(LOG_INFO, "Share below target");
diff --git a/miner.h b/miner.h
index 78565f7..181a7e0 100644
--- a/miner.h
+++ b/miner.h
@@ -901,6 +901,7 @@ struct work {
char job_id[64];
char nonce2[64];
char ntime[16];
+ int sdiff;
unsigned int work_block;
int id;