Browse Source

Merge remote-tracking branch 'conman/master' into bflsc

nfactor-troky
Kano 12 years ago
parent
commit
4266245afe
  1. 95
      cgminer.c
  2. 3
      miner.h
  3. 2
      ocl.c
  4. 134
      util.c
  5. 1
      util.h

95
cgminer.c

@ -250,6 +250,7 @@ struct stratum_share {
bool block; bool block;
struct work *work; struct work *work;
int id; int id;
time_t sshare_time;
}; };
static struct stratum_share *stratum_shares = NULL; static struct stratum_share *stratum_shares = NULL;
@ -1422,10 +1423,7 @@ void clean_work(struct work *work)
free(work->nonce2); free(work->nonce2);
free(work->ntime); free(work->ntime);
free(work->gbt_coinbase); free(work->gbt_coinbase);
work->job_id = NULL; free(work->sessionid);
work->nonce2 = NULL;
work->ntime = NULL;
work->gbt_coinbase = NULL;
memset(work, 0, sizeof(struct work)); memset(work, 0, sizeof(struct work));
} }
@ -3209,36 +3207,69 @@ static void *submit_work_thread(void *userdata)
if (work->stratum) { if (work->stratum) {
struct stratum_share *sshare = calloc(sizeof(struct stratum_share), 1); struct stratum_share *sshare = calloc(sizeof(struct stratum_share), 1);
uint32_t *hash32 = (uint32_t *)work->hash, nonce; uint32_t *hash32 = (uint32_t *)work->hash, nonce;
bool submitted = false;
char *noncehex; char *noncehex;
char s[1024]; char s[1024];
sshare->sshare_time = time(NULL);
/* This work item is freed in parse_stratum_response */ /* This work item is freed in parse_stratum_response */
sshare->work = work; sshare->work = work;
nonce = *((uint32_t *)(work->data + 76));
noncehex = bin2hex((const unsigned char *)&nonce, 4);
memset(s, 0, 1024);
mutex_lock(&sshare_lock); mutex_lock(&sshare_lock);
/* Give the stratum share a unique id */ /* Give the stratum share a unique id */
sshare->id = swork_id++; sshare->id = swork_id++;
HASH_ADD_INT(stratum_shares, id, sshare);
mutex_unlock(&sshare_lock); mutex_unlock(&sshare_lock);
nonce = *((uint32_t *)(work->data + 76));
noncehex = bin2hex((const unsigned char *)&nonce, 4);
memset(s, 0, 1024);
sprintf(s, "{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}", sprintf(s, "{\"params\": [\"%s\", \"%s\", \"%s\", \"%s\", \"%s\"], \"id\": %d, \"method\": \"mining.submit\"}",
pool->rpc_user, work->job_id, work->nonce2, work->ntime, noncehex, sshare->id); pool->rpc_user, work->job_id, work->nonce2, work->ntime, noncehex, sshare->id);
free(noncehex); free(noncehex);
applog(LOG_INFO, "Submitting share %08lx to pool %d", (unsigned long)(hash32[6]), pool->pool_no); applog(LOG_INFO, "Submitting share %08lx to pool %d", hash32[6], pool->pool_no);
/* Try resubmitting for up to 2 minutes if we fail to submit
* once and the stratum pool supports sessionid for mining
* resume. */
while (time(NULL) < sshare->sshare_time + 120) {
bool sessionid_match;
if (likely(stratum_send(pool, s, strlen(s)))) {
if (pool_tclear(pool, &pool->submit_fail))
applog(LOG_WARNING, "Pool %d communication resumed, submitting work", pool->pool_no);
mutex_lock(&sshare_lock);
HASH_ADD_INT(stratum_shares, id, sshare);
mutex_unlock(&sshare_lock);
applog(LOG_DEBUG, "Successfully submitted, adding to stratum_shares db");
submitted = true;
break;
}
if (!pool_tset(pool, &pool->submit_fail) && cnx_needed(pool)) {
applog(LOG_WARNING, "Pool %d stratum share submission failure", pool->pool_no);
total_ro++;
pool->remotefail_occasions++;
}
if (likely(stratum_send(pool, s, strlen(s)))) { mutex_lock(&pool->pool_lock);
if (pool_tclear(pool, &pool->submit_fail)) sessionid_match = pool->sessionid && work->sessionid && !strcmp(pool->sessionid, work->sessionid);
applog(LOG_WARNING, "Pool %d communication resumed, submitting work", pool->pool_no); mutex_unlock(&pool->pool_lock);
applog(LOG_DEBUG, "Successfully submitted, adding to stratum_shares db");
} else if (!pool_tset(pool, &pool->submit_fail) && cnx_needed(pool)) { if (!sessionid_match) {
applog(LOG_WARNING, "Pool %d stratum share submission failure", pool->pool_no); applog(LOG_DEBUG, "No matching session id for resubmitting stratum share");
total_ro++; break;
pool->remotefail_occasions++; }
/* Retry every 5 seconds */
sleep(5);
} }
if (unlikely(!submitted)) {
applog(LOG_DEBUG, "Failed to submit stratum share, discarding");
free_work(work);
free(sshare);
pool->stale_shares++;
total_stale++;
}
goto out; goto out;
} }
@ -4662,7 +4693,7 @@ out:
return ret; return ret;
} }
static void clear_stratum_shares(struct pool *pool) void clear_stratum_shares(struct pool *pool)
{ {
struct stratum_share *sshare, *tmpshare; struct stratum_share *sshare, *tmpshare;
int cleared = 0; int cleared = 0;
@ -4741,6 +4772,16 @@ static void stratum_resumed(struct pool *pool)
} }
} }
static bool supports_resume(struct pool *pool)
{
bool ret;
mutex_lock(&pool->pool_lock);
ret = (pool->sessionid != NULL);
mutex_unlock(&pool->pool_lock);
return ret;
}
/* One stratum thread per pool that has stratum waits on the socket checking /* One stratum thread per pool that has stratum waits on the socket checking
* for new messages and for the integrity of the socket connection. We reset * for new messages and for the integrity of the socket connection. We reset
* the connection based on the integrity of the receive side only as the send * the connection based on the integrity of the receive side only as the send
@ -4770,9 +4811,9 @@ static void *stratum_thread(void *userdata)
clear_pool_work(pool); clear_pool_work(pool);
wait_lpcurrent(pool); wait_lpcurrent(pool);
if (!initiate_stratum(pool) || !auth_stratum(pool)) { if (!restart_stratum(pool)) {
pool_died(pool); pool_died(pool);
while (!initiate_stratum(pool) || !auth_stratum(pool)) { while (!restart_stratum(pool)) {
if (pool->removed) if (pool->removed)
goto out; goto out;
nmsleep(30000); nmsleep(30000);
@ -4801,16 +4842,17 @@ static void *stratum_thread(void *userdata)
/* If the socket to our stratum pool disconnects, all /* If the socket to our stratum pool disconnects, all
* tracked submitted shares are lost and we will leak * tracked submitted shares are lost and we will leak
* the memory if we don't discard their records. */ * the memory if we don't discard their records. */
clear_stratum_shares(pool); if (!supports_resume(pool))
clear_stratum_shares(pool);
clear_pool_work(pool); clear_pool_work(pool);
if (pool == current_pool()) if (pool == current_pool())
restart_threads(); restart_threads();
if (initiate_stratum(pool) && auth_stratum(pool)) if (restart_stratum(pool))
continue; continue;
pool_died(pool); pool_died(pool);
while (!initiate_stratum(pool) || !auth_stratum(pool)) { while (!restart_stratum(pool)) {
if (pool->removed) if (pool->removed)
goto out; goto out;
nmsleep(30000); nmsleep(30000);
@ -5250,7 +5292,8 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
/* Copy parameters required for share submission */ /* Copy parameters required for share submission */
work->job_id = strdup(pool->swork.job_id); work->job_id = strdup(pool->swork.job_id);
work->ntime = strdup(pool->swork.ntime); work->ntime = strdup(pool->swork.ntime);
if (pool->sessionid)
work->sessionid = strdup(pool->sessionid);
mutex_unlock(&pool->pool_lock); mutex_unlock(&pool->pool_lock);
applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash); applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
@ -5522,10 +5565,10 @@ void hash_sole_work(struct thr_info *mythr)
max_nonce = max_nonce * 0x400 / (((cycle * 1000000) + sdiff.tv_usec) / (cycle * 1000000 / 0x400)); max_nonce = max_nonce * 0x400 / (((cycle * 1000000) + sdiff.tv_usec) / (cycle * 1000000 / 0x400));
timersub(&tv_end, &tv_lastupdate, &diff); timersub(&tv_end, &tv_lastupdate, &diff);
if (diff.tv_sec >= opt_log_interval) { if (diff.tv_sec >= cycle) {
hashmeter(thr_id, &diff, hashes_done); hashmeter(thr_id, &diff, hashes_done);
hashes_done = 0; hashes_done = 0;
tv_lastupdate = tv_end; memcpy(&tv_lastupdate, &tv_end, sizeof(struct timeval));
} }
if (unlikely(mythr->work_restart)) { if (unlikely(mythr->work_restart)) {

3
miner.h

@ -746,6 +746,7 @@ extern pthread_mutex_t restart_lock;
extern pthread_cond_t restart_cond; extern pthread_cond_t restart_cond;
extern void thread_reportin(struct thr_info *thr); extern void thread_reportin(struct thr_info *thr);
extern void clear_stratum_shares(struct pool *pool);
extern int restart_wait(unsigned int mstime); extern int restart_wait(unsigned int mstime);
extern void kill_work(void); extern void kill_work(void);
@ -971,6 +972,7 @@ struct pool {
size_t n1_len; size_t n1_len;
uint32_t nonce2; uint32_t nonce2;
int n2size; int n2size;
char *sessionid;
bool has_stratum; bool has_stratum;
bool stratum_active; bool stratum_active;
bool stratum_auth; bool stratum_auth;
@ -1035,6 +1037,7 @@ struct work {
char *nonce2; char *nonce2;
char *ntime; char *ntime;
double sdiff; double sdiff;
char *sessionid;
bool gbt; bool gbt;
char *gbt_coinbase; char *gbt_coinbase;

2
ocl.c

@ -380,7 +380,7 @@ _clState *initCl(unsigned int gpu, char *name, size_t nameSize)
*/ */
char binaryfilename[255]; char binaryfilename[255];
char filename[255]; char filename[255];
char numbuf[10]; char numbuf[16];
if (cgpu->kernel == KL_NONE) { if (cgpu->kernel == KL_NONE) {
if (opt_scrypt) { if (opt_scrypt) {

134
util.c

@ -1247,7 +1247,7 @@ static bool parse_reconnect(struct pool *pool, json_t *val)
applog(LOG_NOTICE, "Reconnect requested from pool %d to %s", pool->pool_no, address); applog(LOG_NOTICE, "Reconnect requested from pool %d to %s", pool->pool_no, address);
if (!initiate_stratum(pool) || !auth_stratum(pool)) if (!restart_stratum(pool))
return false; return false;
return true; return true;
@ -1391,15 +1391,12 @@ out:
return ret; return ret;
} }
bool initiate_stratum(struct pool *pool) static bool setup_stratum_curl(struct pool *pool)
{ {
json_t *val = NULL, *res_val, *err_val;
char curl_err_str[CURL_ERROR_SIZE]; char curl_err_str[CURL_ERROR_SIZE];
char s[RBUFSIZE], *sret = NULL;
CURL *curl = NULL; CURL *curl = NULL;
double byte_count; double byte_count;
json_error_t err; char s[RBUFSIZE];
bool ret = false;
mutex_lock(&pool->stratum_lock); mutex_lock(&pool->stratum_lock);
pool->stratum_active = false; pool->stratum_active = false;
@ -1419,7 +1416,6 @@ bool initiate_stratum(struct pool *pool)
} }
/* Create a http url for use with curl */ /* Create a http url for use with curl */
memset(s, 0, RBUFSIZE);
sprintf(s, "http://%s:%s", pool->sockaddr_url, pool->stratum_port); sprintf(s, "http://%s:%s", pool->sockaddr_url, pool->stratum_port);
curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1); curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
@ -1439,7 +1435,7 @@ bool initiate_stratum(struct pool *pool)
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1);
if (curl_easy_perform(curl)) { if (curl_easy_perform(curl)) {
applog(LOG_INFO, "Stratum connect failed to pool %d: %s", pool->pool_no, curl_err_str); applog(LOG_INFO, "Stratum connect failed to pool %d: %s", pool->pool_no, curl_err_str);
goto out; return false;
} }
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&pool->sock); curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&pool->sock);
keep_alive(curl, pool->sock); keep_alive(curl, pool->sock);
@ -1451,6 +1447,19 @@ bool initiate_stratum(struct pool *pool)
if (curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &byte_count) == CURLE_OK) if (curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &byte_count) == CURLE_OK)
pool->cgminer_pool_stats.bytes_received += byte_count; pool->cgminer_pool_stats.bytes_received += byte_count;
return true;
}
bool initiate_stratum(struct pool *pool)
{
json_t *val = NULL, *res_val, *err_val;
char s[RBUFSIZE], *sret = NULL;
json_error_t err;
bool ret = false;
if (!setup_stratum_curl(pool))
goto out;
sprintf(s, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": []}", swork_id++); sprintf(s, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": []}", swork_id++);
if (!__stratum_send(pool, s, strlen(s))) { if (!__stratum_send(pool, s, strlen(s))) {
@ -1504,6 +1513,11 @@ bool initiate_stratum(struct pool *pool)
applog(LOG_INFO, "Failed to get n2size in initiate_stratum"); applog(LOG_INFO, "Failed to get n2size in initiate_stratum");
goto out; goto out;
} }
pool->sessionid = json_array_string(res_val, 3);
if (pool->sessionid)
applog(LOG_DEBUG, "Pool %d stratum session id: %s", pool->pool_no, pool->sessionid);
else
applog(LOG_DEBUG, "Pool %d stratum session id does not exist");
ret = true; ret = true;
out: out:
@ -1525,6 +1539,110 @@ out:
return ret; return ret;
} }
static void reset_sessionid(struct pool *pool)
{
mutex_lock(&pool->pool_lock);
free(pool->sessionid);
pool->sessionid = NULL;
mutex_unlock(&pool->pool_lock);
}
/* Placeholder for real resume function in the future */
static bool resume_stratum(struct pool *pool)
{
json_t *val = NULL, *err_val, *res_val;
char s[RBUFSIZE], *sret = NULL;
json_error_t err;
bool ret = false;
if (!setup_stratum_curl(pool))
goto out;
mutex_lock(&pool->pool_lock);
sprintf(s, "{\"id\": %d, \"method\": \"mining.resume\", \"params\": [\"%s\"]}", swork_id++, pool->sessionid);
mutex_unlock(&pool->pool_lock);
if (!__stratum_send(pool, s, strlen(s))) {
applog(LOG_DEBUG, "Failed to send s in resume_stratum");
goto out;
}
if (!socket_full(pool, true)) {
applog(LOG_DEBUG, "Timed out waiting for response in resume_stratum");
goto out;
}
sret = recv_line(pool);
if (!sret)
goto out;
val = JSON_LOADS(sret, &err);
free(sret);
if (!val) {
applog(LOG_INFO, "JSON decode failed(%d): %s", err.line, err.text);
goto out;
}
res_val = json_object_get(val, "result");
err_val = json_object_get(val, "error");
/* If there is an error, assume resume support is not there or broken */
if (!res_val || json_is_null(res_val) ||
(err_val && !json_is_null(err_val))) {
char *ss;
if (err_val)
ss = json_dumps(err_val, JSON_INDENT(3));
else
ss = strdup("(unknown reason)");
applog(LOG_INFO, "JSON-RPC decode failed: %s", ss);
free(ss);
reset_sessionid(pool);
goto out;
}
if (json_is_true(res_val)) {
applog(LOG_NOTICE, "Resumed stratum connection to pool %d", pool->pool_no);
pool->stratum_active = true;
ret = true;
} else {
applog(LOG_NOTICE, "Unable to resume old stratum connection to pool %d", pool->pool_no);
reset_sessionid(pool);
clear_stratum_shares(pool);
json_decref(val);
return initiate_stratum(pool);
}
out:
if (val)
json_decref(val);
return ret;
}
bool restart_stratum(struct pool *pool)
{
bool resume;
mutex_lock(&pool->pool_lock);
resume = pool->sessionid != NULL;
mutex_unlock(&pool->pool_lock);
if (resume) {
if (!resume_stratum(pool))
return false;
} else {
if (!initiate_stratum(pool))
return false;
}
if (!auth_stratum(pool))
return false;
return true;
}
void suspend_stratum(struct pool *pool) void suspend_stratum(struct pool *pool)
{ {
applog(LOG_INFO, "Closing socket for stratum pool %d", pool->pool_no); applog(LOG_INFO, "Closing socket for stratum pool %d", pool->pool_no);

1
util.h

@ -52,6 +52,7 @@ bool parse_method(struct pool *pool, char *s);
bool extract_sockaddr(struct pool *pool, char *url); bool extract_sockaddr(struct pool *pool, char *url);
bool auth_stratum(struct pool *pool); bool auth_stratum(struct pool *pool);
bool initiate_stratum(struct pool *pool); bool initiate_stratum(struct pool *pool);
bool restart_stratum(struct pool *pool);
void suspend_stratum(struct pool *pool); void suspend_stratum(struct pool *pool);
void dev_error(struct cgpu_info *dev, enum dev_reason reason); void dev_error(struct cgpu_info *dev, enum dev_reason reason);
void *realloc_strcat(char *ptr, char *s); void *realloc_strcat(char *ptr, char *s);

Loading…
Cancel
Save