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 { @@ -250,6 +250,7 @@ struct stratum_share {
bool block;
struct work *work;
int id;
time_t sshare_time;
};
static struct stratum_share *stratum_shares = NULL;
@ -1422,10 +1423,7 @@ void clean_work(struct work *work) @@ -1422,10 +1423,7 @@ void clean_work(struct work *work)
free(work->nonce2);
free(work->ntime);
free(work->gbt_coinbase);
work->job_id = NULL;
work->nonce2 = NULL;
work->ntime = NULL;
work->gbt_coinbase = NULL;
free(work->sessionid);
memset(work, 0, sizeof(struct work));
}
@ -3209,36 +3207,69 @@ static void *submit_work_thread(void *userdata) @@ -3209,36 +3207,69 @@ static void *submit_work_thread(void *userdata)
if (work->stratum) {
struct stratum_share *sshare = calloc(sizeof(struct stratum_share), 1);
uint32_t *hash32 = (uint32_t *)work->hash, nonce;
bool submitted = false;
char *noncehex;
char s[1024];
sshare->sshare_time = time(NULL);
/* This work item is freed in parse_stratum_response */
sshare->work = work;
nonce = *((uint32_t *)(work->data + 76));
noncehex = bin2hex((const unsigned char *)&nonce, 4);
memset(s, 0, 1024);
mutex_lock(&sshare_lock);
/* Give the stratum share a unique id */
sshare->id = swork_id++;
HASH_ADD_INT(stratum_shares, id, sshare);
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\"}",
pool->rpc_user, work->job_id, work->nonce2, work->ntime, noncehex, sshare->id);
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)))) {
if (pool_tclear(pool, &pool->submit_fail))
applog(LOG_WARNING, "Pool %d communication resumed, submitting work", pool->pool_no);
applog(LOG_DEBUG, "Successfully submitted, adding to stratum_shares db");
} else 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++;
mutex_lock(&pool->pool_lock);
sessionid_match = pool->sessionid && work->sessionid && !strcmp(pool->sessionid, work->sessionid);
mutex_unlock(&pool->pool_lock);
if (!sessionid_match) {
applog(LOG_DEBUG, "No matching session id for resubmitting stratum share");
break;
}
/* 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;
}
@ -4662,7 +4693,7 @@ out: @@ -4662,7 +4693,7 @@ out:
return ret;
}
static void clear_stratum_shares(struct pool *pool)
void clear_stratum_shares(struct pool *pool)
{
struct stratum_share *sshare, *tmpshare;
int cleared = 0;
@ -4741,6 +4772,16 @@ static void stratum_resumed(struct pool *pool) @@ -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
* 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
@ -4770,9 +4811,9 @@ static void *stratum_thread(void *userdata) @@ -4770,9 +4811,9 @@ static void *stratum_thread(void *userdata)
clear_pool_work(pool);
wait_lpcurrent(pool);
if (!initiate_stratum(pool) || !auth_stratum(pool)) {
if (!restart_stratum(pool)) {
pool_died(pool);
while (!initiate_stratum(pool) || !auth_stratum(pool)) {
while (!restart_stratum(pool)) {
if (pool->removed)
goto out;
nmsleep(30000);
@ -4801,16 +4842,17 @@ static void *stratum_thread(void *userdata) @@ -4801,16 +4842,17 @@ static void *stratum_thread(void *userdata)
/* If the socket to our stratum pool disconnects, all
* tracked submitted shares are lost and we will leak
* 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);
if (pool == current_pool())
restart_threads();
if (initiate_stratum(pool) && auth_stratum(pool))
if (restart_stratum(pool))
continue;
pool_died(pool);
while (!initiate_stratum(pool) || !auth_stratum(pool)) {
while (!restart_stratum(pool)) {
if (pool->removed)
goto out;
nmsleep(30000);
@ -5250,7 +5292,8 @@ static void gen_stratum_work(struct pool *pool, struct work *work) @@ -5250,7 +5292,8 @@ static void gen_stratum_work(struct pool *pool, struct work *work)
/* Copy parameters required for share submission */
work->job_id = strdup(pool->swork.job_id);
work->ntime = strdup(pool->swork.ntime);
if (pool->sessionid)
work->sessionid = strdup(pool->sessionid);
mutex_unlock(&pool->pool_lock);
applog(LOG_DEBUG, "Generated stratum merkle %s", merkle_hash);
@ -5522,10 +5565,10 @@ void hash_sole_work(struct thr_info *mythr) @@ -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));
timersub(&tv_end, &tv_lastupdate, &diff);
if (diff.tv_sec >= opt_log_interval) {
if (diff.tv_sec >= cycle) {
hashmeter(thr_id, &diff, hashes_done);
hashes_done = 0;
tv_lastupdate = tv_end;
memcpy(&tv_lastupdate, &tv_end, sizeof(struct timeval));
}
if (unlikely(mythr->work_restart)) {

3
miner.h

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

2
ocl.c

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

134
util.c

@ -1247,7 +1247,7 @@ static bool parse_reconnect(struct pool *pool, json_t *val) @@ -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);
if (!initiate_stratum(pool) || !auth_stratum(pool))
if (!restart_stratum(pool))
return false;
return true;
@ -1391,15 +1391,12 @@ out: @@ -1391,15 +1391,12 @@ out:
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 s[RBUFSIZE], *sret = NULL;
CURL *curl = NULL;
double byte_count;
json_error_t err;
bool ret = false;
char s[RBUFSIZE];
mutex_lock(&pool->stratum_lock);
pool->stratum_active = false;
@ -1419,7 +1416,6 @@ bool initiate_stratum(struct pool *pool) @@ -1419,7 +1416,6 @@ bool initiate_stratum(struct pool *pool)
}
/* Create a http url for use with curl */
memset(s, 0, RBUFSIZE);
sprintf(s, "http://%s:%s", pool->sockaddr_url, pool->stratum_port);
curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
@ -1439,7 +1435,7 @@ bool initiate_stratum(struct pool *pool) @@ -1439,7 +1435,7 @@ bool initiate_stratum(struct pool *pool)
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1);
if (curl_easy_perform(curl)) {
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);
keep_alive(curl, pool->sock);
@ -1451,6 +1447,19 @@ bool initiate_stratum(struct pool *pool) @@ -1451,6 +1447,19 @@ bool initiate_stratum(struct pool *pool)
if (curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &byte_count) == CURLE_OK)
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++);
if (!__stratum_send(pool, s, strlen(s))) {
@ -1504,6 +1513,11 @@ bool initiate_stratum(struct pool *pool) @@ -1504,6 +1513,11 @@ bool initiate_stratum(struct pool *pool)
applog(LOG_INFO, "Failed to get n2size in initiate_stratum");
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;
out:
@ -1525,6 +1539,110 @@ out: @@ -1525,6 +1539,110 @@ out:
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)
{
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); @@ -52,6 +52,7 @@ bool parse_method(struct pool *pool, char *s);
bool extract_sockaddr(struct pool *pool, char *url);
bool auth_stratum(struct pool *pool);
bool initiate_stratum(struct pool *pool);
bool restart_stratum(struct pool *pool);
void suspend_stratum(struct pool *pool);
void dev_error(struct cgpu_info *dev, enum dev_reason reason);
void *realloc_strcat(char *ptr, char *s);

Loading…
Cancel
Save