Handle network errors properly
This commit is contained in:
parent
35ae813dc8
commit
14f953e0f8
5 changed files with 55 additions and 71 deletions
6
NEWS
6
NEWS
|
@ -1,3 +1,8 @@
|
|||
Version 2.1.1 - Jan 20, 2012
|
||||
|
||||
- Handle network errors properly
|
||||
- Make scantime retargeting more accurate
|
||||
|
||||
Version 2.1 - Jan 19, 2012
|
||||
|
||||
- Share the same work among all threads
|
||||
|
@ -9,6 +14,7 @@ Version 2.0 - Jan 16, 2012
|
|||
- Change default port to 9332 for Litecoin and remove default credentials
|
||||
- Add 'scrypt' as the default algorithm and remove other algorithms (ArtForz)
|
||||
- Optimize scrypt for x86 and x86-64
|
||||
- Make scantime retargeting less granular (ArtForz)
|
||||
- Test the whole hash instead of just looking at the high 32 bits
|
||||
- Add configurable timeout, with a default of 180 seconds
|
||||
- Add share summary output (inlikeflynn)
|
||||
|
|
80
cpu-miner.c
80
cpu-miner.c
|
@ -101,7 +101,7 @@ int opt_scantime = 5;
|
|||
static json_t *opt_config;
|
||||
static const bool opt_time = true;
|
||||
static enum sha256_algos opt_algo = ALGO_SCRYPT;
|
||||
int opt_n_threads;
|
||||
static int opt_n_threads;
|
||||
static int num_processors;
|
||||
static char *rpc_url;
|
||||
static char *rpc_userpass;
|
||||
|
@ -292,7 +292,7 @@ static bool submit_upstream_work(CURL *curl, const struct work *work)
|
|||
hexstr);
|
||||
|
||||
/* issue JSON-RPC request */
|
||||
val = json_rpc_call(curl, rpc_url, rpc_userpass, s, false, false);
|
||||
val = json_rpc_call(curl, rpc_url, rpc_userpass, s, false, false, NULL);
|
||||
if (unlikely(!val)) {
|
||||
applog(LOG_ERR, "submit_upstream_work json_rpc_call failed");
|
||||
goto out;
|
||||
|
@ -312,7 +312,7 @@ static bool submit_upstream_work(CURL *curl, const struct work *work)
|
|||
accepted_count,
|
||||
accepted_count + rejected_count,
|
||||
100. * accepted_count / (accepted_count + rejected_count),
|
||||
hashrate,
|
||||
1e-3 * hashrate,
|
||||
json_is_true(res) ? "(yay!!!)" : "(booooo)");
|
||||
|
||||
json_decref(val);
|
||||
|
@ -333,7 +333,7 @@ static bool get_upstream_work(CURL *curl, struct work *work)
|
|||
bool rc;
|
||||
|
||||
val = json_rpc_call(curl, rpc_url, rpc_userpass, rpc_req,
|
||||
want_longpoll, false);
|
||||
want_longpoll, false, NULL);
|
||||
if (!val)
|
||||
return false;
|
||||
|
||||
|
@ -456,22 +456,6 @@ static void *workio_thread(void *userdata)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void hashmeter(int thr_id, const struct timeval *diff,
|
||||
unsigned long hashes_done)
|
||||
{
|
||||
double khashes, secs;
|
||||
|
||||
khashes = hashes_done / 1000.0;
|
||||
secs = (double)diff->tv_sec + ((double)diff->tv_usec / 1000000.0);
|
||||
|
||||
thr_hashrates[thr_id] = khashes / secs;
|
||||
|
||||
if (!opt_quiet)
|
||||
applog(LOG_INFO, "thread %d: %lu hashes, %.2f khash/s",
|
||||
thr_id, hashes_done,
|
||||
khashes / secs);
|
||||
}
|
||||
|
||||
static bool get_work(struct thr_info *thr, struct work *work)
|
||||
{
|
||||
struct workio_cmd *wc;
|
||||
|
@ -535,7 +519,7 @@ static void *miner_thread(void *userdata)
|
|||
{
|
||||
struct thr_info *mythr = userdata;
|
||||
int thr_id = mythr->id;
|
||||
uint32_t max_nonce = 0xffffff;
|
||||
uint32_t max_nonce;
|
||||
uint32_t next_nonce;
|
||||
unsigned char *scratchbuf = NULL;
|
||||
|
||||
|
@ -553,15 +537,13 @@ static void *miner_thread(void *userdata)
|
|||
if (opt_algo == ALGO_SCRYPT)
|
||||
{
|
||||
scratchbuf = scrypt_buffer_alloc();
|
||||
max_nonce = 0xffff * opt_n_threads;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
struct work work __attribute__((aligned(128)));
|
||||
unsigned long hashes_done;
|
||||
struct timeval tv_start, tv_end, diff;
|
||||
int diffms;
|
||||
uint64_t max64;
|
||||
int64_t max64;
|
||||
bool rc;
|
||||
|
||||
/* obtain new work from internal workio thread */
|
||||
|
@ -579,20 +561,29 @@ static void *miner_thread(void *userdata)
|
|||
}
|
||||
if (memcmp(work.data, g_work.data, 76)) {
|
||||
memcpy(&work, &g_work, sizeof(struct work));
|
||||
next_nonce = thr_id;
|
||||
next_nonce = 0xffffffffU / opt_n_threads * thr_id;
|
||||
}
|
||||
pthread_mutex_unlock(&g_work_lock);
|
||||
|
||||
work_restart[thr_id].restart = 0;
|
||||
|
||||
/* adjust max_nonce to meet target scan time */
|
||||
max64 = (g_work_time + opt_scantime - time(NULL)) *
|
||||
(int64_t)thr_hashrates[thr_id];
|
||||
if (max64 <= 0)
|
||||
max64 = 0xfffLL;
|
||||
if (next_nonce + max64 > 0xfffffffeLL)
|
||||
max_nonce = 0xfffffffeU;
|
||||
else
|
||||
max_nonce = next_nonce + max64;
|
||||
|
||||
hashes_done = 0;
|
||||
gettimeofday(&tv_start, NULL);
|
||||
|
||||
/* scan nonces for a proof-of-work hash */
|
||||
switch (opt_algo) {
|
||||
case ALGO_SCRYPT:
|
||||
rc = scanhash_scrypt(thr_id, work.data, scratchbuf,
|
||||
work.target, next_nonce + max_nonce,
|
||||
&next_nonce, &hashes_done);
|
||||
rc = scanhash_scrypt(thr_id, work.data, scratchbuf, work.target,
|
||||
max_nonce, &next_nonce, &hashes_done);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -603,19 +594,11 @@ static void *miner_thread(void *userdata)
|
|||
/* record scanhash elapsed time */
|
||||
gettimeofday(&tv_end, NULL);
|
||||
timeval_subtract(&diff, &tv_end, &tv_start);
|
||||
|
||||
hashmeter(thr_id, &diff, hashes_done);
|
||||
|
||||
/* adjust max_nonce to meet target scan time */
|
||||
diffms = diff.tv_sec * 1000 + diff.tv_usec / 1000;
|
||||
if (diffms > 0) {
|
||||
max64 =
|
||||
((uint64_t)hashes_done * opt_scantime * 1000) / diffms;
|
||||
max64 *= opt_n_threads;
|
||||
if (max64 > 0xffff0000ULL)
|
||||
max64 = 0xffff0000ULL;
|
||||
max_nonce = max64;
|
||||
}
|
||||
thr_hashrates[thr_id] =
|
||||
hashes_done / (diff.tv_sec + 1e-6 * diff.tv_usec);
|
||||
if (!opt_quiet)
|
||||
applog(LOG_INFO, "thread %d: %lu hashes, %.2f khash/s",
|
||||
thr_id, hashes_done, 1e-3 * thr_hashrates[thr_id]);
|
||||
|
||||
/* if nonce found, submit work */
|
||||
if (rc && !submit_work(mythr, &work))
|
||||
|
@ -677,9 +660,10 @@ static void *longpoll_thread(void *userdata)
|
|||
|
||||
while (1) {
|
||||
json_t *val;
|
||||
int err;
|
||||
|
||||
val = json_rpc_call(curl, lp_url, rpc_userpass, rpc_req,
|
||||
false, true);
|
||||
false, true, &err);
|
||||
if (likely(val)) {
|
||||
failures = 0;
|
||||
applog(LOG_INFO, "LONGPOLL detected new block");
|
||||
|
@ -691,10 +675,14 @@ static void *longpoll_thread(void *userdata)
|
|||
restart_threads();
|
||||
}
|
||||
pthread_mutex_unlock(&g_work_lock);
|
||||
} else {
|
||||
/* longpoll failed, keep trying */
|
||||
json_decref(val);
|
||||
} else if (err != CURLE_OPERATION_TIMEDOUT) {
|
||||
pthread_mutex_lock(&g_work_lock);
|
||||
g_work_time -= opt_scantime;
|
||||
pthread_mutex_unlock(&g_work_lock);
|
||||
restart_threads();
|
||||
sleep(opt_fail_pause);
|
||||
}
|
||||
json_decref(val);
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
3
miner.h
3
miner.h
|
@ -123,7 +123,7 @@ extern bool opt_debug;
|
|||
extern bool opt_protocol;
|
||||
extern const uint32_t sha256_init_state[];
|
||||
extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
|
||||
const char *rpc_req, bool, bool);
|
||||
const char *rpc_req, bool, bool, int *);
|
||||
extern char *bin2hex(const unsigned char *p, size_t len);
|
||||
extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len);
|
||||
|
||||
|
@ -141,7 +141,6 @@ extern int opt_scantime;
|
|||
extern int opt_timeout;
|
||||
extern bool want_longpoll;
|
||||
extern bool have_longpoll;
|
||||
extern int opt_n_threads;
|
||||
struct thread_q;
|
||||
|
||||
struct work_restart {
|
||||
|
|
29
scrypt.c
29
scrypt.c
|
@ -520,7 +520,7 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf,
|
|||
uint32_t data3[20], hash3[8];
|
||||
int throughput;
|
||||
#endif
|
||||
unsigned long c = 0;
|
||||
unsigned long first_nonce = *next_nonce;
|
||||
uint32_t n = *next_nonce;
|
||||
uint32_t Htarg = le32dec(&((const uint32_t *)ptarget)[7]);
|
||||
int i;
|
||||
|
@ -533,24 +533,18 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf,
|
|||
throughput = scrypt_best_throughput();
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
data[19] = n;
|
||||
n += opt_n_threads;
|
||||
++c;
|
||||
do {
|
||||
data[19] = n++;
|
||||
#ifdef SCRYPT_3WAY
|
||||
if (throughput >= 2 && n <= max_nonce) {
|
||||
data2[19] = n;
|
||||
n += opt_n_threads;
|
||||
++c;
|
||||
data2[19] = n++;
|
||||
if (throughput >= 3 && n <= max_nonce) {
|
||||
data3[19] = n;
|
||||
n += opt_n_threads;
|
||||
++c;
|
||||
data3[19] = n++;
|
||||
scrypt_1024_1_1_256_sp_3way(data, data2, data3, hash, hash2, hash3, scratchbuf);
|
||||
if (hash3[7] < Htarg || hash3[7] == Htarg && test_hash(hash3, (uint32_t *)ptarget)) {
|
||||
be32enc(&((uint32_t *)pdata)[19], data3[19]);
|
||||
*next_nonce = n;
|
||||
*hashes_done = c;
|
||||
*hashes_done = n - first_nonce;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -559,7 +553,7 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf,
|
|||
if (hash2[7] < Htarg || hash2[7] == Htarg && test_hash(hash2, (uint32_t *)ptarget)) {
|
||||
be32enc(&((uint32_t *)pdata)[19], data2[19]);
|
||||
*next_nonce = n;
|
||||
*hashes_done = c;
|
||||
*hashes_done = n - first_nonce;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -568,19 +562,16 @@ int scanhash_scrypt(int thr_id, unsigned char *pdata, unsigned char *scratchbuf,
|
|||
#else
|
||||
scrypt_1024_1_1_256_sp(data, hash, scratchbuf);
|
||||
#endif
|
||||
|
||||
if (hash[7] < Htarg || hash[7] == Htarg && test_hash(hash, (uint32_t *)ptarget)) {
|
||||
be32enc(&((uint32_t *)pdata)[19], data[19]);
|
||||
*next_nonce = n;
|
||||
*hashes_done = c;
|
||||
*hashes_done = n - first_nonce;
|
||||
return true;
|
||||
}
|
||||
} while (n <= max_nonce && !work_restart[thr_id].restart);
|
||||
|
||||
if ((n > max_nonce) || work_restart[thr_id].restart)
|
||||
break;
|
||||
}
|
||||
*next_nonce = n;
|
||||
*hashes_done = c;
|
||||
*hashes_done = n - first_nonce;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
6
util.c
6
util.c
|
@ -205,7 +205,7 @@ out:
|
|||
|
||||
json_t *json_rpc_call(CURL *curl, const char *url,
|
||||
const char *userpass, const char *rpc_req,
|
||||
bool longpoll_scan, bool longpoll)
|
||||
bool longpoll_scan, bool longpoll, int *curl_err)
|
||||
{
|
||||
json_t *val, *err_val, *res_val;
|
||||
int rc;
|
||||
|
@ -266,11 +266,11 @@ json_t *json_rpc_call(CURL *curl, const char *url,
|
|||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
rc = curl_easy_perform(curl);
|
||||
if (curl_err != NULL)
|
||||
*curl_err = rc;
|
||||
if (rc) {
|
||||
if (!(longpoll && rc == CURLE_OPERATION_TIMEDOUT))
|
||||
applog(LOG_ERR, "HTTP request failed: %s", curl_err_str);
|
||||
if (longpoll && rc != CURLE_OPERATION_TIMEDOUT)
|
||||
sleep(30);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue