Make each pool store its on reference for what the most current block is and fine tune management of block change in shared pool failover strategies using the information.
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
diff --git a/cgminer.c b/cgminer.c
index 08168b6..67ac1a0 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -279,6 +279,7 @@ bool curses_active;
/* Protected by ch_lock */
char current_hash[68];
static char prev_block[12];
+static char current_block[32];
static char datestamp[40];
static char blocktime[32];
@@ -2272,6 +2273,11 @@ static void get_statline(char *buf, size_t bufsiz, struct cgpu_info *cgpu)
wprintw(win, "%s", tmp42); \
} while (0)
+static bool shared_strategy(void)
+{
+ return (pool_strategy == POOL_LOADBALANCE || pool_strategy == POOL_BALANCE);
+}
+
/* Must be called with curses mutex lock held and curses_active */
static void curses_print_status(void)
{
@@ -2287,7 +2293,7 @@ static void curses_print_status(void)
total_staged(), total_stale, new_blocks,
local_work, total_go, total_ro);
wclrtoeol(statuswin);
- if ((pool_strategy == POOL_LOADBALANCE || pool_strategy == POOL_BALANCE) && total_pools > 1) {
+ if (shared_strategy() && total_pools > 1) {
cg_mvwprintw(statuswin, 4, 0, " Connected to multiple pools with%s block change notify",
have_longpoll ? "": "out");
} else if (pool->has_stratum) {
@@ -4015,13 +4021,14 @@ static void signal_work_update(void)
rd_unlock(&mining_thr_lock);
}
-static void set_curblock(char *hexstr)
+static void set_curblock(char *hexstr, unsigned char *bedata)
{
int ofs;
cg_wlock(&ch_lock);
cgtime(&block_timeval);
strcpy(current_hash, hexstr);
+ memcpy(current_block, bedata, 32);
get_timestamp(blocktime, sizeof(blocktime), &block_timeval);
cg_wunlock(&ch_lock);
@@ -4083,6 +4090,7 @@ static void set_blockdiff(const struct work *work)
static bool test_work_current(struct work *work)
{
+ struct pool *pool = work->pool;
unsigned char bedata[32];
char hexstr[68];
bool ret = true;
@@ -4098,7 +4106,6 @@ static bool test_work_current(struct work *work)
if (!block_exists(hexstr)) {
struct block *s = calloc(sizeof(struct block), 1);
int deleted_block = 0;
- ret = false;
if (unlikely(!s))
quit (1, "test_work_current OOM");
@@ -4124,31 +4131,71 @@ static bool test_work_current(struct work *work)
if (deleted_block)
applog(LOG_DEBUG, "Deleted block %d from database", deleted_block);
- set_curblock(hexstr);
- if (unlikely(new_blocks == 1))
- return ret;
+ set_curblock(hexstr, bedata);
+ /* Copy the information to this pool's prev_block since it
+ * knows the new block exists. */
+ memcpy(pool->prev_block, bedata, 32);
+ if (unlikely(new_blocks == 1)) {
+ ret = false;
+ goto out;
+ }
work->work_block = ++work_block;
- if (!work->stratum) {
- if (work->longpoll) {
+ if (work->longpoll) {
+ if (work->stratum) {
+ applog(LOG_NOTICE, "Stratum from pool %d detected new block",
+ pool->pool_no);
+ } else {
applog(LOG_NOTICE, "%sLONGPOLL from pool %d detected new block",
work->gbt ? "GBT " : "", work->pool->pool_no);
- } else if (have_longpoll)
- applog(LOG_NOTICE, "New block detected on network before longpoll");
- else
- applog(LOG_NOTICE, "New block detected on network");
- }
+ }
+ } 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->work_block = ++work_block;
- if (work->pool == current_pool()) {
- applog(LOG_NOTICE, "%sLONGPOLL from pool %d requested work restart",
- work->gbt ? "GBT " : "", work->pool->pool_no);
- restart_threads();
+ } else {
+ if (memcmp(pool->prev_block, bedata, 32)) {
+ /* Work doesn't match what this pool has stored as
+ * prev_block. Let's see if the work is from an old
+ * block or the pool is just learning about a new
+ * block. */
+ if (memcmp(bedata, current_block, 32)) {
+ /* Doesn't match current block. It's stale */
+ applog(LOG_DEBUG, "Stale data from pool %d", pool->pool_no);
+ ret = false;
+ } else {
+ /* Work is from new block and pool is up now
+ * current. */
+ applog(LOG_INFO, "Pool %d now up to date", pool->pool_no);
+ memcpy(pool->prev_block, bedata, 32);
+ }
+ }
+#if 0
+ /* This isn't ideal, this pool is still on an old block but
+ * accepting shares from it. To maintain fair work distribution
+ * we work on it anyway. */
+ if (memcmp(bedata, current_block, 32))
+ applog(LOG_DEBUG, "Pool %d still on old block", pool->pool_no);
+#endif
+ if (work->longpoll) {
+ work->work_block = ++work_block;
+ if (shared_strategy() || work->pool == current_pool()) {
+ if (work->stratum) {
+ applog(LOG_NOTICE, "Stratum from pool %d requested work restart",
+ pool->pool_no);
+ } else {
+ applog(LOG_NOTICE, "%sLONGPOLL from pool %d requested work restart",
+ work->gbt ? "GBT " : "", work->pool->pool_no);
+ }
+ restart_threads();
+ }
}
}
+out:
work->longpoll = false;
+
return ret;
}
@@ -5501,15 +5548,10 @@ static void *stratum_rthread(void *userdata)
* block database */
pool->swork.clean = false;
gen_stratum_work(pool, work);
- if (test_work_current(work)) {
- /* Only accept a work restart if this stratum
- * connection is from the current pool */
- if (pool == current_pool()) {
- restart_threads();
- applog(LOG_NOTICE, "Stratum from pool %d requested work restart", pool->pool_no);
- }
- } else
- applog(LOG_NOTICE, "Stratum from pool %d detected new block", pool->pool_no);
+ work->longpoll = true;
+ /* Return value doesn't matter. We're just informing
+ * that we may need to restart. */
+ test_work_current(work);
free_work(work);
}
}
diff --git a/miner.h b/miner.h
index 19156e7..d0be71e 100644
--- a/miner.h
+++ b/miner.h
@@ -1326,6 +1326,9 @@ struct pool {
struct cgminer_stats cgminer_stats;
struct cgminer_pool_stats cgminer_pool_stats;
+ /* The last block this particular pool knows about */
+ char prev_block[32];
+
/* Stratum variables */
char *stratum_url;
char *stratum_port;