|
|
@ -3043,17 +3043,18 @@ static int block_sort(struct block *blocka, struct block *blockb) |
|
|
|
return blocka->block_no - blockb->block_no; |
|
|
|
return blocka->block_no - blockb->block_no; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void test_work_current(struct work *work) |
|
|
|
static bool test_work_current(struct work *work) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
bool ret = true; |
|
|
|
char *hexstr; |
|
|
|
char *hexstr; |
|
|
|
|
|
|
|
|
|
|
|
if (work->mandatory) |
|
|
|
if (work->mandatory) |
|
|
|
return; |
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
|
|
hexstr = bin2hex(work->data, 18); |
|
|
|
hexstr = bin2hex(work->data, 18); |
|
|
|
if (unlikely(!hexstr)) { |
|
|
|
if (unlikely(!hexstr)) { |
|
|
|
applog(LOG_ERR, "stage_thread OOM"); |
|
|
|
applog(LOG_ERR, "stage_thread OOM"); |
|
|
|
return; |
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Search to see if this block exists yet and if not, consider it a
|
|
|
|
/* Search to see if this block exists yet and if not, consider it a
|
|
|
@ -3061,6 +3062,7 @@ static void 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"); |
|
|
@ -3098,8 +3100,8 @@ static void test_work_current(struct work *work) |
|
|
|
applog(LOG_NOTICE, "New block detected on network before longpoll"); |
|
|
|
applog(LOG_NOTICE, "New block detected on network before longpoll"); |
|
|
|
else |
|
|
|
else |
|
|
|
applog(LOG_NOTICE, "New block detected on network"); |
|
|
|
applog(LOG_NOTICE, "New block detected on network"); |
|
|
|
restart_threads(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
restart_threads(); |
|
|
|
} else if (work->longpoll) { |
|
|
|
} else if (work->longpoll) { |
|
|
|
work->longpoll = false; |
|
|
|
work->longpoll = false; |
|
|
|
if (work->pool == current_pool()) { |
|
|
|
if (work->pool == current_pool()) { |
|
|
@ -3111,6 +3113,7 @@ static void test_work_current(struct work *work) |
|
|
|
} |
|
|
|
} |
|
|
|
out_free: |
|
|
|
out_free: |
|
|
|
free(hexstr); |
|
|
|
free(hexstr); |
|
|
|
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int tv_sort(struct work *worka, struct work *workb) |
|
|
|
static int tv_sort(struct work *worka, struct work *workb) |
|
|
@ -4145,10 +4148,20 @@ static void *stratum_thread(void *userdata) |
|
|
|
if (!parse_method(pool, s) && !parse_stratum_response(s)) |
|
|
|
if (!parse_method(pool, s) && !parse_stratum_response(s)) |
|
|
|
applog(LOG_INFO, "Unknown stratum msg: %s", s); |
|
|
|
applog(LOG_INFO, "Unknown stratum msg: %s", s); |
|
|
|
free(s); |
|
|
|
free(s); |
|
|
|
if (unlikely(pool->swork.clean)) { |
|
|
|
if (pool->swork.clean) { |
|
|
|
|
|
|
|
struct work work; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Generate a single work item to update the current
|
|
|
|
|
|
|
|
* block database */ |
|
|
|
pool->swork.clean = false; |
|
|
|
pool->swork.clean = false; |
|
|
|
applog(LOG_NOTICE, "Stratum requested work restart for block change"); |
|
|
|
gen_stratum_work(pool, &work); |
|
|
|
restart_threads(); |
|
|
|
if (test_work_current(&work)) { |
|
|
|
|
|
|
|
if (pool == current_pool()) { |
|
|
|
|
|
|
|
restart_threads(); |
|
|
|
|
|
|
|
applog(LOG_NOTICE, "Stratum requested work restart for block change"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else |
|
|
|
|
|
|
|
applog(LOG_NOTICE, "Stratum from pool %d detected new block", pool->pool_no); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (unlikely(pool->removed)) { |
|
|
|
if (unlikely(pool->removed)) { |
|
|
|