Create machinery to divert work requests to stratum.
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
diff --git a/cgminer.c b/cgminer.c
index 127bcc5..b800ffe 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -2069,19 +2069,22 @@ static double DIFFEXACTONE = 269599466671506397946670150870196306736371444225405
/*
* Calculate the work share difficulty
*/
-static void calc_diff(struct work *work)
+static void calc_diff(struct work *work, int known)
{
struct cgminer_pool_stats *pool_stats = &(work->pool->cgminer_pool_stats);
double targ;
int i;
- targ = 0;
- for (i = 31; i >= 0; i--) {
- targ *= 256;
- targ += work->target[i];
- }
+ if (!known) {
+ targ = 0;
+ for (i = 31; i >= 0; i--) {
+ targ *= 256;
+ targ += work->target[i];
+ }
- work->work_difficulty = DIFFEXACTONE / (targ ? : DIFFEXACTONE);
+ work->work_difficulty = DIFFEXACTONE / (targ ? : DIFFEXACTONE);
+ } else
+ work->work_difficulty = known;
pool_stats->last_diff = work->work_difficulty;
@@ -2115,7 +2118,7 @@ static void get_benchmark_work(struct work *work)
gettimeofday(&(work->tv_getwork), NULL);
memcpy(&(work->tv_getwork_reply), &(work->tv_getwork), sizeof(struct timeval));
work->getwork_mode = GETWORK_MODE_BENCHMARK;
- calc_diff(work);
+ calc_diff(work, 0);
}
static bool get_upstream_work(struct work *work, CURL *curl)
@@ -2163,7 +2166,7 @@ static bool get_upstream_work(struct work *work, CURL *curl)
work->pool = pool;
work->longpoll = false;
work->getwork_mode = GETWORK_MODE_POOL;
- calc_diff(work);
+ calc_diff(work, 0);
total_getworks++;
pool->getwork_requested++;
@@ -2443,7 +2446,7 @@ static inline bool should_roll(struct work *work)
* reject blocks as invalid. */
static inline bool can_roll(struct work *work)
{
- return (work->pool && work->rolltime && !work->clone &&
+ return (!work->stratum && work->pool && work->rolltime && !work->clone &&
work->rolls < 7000 && !stale_work(work, false));
}
@@ -2526,6 +2529,8 @@ static void pool_died(struct pool *pool)
}
}
+static void gen_stratum_work(struct pool *pool, struct work *work);
+
static void *get_work_thread(void *userdata)
{
struct workio_cmd *wc = (struct workio_cmd *)userdata;
@@ -2539,6 +2544,17 @@ static void *get_work_thread(void *userdata)
pool = wc->pool;
+ if (pool->has_stratum) {
+ ret_work = make_work();
+ gen_stratum_work(pool, ret_work);
+ if (unlikely(!stage_work(ret_work))) {
+ applog(LOG_ERR, "Failed to stage stratum work in get_work_thread");
+ kill_work();
+ free(ret_work);
+ }
+ goto out;
+ }
+
if (clone_available()) {
dec_queued(pool);
goto out;
@@ -3014,15 +3030,17 @@ static void test_work_current(struct work *work)
work_block++;
- if (work->longpoll) {
- applog(LOG_NOTICE, "LONGPOLL from pool %d detected new block",
- work->pool->pool_no);
- work->longpoll = false;
- } else if (have_longpoll)
- applog(LOG_NOTICE, "New block detected on network before longpoll");
- else
- applog(LOG_NOTICE, "New block detected on network");
- restart_threads();
+ if (!work->stratum) {
+ if (work->longpoll) {
+ applog(LOG_NOTICE, "LONGPOLL from pool %d detected new block",
+ work->pool->pool_no);
+ work->longpoll = false;
+ } else if (have_longpoll)
+ applog(LOG_NOTICE, "New block detected on network before longpoll");
+ else
+ applog(LOG_NOTICE, "New block detected on network");
+ restart_threads();
+ }
} else if (work->longpoll) {
work->longpoll = false;
if (work->pool == current_pool()) {
@@ -4064,7 +4082,7 @@ static bool pool_active(struct pool *pool, bool pinging)
memcpy(&(work->tv_getwork), &tv_getwork, sizeof(struct timeval));
memcpy(&(work->tv_getwork_reply), &tv_getwork_reply, sizeof(struct timeval));
work->getwork_mode = GETWORK_MODE_TESTPOOL;
- calc_diff(work);
+ calc_diff(work, 0);
applog(LOG_DEBUG, "Pushing pooltest work to base pool");
tq_push(thr_info[stage_thr_id].q, work);
@@ -4220,6 +4238,12 @@ static struct work *hash_pop(const struct timespec *abstime)
static bool reuse_work(struct work *work)
{
+ if (work->stratum && !work->pool->idle) {
+ applog(LOG_DEBUG, "Reusing stratum work");
+ gen_stratum_work(work->pool, work);;
+ return true;
+ }
+
if (can_roll(work) && should_roll(work)) {
roll_work(work);
return true;
@@ -4347,6 +4371,16 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
strcat((char *)work->target, buf);
free(buf);
applog(LOG_DEBUG, "Generated target %s", work->target);
+
+ work->pool = pool;
+ work->stratum = true;
+ work->blk.nonce = 0;
+ work->id = total_work++;
+ work->longpoll = false;
+ work->getwork_mode = GETWORK_MODE_STRATUM;
+ calc_diff(work, diff);
+
+ gettimeofday(&work->tv_staged, NULL);
}
static void get_work(struct work *work, struct thr_info *thr, const int thr_id)
@@ -4368,11 +4402,6 @@ static void get_work(struct work *work, struct thr_info *thr, const int thr_id)
retry:
pool = current_pool();
- if (pool->has_stratum) {
- gen_stratum_work(pool, work);
- goto out;
- }
-
if (reuse_work(work))
goto out;
@@ -4769,7 +4798,7 @@ static void convert_to_work(json_t *val, int rolltime, struct pool *pool, struct
memcpy(&(work->tv_getwork), tv_lp, sizeof(struct timeval));
memcpy(&(work->tv_getwork_reply), tv_lp_reply, sizeof(struct timeval));
work->getwork_mode = GETWORK_MODE_LP;
- calc_diff(work);
+ calc_diff(work, 0);
if (pool->enabled == POOL_REJECTING)
work->mandatory = true;
diff --git a/miner.h b/miner.h
index 28d102a..fe617fc 100644
--- a/miner.h
+++ b/miner.h
@@ -850,6 +850,7 @@ struct pool {
#define GETWORK_MODE_POOL 'P'
#define GETWORK_MODE_LP 'L'
#define GETWORK_MODE_BENCHMARK 'B'
+#define GETWORK_MODE_STRATUM 'S'
struct work {
unsigned char data[128];
@@ -878,6 +879,7 @@ struct work {
bool mandatory;
bool block;
bool queued;
+ bool stratum;
unsigned int work_block;
int id;