Browse Source

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.

nfactor-troky
Con Kolivas 11 years ago
parent
commit
ab1e9404a7
  1. 98
      cgminer.c
  2. 3
      miner.h

98
cgminer.c

@ -279,6 +279,7 @@ bool curses_active;
/* Protected by ch_lock */ /* Protected by ch_lock */
char current_hash[68]; char current_hash[68];
static char prev_block[12]; static char prev_block[12];
static char current_block[32];
static char datestamp[40]; static char datestamp[40];
static char blocktime[32]; 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); \ wprintw(win, "%s", tmp42); \
} while (0) } 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 */ /* Must be called with curses mutex lock held and curses_active */
static void curses_print_status(void) static void curses_print_status(void)
{ {
@ -2287,7 +2293,7 @@ static void curses_print_status(void)
total_staged(), total_stale, new_blocks, total_staged(), total_stale, new_blocks,
local_work, total_go, total_ro); local_work, total_go, total_ro);
wclrtoeol(statuswin); 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", cg_mvwprintw(statuswin, 4, 0, " Connected to multiple pools with%s block change notify",
have_longpoll ? "": "out"); have_longpoll ? "": "out");
} else if (pool->has_stratum) { } else if (pool->has_stratum) {
@ -4015,13 +4021,14 @@ static void signal_work_update(void)
rd_unlock(&mining_thr_lock); rd_unlock(&mining_thr_lock);
} }
static void set_curblock(char *hexstr) static void set_curblock(char *hexstr, unsigned char *bedata)
{ {
int ofs; int ofs;
cg_wlock(&ch_lock); cg_wlock(&ch_lock);
cgtime(&block_timeval); cgtime(&block_timeval);
strcpy(current_hash, hexstr); strcpy(current_hash, hexstr);
memcpy(current_block, bedata, 32);
get_timestamp(blocktime, sizeof(blocktime), &block_timeval); get_timestamp(blocktime, sizeof(blocktime), &block_timeval);
cg_wunlock(&ch_lock); cg_wunlock(&ch_lock);
@ -4083,6 +4090,7 @@ static void set_blockdiff(const struct work *work)
static bool test_work_current(struct work *work) static bool test_work_current(struct work *work)
{ {
struct pool *pool = work->pool;
unsigned char bedata[32]; unsigned char bedata[32];
char hexstr[68]; char hexstr[68];
bool ret = true; bool ret = true;
@ -4098,7 +4106,6 @@ static bool test_work_current(struct work *work)
if (!block_exists(hexstr)) { if (!block_exists(hexstr)) {
struct block *s = calloc(sizeof(struct block), 1); struct block *s = calloc(sizeof(struct block), 1);
int deleted_block = 0; int deleted_block = 0;
ret = false;
if (unlikely(!s)) if (unlikely(!s))
quit (1, "test_work_current OOM"); quit (1, "test_work_current OOM");
@ -4124,31 +4131,71 @@ static bool test_work_current(struct work *work)
if (deleted_block) if (deleted_block)
applog(LOG_DEBUG, "Deleted block %d from database", deleted_block); applog(LOG_DEBUG, "Deleted block %d from database", deleted_block);
set_curblock(hexstr); set_curblock(hexstr, bedata);
if (unlikely(new_blocks == 1)) /* Copy the information to this pool's prev_block since it
return ret; * 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; 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", applog(LOG_NOTICE, "%sLONGPOLL from pool %d detected new block",
work->gbt ? "GBT " : "", work->pool->pool_no); work->gbt ? "GBT " : "", work->pool->pool_no);
} else if (have_longpoll) }
applog(LOG_NOTICE, "New block detected on network before longpoll"); } else if (have_longpoll)
else applog(LOG_NOTICE, "New block detected on network before longpoll");
applog(LOG_NOTICE, "New block detected on network"); else
} applog(LOG_NOTICE, "New block detected on network");
restart_threads(); restart_threads();
} else if (work->longpoll) { } else {
work->work_block = ++work_block; if (memcmp(pool->prev_block, bedata, 32)) {
if (work->pool == current_pool()) { /* Work doesn't match what this pool has stored as
applog(LOG_NOTICE, "%sLONGPOLL from pool %d requested work restart", * prev_block. Let's see if the work is from an old
work->gbt ? "GBT " : "", work->pool->pool_no); * block or the pool is just learning about a new
restart_threads(); * 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; work->longpoll = false;
return ret; return ret;
} }
@ -5501,15 +5548,10 @@ static void *stratum_rthread(void *userdata)
* block database */ * block database */
pool->swork.clean = false; pool->swork.clean = false;
gen_stratum_work(pool, work); gen_stratum_work(pool, work);
if (test_work_current(work)) { work->longpoll = true;
/* Only accept a work restart if this stratum /* Return value doesn't matter. We're just informing
* connection is from the current pool */ * that we may need to restart. */
if (pool == current_pool()) { test_work_current(work);
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);
free_work(work); free_work(work);
} }
} }

3
miner.h

@ -1326,6 +1326,9 @@ struct pool {
struct cgminer_stats cgminer_stats; struct cgminer_stats cgminer_stats;
struct cgminer_pool_stats cgminer_pool_stats; struct cgminer_pool_stats cgminer_pool_stats;
/* The last block this particular pool knows about */
char prev_block[32];
/* Stratum variables */ /* Stratum variables */
char *stratum_url; char *stratum_url;
char *stratum_port; char *stratum_port;

Loading…
Cancel
Save