|
|
@ -1660,6 +1660,7 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) |
|
|
|
pool->seq_rejects = 0; |
|
|
|
pool->seq_rejects = 0; |
|
|
|
cgpu->last_share_pool = pool->pool_no; |
|
|
|
cgpu->last_share_pool = pool->pool_no; |
|
|
|
cgpu->last_share_pool_time = time(NULL); |
|
|
|
cgpu->last_share_pool_time = time(NULL); |
|
|
|
|
|
|
|
pool->last_share_time = cgpu->last_share_pool_time; |
|
|
|
applog(LOG_DEBUG, "PROOF OF WORK RESULT: true (yay!!!)"); |
|
|
|
applog(LOG_DEBUG, "PROOF OF WORK RESULT: true (yay!!!)"); |
|
|
|
if (!QUIET) { |
|
|
|
if (!QUIET) { |
|
|
|
if (total_pools > 1) |
|
|
|
if (total_pools > 1) |
|
|
@ -1675,6 +1676,16 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) |
|
|
|
kill_work(); |
|
|
|
kill_work(); |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Detect if a pool that has been temporarily disabled for
|
|
|
|
|
|
|
|
* continually rejecting shares has started accepting shares. |
|
|
|
|
|
|
|
* This will only happen with the work returned from a |
|
|
|
|
|
|
|
* longpoll */ |
|
|
|
|
|
|
|
if (unlikely(pool->enabled == POOL_REJECTING)) { |
|
|
|
|
|
|
|
applog(LOG_WARNING, "Rejecting pool %d now accepting shares, re-enabling!", pool->pool_no); |
|
|
|
|
|
|
|
pool->enabled = POOL_ENABLED; |
|
|
|
|
|
|
|
switch_pools(NULL); |
|
|
|
|
|
|
|
} |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
cgpu->rejected++; |
|
|
|
cgpu->rejected++; |
|
|
|
total_rejected++; |
|
|
|
total_rejected++; |
|
|
@ -1721,9 +1732,10 @@ static bool submit_upstream_work(const struct work *work, CURL *curl) |
|
|
|
if (pool->seq_rejects > utility) { |
|
|
|
if (pool->seq_rejects > utility) { |
|
|
|
applog(LOG_WARNING, "Pool %d rejected %d sequential shares, disabling!", |
|
|
|
applog(LOG_WARNING, "Pool %d rejected %d sequential shares, disabling!", |
|
|
|
pool->pool_no, pool->seq_rejects); |
|
|
|
pool->pool_no, pool->seq_rejects); |
|
|
|
pool->enabled = false; |
|
|
|
pool->enabled = POOL_REJECTING; |
|
|
|
if (pool == current_pool()) |
|
|
|
if (pool == current_pool()) |
|
|
|
switch_pools(NULL); |
|
|
|
switch_pools(NULL); |
|
|
|
|
|
|
|
pool->seq_rejects = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -1768,7 +1780,7 @@ static inline struct pool *select_pool(bool lagging) |
|
|
|
if (++rotating_pool >= total_pools) |
|
|
|
if (++rotating_pool >= total_pools) |
|
|
|
rotating_pool = 0; |
|
|
|
rotating_pool = 0; |
|
|
|
pool = pools[rotating_pool]; |
|
|
|
pool = pools[rotating_pool]; |
|
|
|
if ((!pool->idle && pool->enabled) || pool == cp) |
|
|
|
if ((!pool->idle && pool->enabled == POOL_ENABLED) || pool == cp) |
|
|
|
break; |
|
|
|
break; |
|
|
|
pool = NULL; |
|
|
|
pool = NULL; |
|
|
|
} |
|
|
|
} |
|
|
@ -2042,25 +2054,30 @@ static void *get_work_thread(void *userdata) |
|
|
|
else |
|
|
|
else |
|
|
|
ret_work->thr = NULL; |
|
|
|
ret_work->thr = NULL; |
|
|
|
|
|
|
|
|
|
|
|
pool = ret_work->pool = select_pool(wc->lagging); |
|
|
|
if (opt_benchmark) |
|
|
|
ce = pop_curl_entry(pool); |
|
|
|
get_benchmark_work(ret_work); |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
pool = ret_work->pool = select_pool(wc->lagging); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ce = pop_curl_entry(pool); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* obtain new work from bitcoin via JSON-RPC */ |
|
|
|
|
|
|
|
while (!get_upstream_work(ret_work, ce->curl)) { |
|
|
|
|
|
|
|
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) { |
|
|
|
|
|
|
|
applog(LOG_ERR, "json_rpc_call failed, terminating workio thread"); |
|
|
|
|
|
|
|
free_work(ret_work); |
|
|
|
|
|
|
|
kill_work(); |
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* obtain new work from bitcoin via JSON-RPC */ |
|
|
|
/* pause, then restart work-request loop */ |
|
|
|
while (!get_upstream_work(ret_work, ce->curl)) { |
|
|
|
applog(LOG_DEBUG, "json_rpc_call failed on get work, retry after %d seconds", |
|
|
|
if (unlikely((opt_retries >= 0) && (++failures > opt_retries))) { |
|
|
|
fail_pause); |
|
|
|
applog(LOG_ERR, "json_rpc_call failed, terminating workio thread"); |
|
|
|
sleep(fail_pause); |
|
|
|
free_work(ret_work); |
|
|
|
fail_pause += opt_fail_pause; |
|
|
|
kill_work(); |
|
|
|
|
|
|
|
goto out; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
fail_pause = opt_fail_pause; |
|
|
|
/* pause, then restart work-request loop */ |
|
|
|
|
|
|
|
applog(LOG_DEBUG, "json_rpc_call failed on get work, retry after %d seconds", |
|
|
|
|
|
|
|
fail_pause); |
|
|
|
|
|
|
|
sleep(fail_pause); |
|
|
|
|
|
|
|
fail_pause += opt_fail_pause; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
fail_pause = opt_fail_pause; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
applog(LOG_DEBUG, "Pushing work to requesting thread"); |
|
|
|
applog(LOG_DEBUG, "Pushing work to requesting thread"); |
|
|
|
|
|
|
|
|
|
|
@ -2073,7 +2090,8 @@ static void *get_work_thread(void *userdata) |
|
|
|
|
|
|
|
|
|
|
|
out: |
|
|
|
out: |
|
|
|
workio_cmd_free(wc); |
|
|
|
workio_cmd_free(wc); |
|
|
|
push_curl_entry(ce, pool); |
|
|
|
if (!opt_benchmark) |
|
|
|
|
|
|
|
push_curl_entry(ce, pool); |
|
|
|
return NULL; |
|
|
|
return NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -2094,6 +2112,7 @@ static bool workio_get_work(struct workio_cmd *wc) |
|
|
|
static bool stale_work(struct work *work, bool share) |
|
|
|
static bool stale_work(struct work *work, bool share) |
|
|
|
{ |
|
|
|
{ |
|
|
|
struct timeval now; |
|
|
|
struct timeval now; |
|
|
|
|
|
|
|
struct pool *pool; |
|
|
|
|
|
|
|
|
|
|
|
if (opt_benchmark) |
|
|
|
if (opt_benchmark) |
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -2108,7 +2127,8 @@ static bool stale_work(struct work *work, bool share) |
|
|
|
if (work->work_block != work_block) |
|
|
|
if (work->work_block != work_block) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
if (opt_fail_only && !share && work->pool != current_pool()) |
|
|
|
pool = work->pool; |
|
|
|
|
|
|
|
if (opt_fail_only && !share && pool != current_pool() && pool->enabled != POOL_REJECTING) |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
|
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
@ -2233,7 +2253,7 @@ void switch_pools(struct pool *selected) |
|
|
|
case POOL_LOADBALANCE: |
|
|
|
case POOL_LOADBALANCE: |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
pool = priority_pool(i); |
|
|
|
pool = priority_pool(i); |
|
|
|
if (!pool->idle && pool->enabled) { |
|
|
|
if (!pool->idle && pool->enabled == POOL_ENABLED) { |
|
|
|
pool_no = pool->pool_no; |
|
|
|
pool_no = pool->pool_no; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
@ -2542,7 +2562,7 @@ int active_pools(void) |
|
|
|
int i; |
|
|
|
int i; |
|
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
if ((pools[i])->enabled) |
|
|
|
if ((pools[i])->enabled == POOL_ENABLED) |
|
|
|
ret++; |
|
|
|
ret++; |
|
|
|
} |
|
|
|
} |
|
|
|
return ret; |
|
|
|
return ret; |
|
|
@ -2764,11 +2784,21 @@ updated: |
|
|
|
|
|
|
|
|
|
|
|
if (pool == current_pool()) |
|
|
|
if (pool == current_pool()) |
|
|
|
wattron(logwin, A_BOLD); |
|
|
|
wattron(logwin, A_BOLD); |
|
|
|
if (!pool->enabled) |
|
|
|
if (pool->enabled != POOL_ENABLED) |
|
|
|
wattron(logwin, A_DIM); |
|
|
|
wattron(logwin, A_DIM); |
|
|
|
wlogprint("%d: %s %s Priority %d: %s User:%s\n", |
|
|
|
wlogprint("%d: "); |
|
|
|
pool->pool_no, |
|
|
|
switch (pool->enabled) { |
|
|
|
pool->enabled? "Enabled" : "Disabled", |
|
|
|
case POOL_ENABLED: |
|
|
|
|
|
|
|
wlogprint("Enabled "); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case POOL_DISABLED: |
|
|
|
|
|
|
|
wlogprint("Disabled "); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case POOL_REJECTING: |
|
|
|
|
|
|
|
wlogprint("Rejecting "); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
wlogprint("%s Priority %d: %s User:%s\n", |
|
|
|
pool->idle? "Dead" : "Alive", |
|
|
|
pool->idle? "Dead" : "Alive", |
|
|
|
pool->prio, |
|
|
|
pool->prio, |
|
|
|
pool->rpc_url, pool->rpc_user); |
|
|
|
pool->rpc_url, pool->rpc_user); |
|
|
@ -2804,7 +2834,7 @@ retry: |
|
|
|
wlogprint("Unable to remove pool due to activity\n"); |
|
|
|
wlogprint("Unable to remove pool due to activity\n"); |
|
|
|
goto retry; |
|
|
|
goto retry; |
|
|
|
} |
|
|
|
} |
|
|
|
pool->enabled = false; |
|
|
|
pool->enabled = POOL_DISABLED; |
|
|
|
remove_pool(pool); |
|
|
|
remove_pool(pool); |
|
|
|
goto updated; |
|
|
|
goto updated; |
|
|
|
} else if (!strncasecmp(&input, "s", 1)) { |
|
|
|
} else if (!strncasecmp(&input, "s", 1)) { |
|
|
@ -2814,7 +2844,7 @@ retry: |
|
|
|
goto retry; |
|
|
|
goto retry; |
|
|
|
} |
|
|
|
} |
|
|
|
pool = pools[selected]; |
|
|
|
pool = pools[selected]; |
|
|
|
pool->enabled = true; |
|
|
|
pool->enabled = POOL_ENABLED; |
|
|
|
switch_pools(pool); |
|
|
|
switch_pools(pool); |
|
|
|
goto updated; |
|
|
|
goto updated; |
|
|
|
} else if (!strncasecmp(&input, "d", 1)) { |
|
|
|
} else if (!strncasecmp(&input, "d", 1)) { |
|
|
@ -2828,7 +2858,7 @@ retry: |
|
|
|
goto retry; |
|
|
|
goto retry; |
|
|
|
} |
|
|
|
} |
|
|
|
pool = pools[selected]; |
|
|
|
pool = pools[selected]; |
|
|
|
pool->enabled = false; |
|
|
|
pool->enabled = POOL_DISABLED; |
|
|
|
if (pool == current_pool()) |
|
|
|
if (pool == current_pool()) |
|
|
|
switch_pools(NULL); |
|
|
|
switch_pools(NULL); |
|
|
|
goto updated; |
|
|
|
goto updated; |
|
|
@ -2839,7 +2869,7 @@ retry: |
|
|
|
goto retry; |
|
|
|
goto retry; |
|
|
|
} |
|
|
|
} |
|
|
|
pool = pools[selected]; |
|
|
|
pool = pools[selected]; |
|
|
|
pool->enabled = true; |
|
|
|
pool->enabled = POOL_ENABLED; |
|
|
|
if (pool->prio < current_pool()->prio) |
|
|
|
if (pool->prio < current_pool()->prio) |
|
|
|
switch_pools(pool); |
|
|
|
switch_pools(pool); |
|
|
|
goto updated; |
|
|
|
goto updated; |
|
|
@ -3880,8 +3910,11 @@ static void convert_to_work(json_t *val, bool rolltime, struct pool *pool) |
|
|
|
* allows testwork to know whether LP discovered the block or not. */ |
|
|
|
* allows testwork to know whether LP discovered the block or not. */ |
|
|
|
test_work_current(work); |
|
|
|
test_work_current(work); |
|
|
|
|
|
|
|
|
|
|
|
/* Don't use backup LPs as work if we have failover-only enabled */ |
|
|
|
/* Don't use backup LPs as work if we have failover-only enabled. Use
|
|
|
|
if (pool != current_pool() && opt_fail_only) { |
|
|
|
* the longpoll work from a pool that has been rejecting shares as a |
|
|
|
|
|
|
|
* way to detect when the pool has recovered. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
if (pool != current_pool() && opt_fail_only && pool->enabled != POOL_REJECTING) { |
|
|
|
free_work(work); |
|
|
|
free_work(work); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -4058,8 +4091,9 @@ static void *watchpool_thread(void __maybe_unused *userdata) |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
struct pool *pool = pools[i]; |
|
|
|
struct pool *pool = pools[i]; |
|
|
|
|
|
|
|
|
|
|
|
reap_curl(pool); |
|
|
|
if (!opt_benchmark) |
|
|
|
if (!pool->enabled) |
|
|
|
reap_curl(pool); |
|
|
|
|
|
|
|
if (pool->enabled != POOL_ENABLED) |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
|
|
/* Test pool is idle once every minute */ |
|
|
|
/* Test pool is idle once every minute */ |
|
|
@ -4408,7 +4442,7 @@ int add_pool_details(bool live, char *url, char *user, char *pass) |
|
|
|
|
|
|
|
|
|
|
|
/* Test the pool is not idle if we're live running, otherwise
|
|
|
|
/* Test the pool is not idle if we're live running, otherwise
|
|
|
|
* it will be tested separately */ |
|
|
|
* it will be tested separately */ |
|
|
|
pool->enabled = true; |
|
|
|
pool->enabled = POOL_ENABLED; |
|
|
|
if (live && !pool_active(pool, false)) |
|
|
|
if (live && !pool_active(pool, false)) |
|
|
|
pool->idle = true; |
|
|
|
pool->idle = true; |
|
|
|
|
|
|
|
|
|
|
@ -4728,7 +4762,7 @@ int main(int argc, char *argv[]) |
|
|
|
strcpy(pool->rpc_url, "Benchmark"); |
|
|
|
strcpy(pool->rpc_url, "Benchmark"); |
|
|
|
pool->rpc_user = pool->rpc_url; |
|
|
|
pool->rpc_user = pool->rpc_url; |
|
|
|
pool->rpc_pass = pool->rpc_url; |
|
|
|
pool->rpc_pass = pool->rpc_url; |
|
|
|
pool->enabled = true; |
|
|
|
pool->enabled = POOL_ENABLED; |
|
|
|
pool->idle = false; |
|
|
|
pool->idle = false; |
|
|
|
successful_connect = true; |
|
|
|
successful_connect = true; |
|
|
|
} |
|
|
|
} |
|
|
@ -4957,7 +4991,7 @@ int main(int argc, char *argv[]) |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
for (i = 0; i < total_pools; i++) { |
|
|
|
struct pool *pool = pools[i]; |
|
|
|
struct pool *pool = pools[i]; |
|
|
|
|
|
|
|
|
|
|
|
pool->enabled = true; |
|
|
|
pool->enabled = POOL_ENABLED; |
|
|
|
pool->idle = true; |
|
|
|
pool->idle = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|