mirror of
https://github.com/GOSTSec/sgminer
synced 2025-01-12 07:48:22 +00:00
Merge branch 'master' of git://github.com/ckolivas/cgminer.git
This commit is contained in:
commit
dd2b7e5fe0
30
NEWS
30
NEWS
@ -1,3 +1,33 @@
|
|||||||
|
Version 2.8.6 - October 29, 2012
|
||||||
|
|
||||||
|
- Shorten the initiate stratum connect timeout to 30 seconds.
|
||||||
|
- Shorten the stratum timeout on read to 90 seconds to detect unresponsive pool.
|
||||||
|
- Display best share difficulty on exit.
|
||||||
|
- Make stratum socket fail more robust on windows by disabling the send buffer.
|
||||||
|
- Reuse the same curl handle forcing a new connection instead of risking
|
||||||
|
derefencing.
|
||||||
|
- Add information about submission failure to stratum send.
|
||||||
|
- Only add stratum share to database if we succeeded in submitting it, with a
|
||||||
|
debug output saying it succeeded.
|
||||||
|
- Use keepalive with stratum sockets to improve its ability to detect broken
|
||||||
|
connections.
|
||||||
|
- Show only the URL in the status bar to avoid long prefixes making for extra
|
||||||
|
long lines.
|
||||||
|
- Display compact status in menu and update README to reflect current menu
|
||||||
|
entries.
|
||||||
|
- Add a compact display mode that does not list per device statistics in the
|
||||||
|
status window.
|
||||||
|
- Add blank spaces after best share displayed.
|
||||||
|
- Round a few static string arrays up to 4 byte boundaries for ARM.
|
||||||
|
- Display best share diff for scrypt as well.
|
||||||
|
- Show the best diff share as "best share" and add info to the README.
|
||||||
|
- Display the best diff share submitted so far.
|
||||||
|
- Redundant check.
|
||||||
|
- The work struct pointer in struct pc_data in findnonce is never freed yet
|
||||||
|
there is no need to allocate it separately so make struct work a static part of
|
||||||
|
the struct pc_data. s
|
||||||
|
|
||||||
|
|
||||||
Version 2.8.5 - October 23, 2012
|
Version 2.8.5 - October 23, 2012
|
||||||
|
|
||||||
- Handle crash exceptions by trying to restart cgminer unless the --no-restart
|
- Handle crash exceptions by trying to restart cgminer unless the --no-restart
|
||||||
|
25
README
25
README
@ -143,6 +143,7 @@ Options for both config file and command line:
|
|||||||
--auto-gpu Automatically adjust all GPU engine clock speeds to maintain a target temperature
|
--auto-gpu Automatically adjust all GPU engine clock speeds to maintain a target temperature
|
||||||
--balance Change multipool strategy from failover to even share balance
|
--balance Change multipool strategy from failover to even share balance
|
||||||
--benchmark Run cgminer in benchmark mode - produces no shares
|
--benchmark Run cgminer in benchmark mode - produces no shares
|
||||||
|
--compact Use compact display without per device statistics
|
||||||
--debug|-D Enable debug output
|
--debug|-D Enable debug output
|
||||||
--expiry|-E <arg> Upper bound on how many seconds after getting work we consider a share from it stale (default: 120)
|
--expiry|-E <arg> Upper bound on how many seconds after getting work we consider a share from it stale (default: 120)
|
||||||
--failover-only Don't leak work to backup pools when primary pool is lagging
|
--failover-only Don't leak work to backup pools when primary pool is lagging
|
||||||
@ -341,6 +342,7 @@ The following options are available while running with a single keypress:
|
|||||||
P gives you:
|
P gives you:
|
||||||
|
|
||||||
Current pool management strategy: Failover
|
Current pool management strategy: Failover
|
||||||
|
[F]ailover only disabled
|
||||||
[A]dd pool [R]emove pool [D]isable pool [E]nable pool
|
[A]dd pool [R]emove pool [D]isable pool [E]nable pool
|
||||||
[C]hange management strategy [S]witch pool [I]nformation
|
[C]hange management strategy [S]witch pool [I]nformation
|
||||||
|
|
||||||
@ -350,15 +352,21 @@ S gives you:
|
|||||||
[Q]ueue: 1
|
[Q]ueue: 1
|
||||||
[S]cantime: 60
|
[S]cantime: 60
|
||||||
[E]xpiry: 120
|
[E]xpiry: 120
|
||||||
[R]etries: -1
|
|
||||||
[P]ause: 5
|
|
||||||
[W]rite config file
|
[W]rite config file
|
||||||
|
[C]gminer restart
|
||||||
|
|
||||||
|
|
||||||
D gives you:
|
D gives you:
|
||||||
|
|
||||||
Toggle: [D]ebug [N]ormal [S]ilent [V]erbose [R]PC debug
|
[N]ormal [C]lear [S]ilent mode (disable all output)
|
||||||
[L]og interval [C]lear
|
[D]ebug:off
|
||||||
|
[P]er-device:off
|
||||||
|
[Q]uiet:off
|
||||||
|
[V]erbose:off
|
||||||
|
[R]PC debug:off
|
||||||
|
[W]orkTime details:off
|
||||||
|
co[M]pact: off
|
||||||
|
[L]og interval:5
|
||||||
|
|
||||||
|
|
||||||
Q quits the application.
|
Q quits the application.
|
||||||
@ -441,6 +449,15 @@ diminish return performance even if the hash rate might appear better. A good
|
|||||||
starting baseline intensity to try on dedicated miners is 9. Higher values are
|
starting baseline intensity to try on dedicated miners is 9. Higher values are
|
||||||
there to cope with future improvements in hardware.
|
there to cope with future improvements in hardware.
|
||||||
|
|
||||||
|
|
||||||
|
The block display shows:
|
||||||
|
Block: 0074c5e482e34a506d2a051a... Started: [17:17:22] Best share: 2.71K
|
||||||
|
|
||||||
|
This shows a short stretch of the current block, when the new block started,
|
||||||
|
and the all time best difficulty share you've submitted since starting cgminer
|
||||||
|
this time.
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
MULTIPOOL
|
MULTIPOOL
|
||||||
|
|
||||||
|
119
cgminer.c
119
cgminer.c
@ -92,6 +92,7 @@ bool use_syslog;
|
|||||||
bool opt_quiet;
|
bool opt_quiet;
|
||||||
bool opt_realquiet;
|
bool opt_realquiet;
|
||||||
bool opt_loginput;
|
bool opt_loginput;
|
||||||
|
bool opt_compact;
|
||||||
const int opt_cutofftemp = 95;
|
const int opt_cutofftemp = 95;
|
||||||
int opt_log_interval = 5;
|
int opt_log_interval = 5;
|
||||||
int opt_queue = 1;
|
int opt_queue = 1;
|
||||||
@ -213,15 +214,17 @@ const
|
|||||||
#endif
|
#endif
|
||||||
bool curses_active;
|
bool curses_active;
|
||||||
|
|
||||||
static char current_block[37];
|
static char current_block[40];
|
||||||
static char *current_hash;
|
static char *current_hash;
|
||||||
char *current_fullhash;
|
char *current_fullhash;
|
||||||
static char datestamp[40];
|
static char datestamp[40];
|
||||||
static char blocktime[30];
|
static char blocktime[30];
|
||||||
struct timeval block_timeval;
|
struct timeval block_timeval;
|
||||||
|
static char best_share[8] = "0";
|
||||||
|
static uint64_t best_diff = 0;
|
||||||
|
|
||||||
struct block {
|
struct block {
|
||||||
char hash[37];
|
char hash[40];
|
||||||
UT_hash_handle hh;
|
UT_hash_handle hh;
|
||||||
int block_no;
|
int block_no;
|
||||||
};
|
};
|
||||||
@ -549,10 +552,10 @@ static char *set_rr(enum pool_strategy *strategy)
|
|||||||
* stratum+tcp or by detecting a stratum server response */
|
* stratum+tcp or by detecting a stratum server response */
|
||||||
bool detect_stratum(struct pool *pool, char *url)
|
bool detect_stratum(struct pool *pool, char *url)
|
||||||
{
|
{
|
||||||
if (opt_scrypt)
|
if (!extract_sockaddr(pool, url))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!extract_sockaddr(pool, url))
|
if (opt_scrypt)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!strncasecmp(url, "stratum+tcp://", 14)) {
|
if (!strncasecmp(url, "stratum+tcp://", 14)) {
|
||||||
@ -852,6 +855,13 @@ static struct opt_table opt_config_table[] = {
|
|||||||
OPT_WITH_ARG("--bench-algo|-b",
|
OPT_WITH_ARG("--bench-algo|-b",
|
||||||
set_int_0_to_9999, opt_show_intval, &opt_bench_algo,
|
set_int_0_to_9999, opt_show_intval, &opt_bench_algo,
|
||||||
opt_hidden),
|
opt_hidden),
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_CURSES
|
||||||
|
OPT_WITHOUT_ARG("--compact",
|
||||||
|
opt_set_bool, &opt_compact,
|
||||||
|
"Use compact display without per device statistics"),
|
||||||
|
#endif
|
||||||
|
#ifdef WANT_CPUMINE
|
||||||
OPT_WITH_ARG("--cpu-threads|-t",
|
OPT_WITH_ARG("--cpu-threads|-t",
|
||||||
force_nthreads_int, opt_show_intval, &opt_n_threads,
|
force_nthreads_int, opt_show_intval, &opt_n_threads,
|
||||||
"Number of miner CPU threads"),
|
"Number of miner CPU threads"),
|
||||||
@ -1578,16 +1588,16 @@ static void curses_print_status(void)
|
|||||||
wclrtoeol(statuswin);
|
wclrtoeol(statuswin);
|
||||||
if (pool->has_stratum) {
|
if (pool->has_stratum) {
|
||||||
mvwprintw(statuswin, 4, 0, " Connected to %s with stratum as user %s",
|
mvwprintw(statuswin, 4, 0, " Connected to %s with stratum as user %s",
|
||||||
pool->stratum_url, pool->rpc_user);
|
pool->sockaddr_url, pool->rpc_user);
|
||||||
} else if ((pool_strategy == POOL_LOADBALANCE || pool_strategy == POOL_BALANCE) && total_pools > 1) {
|
} else if ((pool_strategy == POOL_LOADBALANCE || pool_strategy == POOL_BALANCE) && total_pools > 1) {
|
||||||
mvwprintw(statuswin, 4, 0, " Connected to multiple pools with%s LP",
|
mvwprintw(statuswin, 4, 0, " Connected to multiple pools with%s LP",
|
||||||
have_longpoll ? "": "out");
|
have_longpoll ? "": "out");
|
||||||
} else {
|
} else {
|
||||||
mvwprintw(statuswin, 4, 0, " Connected to %s with%s LP as user %s",
|
mvwprintw(statuswin, 4, 0, " Connected to %s with%s LP as user %s",
|
||||||
pool->rpc_url, have_longpoll ? "": "out", pool->rpc_user);
|
pool->sockaddr_url, have_longpoll ? "": "out", pool->rpc_user);
|
||||||
}
|
}
|
||||||
wclrtoeol(statuswin);
|
wclrtoeol(statuswin);
|
||||||
mvwprintw(statuswin, 5, 0, " Block: %s... Started: %s", current_hash, blocktime);
|
mvwprintw(statuswin, 5, 0, " Block: %s... Started: %s Best share: %s ", current_hash, blocktime, best_share);
|
||||||
mvwhline(statuswin, 6, 0, '-', 80);
|
mvwhline(statuswin, 6, 0, '-', 80);
|
||||||
mvwhline(statuswin, statusy - 1, 0, '-', 80);
|
mvwhline(statuswin, statusy - 1, 0, '-', 80);
|
||||||
mvwprintw(statuswin, devcursor - 1, 1, "[P]ool management %s[S]ettings [D]isplay options [Q]uit",
|
mvwprintw(statuswin, devcursor - 1, 1, "[P]ool management %s[S]ettings [D]isplay options [Q]uit",
|
||||||
@ -1610,7 +1620,7 @@ static void curses_print_devstatus(int thr_id)
|
|||||||
char displayed_hashes[16], displayed_rolling[16];
|
char displayed_hashes[16], displayed_rolling[16];
|
||||||
uint64_t dh64, dr64;
|
uint64_t dh64, dr64;
|
||||||
|
|
||||||
if (devcursor + cgpu->cgminer_id > LINES - 2)
|
if (devcursor + cgpu->cgminer_id > LINES - 2 || opt_compact)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cgpu->utility = cgpu->accepted / total_secs * 60;
|
cgpu->utility = cgpu->accepted / total_secs * 60;
|
||||||
@ -1670,14 +1680,13 @@ static void print_status(int thr_id)
|
|||||||
|
|
||||||
#ifdef HAVE_CURSES
|
#ifdef HAVE_CURSES
|
||||||
/* Check for window resize. Called with curses mutex locked */
|
/* Check for window resize. Called with curses mutex locked */
|
||||||
static inline bool change_logwinsize(void)
|
static inline void change_logwinsize(void)
|
||||||
{
|
{
|
||||||
int x, y, logx, logy;
|
int x, y, logx, logy;
|
||||||
bool ret = false;
|
|
||||||
|
|
||||||
getmaxyx(mainwin, y, x);
|
getmaxyx(mainwin, y, x);
|
||||||
if (x < 80 || y < 25)
|
if (x < 80 || y < 25)
|
||||||
return ret;
|
return;
|
||||||
|
|
||||||
if (y > statusy + 2 && statusy < logstart) {
|
if (y > statusy + 2 && statusy < logstart) {
|
||||||
if (y - 2 < logstart)
|
if (y - 2 < logstart)
|
||||||
@ -1687,17 +1696,13 @@ static inline bool change_logwinsize(void)
|
|||||||
logcursor = statusy + 1;
|
logcursor = statusy + 1;
|
||||||
mvwin(logwin, logcursor, 0);
|
mvwin(logwin, logcursor, 0);
|
||||||
wresize(statuswin, statusy, x);
|
wresize(statuswin, statusy, x);
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
y -= logcursor;
|
y -= logcursor;
|
||||||
getmaxyx(logwin, logy, logx);
|
getmaxyx(logwin, logy, logx);
|
||||||
/* Detect screen size change */
|
/* Detect screen size change */
|
||||||
if (x != logx || y != logy) {
|
if (x != logx || y != logy)
|
||||||
wresize(logwin, y, x);
|
wresize(logwin, y, x);
|
||||||
ret = true;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_winsizes(void)
|
static void check_winsizes(void)
|
||||||
@ -1707,6 +1712,7 @@ static void check_winsizes(void)
|
|||||||
if (curses_active_locked()) {
|
if (curses_active_locked()) {
|
||||||
int y, x;
|
int y, x;
|
||||||
|
|
||||||
|
erase();
|
||||||
x = getmaxx(statuswin);
|
x = getmaxx(statuswin);
|
||||||
if (logstart > LINES - 2)
|
if (logstart > LINES - 2)
|
||||||
statusy = LINES - 2;
|
statusy = LINES - 2;
|
||||||
@ -1722,6 +1728,18 @@ static void check_winsizes(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void switch_compact(void)
|
||||||
|
{
|
||||||
|
if (opt_compact) {
|
||||||
|
logstart = devcursor + 1;
|
||||||
|
logcursor = logstart + 1;
|
||||||
|
} else {
|
||||||
|
logstart = devcursor + total_devices + 1;
|
||||||
|
logcursor = logstart + 1;
|
||||||
|
}
|
||||||
|
check_winsizes();
|
||||||
|
}
|
||||||
|
|
||||||
/* For mandatory printing when mutex is already locked */
|
/* For mandatory printing when mutex is already locked */
|
||||||
void wlog(const char *f, ...)
|
void wlog(const char *f, ...)
|
||||||
{
|
{
|
||||||
@ -1770,6 +1788,7 @@ bool log_curses_only(int prio, const char *f, va_list ap)
|
|||||||
void clear_logwin(void)
|
void clear_logwin(void)
|
||||||
{
|
{
|
||||||
if (curses_active_locked()) {
|
if (curses_active_locked()) {
|
||||||
|
erase();
|
||||||
wclear(logwin);
|
wclear(logwin);
|
||||||
unlock_curses();
|
unlock_curses();
|
||||||
}
|
}
|
||||||
@ -1980,17 +1999,26 @@ static uint64_t share_diff(const struct work *work)
|
|||||||
if (unlikely(!d64))
|
if (unlikely(!d64))
|
||||||
d64 = 1;
|
d64 = 1;
|
||||||
ret = diffone / d64;
|
ret = diffone / d64;
|
||||||
|
if (ret > best_diff) {
|
||||||
|
best_diff = ret;
|
||||||
|
suffix_string(best_diff, best_share, 0);
|
||||||
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t scrypt_diff(const struct work *work)
|
static uint32_t scrypt_diff(const struct work *work)
|
||||||
{
|
{
|
||||||
const uint32_t scrypt_diffone = 0x0000fffful;
|
const uint32_t scrypt_diffone = 0x0000fffful;
|
||||||
uint32_t d32 = work->outputhash;
|
uint32_t d32 = work->outputhash, ret;
|
||||||
|
|
||||||
if (unlikely(!d32))
|
if (unlikely(!d32))
|
||||||
d32 = 1;
|
d32 = 1;
|
||||||
return scrypt_diffone / d32;
|
ret = scrypt_diffone / d32;
|
||||||
|
if (ret > best_diff) {
|
||||||
|
best_diff = ret;
|
||||||
|
suffix_string(best_diff, best_share, 0);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit)
|
static bool submit_upstream_work(struct work *work, CURL *curl, bool resubmit)
|
||||||
@ -2887,34 +2915,41 @@ static void *submit_work_thread(void *userdata)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (work->stratum) {
|
if (work->stratum) {
|
||||||
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;
|
||||||
char *noncehex;
|
char *noncehex;
|
||||||
char s[1024];
|
char s[1024];
|
||||||
|
|
||||||
memcpy(&sshare->work, work, sizeof(struct work));
|
|
||||||
|
|
||||||
/* Give the stratum share a unique id */
|
/* Give the stratum share a unique id */
|
||||||
mutex_lock(&sshare_lock);
|
swork_id++;
|
||||||
sshare->id = swork_id++;
|
|
||||||
HASH_ADD_INT(stratum_shares, id, sshare);
|
|
||||||
mutex_unlock(&sshare_lock);
|
|
||||||
|
|
||||||
nonce = *((uint32_t *)(work->data + 76));
|
nonce = *((uint32_t *)(work->data + 76));
|
||||||
noncehex = bin2hex((const unsigned char *)&nonce, 4);
|
noncehex = bin2hex((const unsigned char *)&nonce, 4);
|
||||||
|
|
||||||
memset(s, 0, 1024);
|
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, swork_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", (unsigned long)(hash32[6]), pool->pool_no);
|
||||||
|
|
||||||
if (unlikely(!stratum_send(pool, s, strlen(s)))) {
|
if (likely(stratum_send(pool, s, strlen(s)))) {
|
||||||
|
struct stratum_share *sshare = calloc(sizeof(struct stratum_share), 1);
|
||||||
|
|
||||||
|
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");
|
||||||
|
memcpy(&sshare->work, work, sizeof(struct work));
|
||||||
|
|
||||||
mutex_lock(&sshare_lock);
|
mutex_lock(&sshare_lock);
|
||||||
HASH_DEL(stratum_shares, sshare);
|
sshare->id = swork_id;
|
||||||
|
HASH_ADD_INT(stratum_shares, id, sshare);
|
||||||
mutex_unlock(&sshare_lock);
|
mutex_unlock(&sshare_lock);
|
||||||
free(sshare);
|
} else {
|
||||||
|
applog(LOG_INFO, "Failed to submit stratum share");
|
||||||
|
if (!pool_tset(pool, &pool->submit_fail)) {
|
||||||
|
total_ro++;
|
||||||
|
pool->remotefail_occasions++;
|
||||||
|
applog(LOG_WARNING, "Pool %d share submission failure", pool->pool_no);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
goto out;
|
goto out;
|
||||||
@ -3143,14 +3178,14 @@ static void set_curblock(char *hexstr, unsigned char *hash)
|
|||||||
|
|
||||||
strcpy(current_block, hexstr);
|
strcpy(current_block, hexstr);
|
||||||
swap256(hash_swap, hash);
|
swap256(hash_swap, hash);
|
||||||
swap256(block_hash_swap, hash+4);
|
swap256(block_hash_swap, hash + 4);
|
||||||
|
|
||||||
/* Don't free current_hash directly to avoid dereferencing when read
|
/* Don't free current_hash directly to avoid dereferencing when read
|
||||||
* elsewhere - and update block_timeval inside the same lock */
|
* elsewhere - and update block_timeval inside the same lock */
|
||||||
mutex_lock(&ch_lock);
|
mutex_lock(&ch_lock);
|
||||||
gettimeofday(&block_timeval, NULL);
|
gettimeofday(&block_timeval, NULL);
|
||||||
old_hash = current_hash;
|
old_hash = current_hash;
|
||||||
current_hash = bin2hex(hash_swap, 16);
|
current_hash = bin2hex(hash_swap + 2, 12);
|
||||||
free(old_hash);
|
free(old_hash);
|
||||||
old_hash = current_fullhash;
|
old_hash = current_fullhash;
|
||||||
current_fullhash = bin2hex(block_hash_swap, 32);
|
current_fullhash = bin2hex(block_hash_swap, 32);
|
||||||
@ -3793,13 +3828,16 @@ static void display_options(void)
|
|||||||
clear_logwin();
|
clear_logwin();
|
||||||
retry:
|
retry:
|
||||||
wlogprint("[N]ormal [C]lear [S]ilent mode (disable all output)\n");
|
wlogprint("[N]ormal [C]lear [S]ilent mode (disable all output)\n");
|
||||||
wlogprint("[D]ebug:%s\n[P]er-device:%s\n[Q]uiet:%s\n[V]erbose:%s\n[R]PC debug:%s\n[W]orkTime details:%s\n[L]og interval:%d\n",
|
wlogprint("[D]ebug:%s\n[P]er-device:%s\n[Q]uiet:%s\n[V]erbose:%s\n"
|
||||||
|
"[R]PC debug:%s\n[W]orkTime details:%s\nco[M]pact: %s\n"
|
||||||
|
"[L]og interval:%d\n",
|
||||||
opt_debug ? "on" : "off",
|
opt_debug ? "on" : "off",
|
||||||
want_per_device_stats? "on" : "off",
|
want_per_device_stats? "on" : "off",
|
||||||
opt_quiet ? "on" : "off",
|
opt_quiet ? "on" : "off",
|
||||||
opt_log_output ? "on" : "off",
|
opt_log_output ? "on" : "off",
|
||||||
opt_protocol ? "on" : "off",
|
opt_protocol ? "on" : "off",
|
||||||
opt_worktime ? "on" : "off",
|
opt_worktime ? "on" : "off",
|
||||||
|
opt_compact ? "on" : "off",
|
||||||
opt_log_interval);
|
opt_log_interval);
|
||||||
wlogprint("Select an option or any other key to return\n");
|
wlogprint("Select an option or any other key to return\n");
|
||||||
input = getch();
|
input = getch();
|
||||||
@ -3818,8 +3856,10 @@ retry:
|
|||||||
opt_debug = false;
|
opt_debug = false;
|
||||||
opt_quiet = false;
|
opt_quiet = false;
|
||||||
opt_protocol = false;
|
opt_protocol = false;
|
||||||
|
opt_compact = false;
|
||||||
want_per_device_stats = false;
|
want_per_device_stats = false;
|
||||||
wlogprint("Output mode reset to normal\n");
|
wlogprint("Output mode reset to normal\n");
|
||||||
|
switch_compact();
|
||||||
goto retry;
|
goto retry;
|
||||||
} else if (!strncasecmp(&input, "d", 1)) {
|
} else if (!strncasecmp(&input, "d", 1)) {
|
||||||
opt_debug ^= true;
|
opt_debug ^= true;
|
||||||
@ -3828,6 +3868,11 @@ retry:
|
|||||||
opt_quiet = false;
|
opt_quiet = false;
|
||||||
wlogprint("Debug mode %s\n", opt_debug ? "enabled" : "disabled");
|
wlogprint("Debug mode %s\n", opt_debug ? "enabled" : "disabled");
|
||||||
goto retry;
|
goto retry;
|
||||||
|
} else if (!strncasecmp(&input, "m", 1)) {
|
||||||
|
opt_compact ^= true;
|
||||||
|
wlogprint("Compact mode %s\n", opt_compact ? "enabled" : "disabled");
|
||||||
|
switch_compact();
|
||||||
|
goto retry;
|
||||||
} else if (!strncasecmp(&input, "p", 1)) {
|
} else if (!strncasecmp(&input, "p", 1)) {
|
||||||
want_per_device_stats ^= true;
|
want_per_device_stats ^= true;
|
||||||
opt_log_output = want_per_device_stats;
|
opt_log_output = want_per_device_stats;
|
||||||
@ -4278,11 +4323,11 @@ static void *stratum_thread(void *userdata)
|
|||||||
|
|
||||||
FD_ZERO(&rd);
|
FD_ZERO(&rd);
|
||||||
FD_SET(pool->sock, &rd);
|
FD_SET(pool->sock, &rd);
|
||||||
timeout.tv_sec = 120;
|
timeout.tv_sec = 90;
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
/* The protocol specifies that notify messages should be sent
|
/* The protocol specifies that notify messages should be sent
|
||||||
* every minute so if we fail to receive any for 2 minutes we
|
* every minute so if we fail to receive any for 90 seconds we
|
||||||
* assume the connection has been dropped and treat this pool
|
* assume the connection has been dropped and treat this pool
|
||||||
* as dead */
|
* as dead */
|
||||||
select(pool->sock + 1, &rd, NULL, NULL, &timeout);
|
select(pool->sock + 1, &rd, NULL, NULL, &timeout);
|
||||||
@ -5646,6 +5691,7 @@ static void print_summary(void)
|
|||||||
|
|
||||||
applog(LOG_WARNING, "Average hashrate: %.1f %shash/s", displayed_hashes, mhash_base? "Mega" : "Kilo");
|
applog(LOG_WARNING, "Average hashrate: %.1f %shash/s", displayed_hashes, mhash_base? "Mega" : "Kilo");
|
||||||
applog(LOG_WARNING, "Solved blocks: %d", found_blocks);
|
applog(LOG_WARNING, "Solved blocks: %d", found_blocks);
|
||||||
|
applog(LOG_WARNING, "Best share difficulty: %s", best_share);
|
||||||
applog(LOG_WARNING, "Queued work requests: %d", total_getworks);
|
applog(LOG_WARNING, "Queued work requests: %d", total_getworks);
|
||||||
applog(LOG_WARNING, "Share submissions: %d", total_accepted + total_rejected);
|
applog(LOG_WARNING, "Share submissions: %d", total_accepted + total_rejected);
|
||||||
applog(LOG_WARNING, "Accepted shares: %d", total_accepted);
|
applog(LOG_WARNING, "Accepted shares: %d", total_accepted);
|
||||||
@ -6291,12 +6337,13 @@ int main(int argc, char *argv[])
|
|||||||
for (i = 0; i < total_devices; ++i)
|
for (i = 0; i < total_devices; ++i)
|
||||||
devices[i]->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;
|
devices[i]->cgminer_stats.getwork_wait_min.tv_sec = MIN_SEC_UNSET;
|
||||||
|
|
||||||
|
if (!opt_compact) {
|
||||||
logstart += total_devices;
|
logstart += total_devices;
|
||||||
logcursor = logstart + 1;
|
logcursor = logstart + 1;
|
||||||
|
|
||||||
#ifdef HAVE_CURSES
|
#ifdef HAVE_CURSES
|
||||||
check_winsizes();
|
check_winsizes();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (!total_pools) {
|
if (!total_pools) {
|
||||||
applog(LOG_WARNING, "Need to specify at least one pool server.");
|
applog(LOG_WARNING, "Need to specify at least one pool server.");
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||||
m4_define([v_maj], [2])
|
m4_define([v_maj], [2])
|
||||||
m4_define([v_min], [8])
|
m4_define([v_min], [8])
|
||||||
m4_define([v_mic], [5])
|
m4_define([v_mic], [6])
|
||||||
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##--##
|
||||||
m4_define([v_ver], [v_maj.v_min.v_mic])
|
m4_define([v_ver], [v_maj.v_min.v_mic])
|
||||||
m4_define([lt_rev], m4_eval(v_maj + v_min))
|
m4_define([lt_rev], m4_eval(v_maj + v_min))
|
||||||
|
68
util.c
68
util.c
@ -196,39 +196,41 @@ out:
|
|||||||
return ptrlen;
|
return ptrlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
int json_rpc_call_sockopt_cb(void __maybe_unused *userdata, curl_socket_t fd,
|
static int keep_sockalive(SOCKETTYPE fd)
|
||||||
curlsocktype __maybe_unused purpose)
|
|
||||||
{
|
{
|
||||||
int tcp_keepidle = 120;
|
const int tcp_keepidle = 60;
|
||||||
int tcp_keepintvl = 120;
|
const int tcp_keepintvl = 60;
|
||||||
|
const int keepalive = 1;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
int keepalive = 1;
|
const int tcp_keepcnt = 5;
|
||||||
int tcp_keepcnt = 5;
|
|
||||||
|
|
||||||
if (unlikely(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive))))
|
if (unlikely(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &keepalive, sizeof(keepalive))))
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
# ifdef __linux
|
# ifdef __linux
|
||||||
|
|
||||||
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt))))
|
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPCNT, &tcp_keepcnt, sizeof(tcp_keepcnt))))
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle))))
|
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPIDLE, &tcp_keepidle, sizeof(tcp_keepidle))))
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl))))
|
if (unlikely(setsockopt(fd, SOL_TCP, TCP_KEEPINTVL, &tcp_keepintvl, sizeof(tcp_keepintvl))))
|
||||||
return 1;
|
ret = 1;
|
||||||
# endif /* __linux */
|
# endif /* __linux */
|
||||||
# ifdef __APPLE_CC__
|
# ifdef __APPLE_CC__
|
||||||
|
|
||||||
if (unlikely(setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &tcp_keepintvl, sizeof(tcp_keepintvl))))
|
if (unlikely(setsockopt(fd, IPPROTO_TCP, TCP_KEEPALIVE, &tcp_keepintvl, sizeof(tcp_keepintvl))))
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
# endif /* __APPLE_CC__ */
|
# endif /* __APPLE_CC__ */
|
||||||
|
|
||||||
#else /* WIN32 */
|
#else /* WIN32 */
|
||||||
|
|
||||||
|
const int zero = 0;
|
||||||
struct tcp_keepalive vals;
|
struct tcp_keepalive vals;
|
||||||
vals.onoff = 1;
|
vals.onoff = 1;
|
||||||
vals.keepalivetime = tcp_keepidle * 1000;
|
vals.keepalivetime = tcp_keepidle * 1000;
|
||||||
@ -236,12 +238,26 @@ int json_rpc_call_sockopt_cb(void __maybe_unused *userdata, curl_socket_t fd,
|
|||||||
|
|
||||||
DWORD outputBytes;
|
DWORD outputBytes;
|
||||||
|
|
||||||
if (unlikely(WSAIoctl(fd, SIO_KEEPALIVE_VALS, &vals, sizeof(vals), NULL, 0, &outputBytes, NULL, NULL)))
|
if (unlikely(setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (const char *)&keepalive, sizeof(keepalive))))
|
||||||
return 1;
|
ret = 1;
|
||||||
|
|
||||||
|
if (unlikely(WSAIoctl(fd, SIO_KEEPALIVE_VALS, &vals, sizeof(vals), NULL, 0, &outputBytes, NULL, NULL)))
|
||||||
|
ret = 1;
|
||||||
|
|
||||||
|
/* Windows happily submits indefinitely to the send buffer blissfully
|
||||||
|
* unaware nothing is getting there without gracefully failing unless
|
||||||
|
* we disable the send buffer */
|
||||||
|
if (unlikely(setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const char *)&zero, sizeof(zero))))
|
||||||
|
ret = 1;
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int json_rpc_call_sockopt_cb(void __maybe_unused *userdata, curl_socket_t fd,
|
||||||
|
curlsocktype __maybe_unused purpose)
|
||||||
|
{
|
||||||
|
return keep_sockalive(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void last_nettime(struct timeval *last)
|
static void last_nettime(struct timeval *last)
|
||||||
@ -823,6 +839,7 @@ bool extract_sockaddr(struct pool *pool, char *url)
|
|||||||
struct addrinfo hints, *res;
|
struct addrinfo hints, *res;
|
||||||
int url_len, port_len = 0;
|
int url_len, port_len = 0;
|
||||||
|
|
||||||
|
pool->sockaddr_url = url;
|
||||||
url_begin = strstr(url, "//");
|
url_begin = strstr(url, "//");
|
||||||
if (!url_begin)
|
if (!url_begin)
|
||||||
url_begin = url;
|
url_begin = url;
|
||||||
@ -881,8 +898,8 @@ static bool __stratum_send(struct pool *pool, char *s, ssize_t len)
|
|||||||
|
|
||||||
while (len > 0 ) {
|
while (len > 0 ) {
|
||||||
struct timeval timeout = {0, 0};
|
struct timeval timeout = {0, 0};
|
||||||
CURLcode rc = CURLE_SEND_ERROR;
|
|
||||||
size_t sent = 0;
|
size_t sent = 0;
|
||||||
|
CURLcode rc;
|
||||||
fd_set wd;
|
fd_set wd;
|
||||||
|
|
||||||
FD_ZERO(&wd);
|
FD_ZERO(&wd);
|
||||||
@ -891,7 +908,6 @@ static bool __stratum_send(struct pool *pool, char *s, ssize_t len)
|
|||||||
applog(LOG_DEBUG, "Write select failed on pool %d sock", pool->pool_no);
|
applog(LOG_DEBUG, "Write select failed on pool %d sock", pool->pool_no);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (likely(pool->stratum_curl))
|
|
||||||
rc = curl_easy_send(pool->stratum_curl, s + ssent, len, &sent);
|
rc = curl_easy_send(pool->stratum_curl, s + ssent, len, &sent);
|
||||||
if (rc != CURLE_OK) {
|
if (rc != CURLE_OK) {
|
||||||
applog(LOG_DEBUG, "Failed to curl_easy_send in stratum_send");
|
applog(LOG_DEBUG, "Failed to curl_easy_send in stratum_send");
|
||||||
@ -925,7 +941,6 @@ static void clear_sock(struct pool *pool)
|
|||||||
mutex_lock(&pool->stratum_lock);
|
mutex_lock(&pool->stratum_lock);
|
||||||
/* Ignore return code of curl_easy_recv since we're just clearing
|
/* Ignore return code of curl_easy_recv since we're just clearing
|
||||||
* anything in the socket if it's still alive */
|
* anything in the socket if it's still alive */
|
||||||
if (likely(pool->stratum_curl))
|
|
||||||
curl_easy_recv(pool->stratum_curl, pool->sockbuf, RECVSIZE, &n);
|
curl_easy_recv(pool->stratum_curl, pool->sockbuf, RECVSIZE, &n);
|
||||||
mutex_unlock(&pool->stratum_lock);
|
mutex_unlock(&pool->stratum_lock);
|
||||||
strcpy(pool->sockbuf, "");
|
strcpy(pool->sockbuf, "");
|
||||||
@ -962,9 +977,9 @@ char *recv_line(struct pool *pool)
|
|||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
|
|
||||||
if (!strstr(pool->sockbuf, "\n")) {
|
if (!strstr(pool->sockbuf, "\n")) {
|
||||||
CURLcode rc = CURLE_RECV_ERROR;
|
|
||||||
char s[RBUFSIZE];
|
char s[RBUFSIZE];
|
||||||
size_t sspace;
|
size_t sspace;
|
||||||
|
CURLcode rc;
|
||||||
|
|
||||||
if (!sock_full(pool, true)) {
|
if (!sock_full(pool, true)) {
|
||||||
applog(LOG_DEBUG, "Timed out waiting for data on sock_full");
|
applog(LOG_DEBUG, "Timed out waiting for data on sock_full");
|
||||||
@ -973,7 +988,6 @@ char *recv_line(struct pool *pool)
|
|||||||
memset(s, 0, RBUFSIZE);
|
memset(s, 0, RBUFSIZE);
|
||||||
|
|
||||||
mutex_lock(&pool->stratum_lock);
|
mutex_lock(&pool->stratum_lock);
|
||||||
if (likely(pool->stratum_curl))
|
|
||||||
rc = curl_easy_recv(pool->stratum_curl, s, RECVSIZE, &n);
|
rc = curl_easy_recv(pool->stratum_curl, s, RECVSIZE, &n);
|
||||||
mutex_unlock(&pool->stratum_lock);
|
mutex_unlock(&pool->stratum_lock);
|
||||||
|
|
||||||
@ -1314,7 +1328,6 @@ bool initiate_stratum(struct pool *pool)
|
|||||||
|
|
||||||
mutex_lock(&pool->stratum_lock);
|
mutex_lock(&pool->stratum_lock);
|
||||||
pool->stratum_active = false;
|
pool->stratum_active = false;
|
||||||
|
|
||||||
if (!pool->stratum_curl) {
|
if (!pool->stratum_curl) {
|
||||||
pool->stratum_curl = curl_easy_init();
|
pool->stratum_curl = curl_easy_init();
|
||||||
if (unlikely(!pool->stratum_curl))
|
if (unlikely(!pool->stratum_curl))
|
||||||
@ -1327,7 +1340,8 @@ bool initiate_stratum(struct pool *pool)
|
|||||||
memset(s, 0, RBUFSIZE);
|
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_CONNECTTIMEOUT, 60);
|
curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1);
|
||||||
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30);
|
||||||
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str);
|
||||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, s);
|
curl_easy_setopt(curl, CURLOPT_URL, s);
|
||||||
@ -1346,6 +1360,7 @@ bool initiate_stratum(struct pool *pool)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&pool->sock);
|
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&pool->sock);
|
||||||
|
keep_sockalive(pool->sock);
|
||||||
|
|
||||||
sprintf(s, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": []}", swork_id++);
|
sprintf(s, "{\"id\": %d, \"method\": \"mining.subscribe\", \"params\": []}", swork_id++);
|
||||||
|
|
||||||
@ -1414,15 +1429,8 @@ out:
|
|||||||
applog(LOG_DEBUG, "Pool %d confirmed mining.subscribe with extranonce1 %s extran2size %d",
|
applog(LOG_DEBUG, "Pool %d confirmed mining.subscribe with extranonce1 %s extran2size %d",
|
||||||
pool->pool_no, pool->nonce1, pool->n2size);
|
pool->pool_no, pool->nonce1, pool->n2size);
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
applog(LOG_DEBUG, "Initiate stratum failed, disabling stratum_active");
|
applog(LOG_DEBUG, "Initiate stratum failed");
|
||||||
mutex_lock(&pool->stratum_lock);
|
|
||||||
if (curl) {
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
pool->stratum_curl = NULL;
|
|
||||||
}
|
|
||||||
mutex_unlock(&pool->stratum_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user