From 5592fa2c2de48f08f288a695366b403034e8ecd3 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 5 Oct 2015 15:01:07 +1100 Subject: [PATCH 01/17] Add 7 day stats to workers --- src/stratifier.c | 138 ++++++++++++++++++++++++++--------------------- 1 file changed, 77 insertions(+), 61 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 7073f97a..8cebb54e 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -28,6 +28,14 @@ #include "uthash.h" #include "utlist.h" +#define MIN1 60 +#define MIN5 300 +#define MIN15 900 +#define HOUR 3600 +#define HOUR6 21600 +#define DAY 86400 +#define WEEK 604800 + /* Consistent across all pool instances */ static const char *workpadding = "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"; static const char *scriptsig_header = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff"; @@ -200,6 +208,7 @@ struct worker_instance { double dsps5; double dsps60; double dsps1440; + double dsps10080; tv_t last_share; tv_t last_update; time_t start_time; @@ -2155,11 +2164,11 @@ static void read_userstats(ckpool_t *ckp, user_instance_t *user) if (tvsec_diff > 60) { LOGINFO("Old user stats indicate not logged for %d seconds, decaying stats", tvsec_diff); - decay_time(&user->dsps1, 0, tvsec_diff, 60); - decay_time(&user->dsps5, 0, tvsec_diff, 300); - decay_time(&user->dsps60, 0, tvsec_diff, 3600); - decay_time(&user->dsps1440, 0, tvsec_diff, 86400); - decay_time(&user->dsps10080, 0, tvsec_diff, 604800); + decay_time(&user->dsps1, 0, tvsec_diff, MIN1); + decay_time(&user->dsps5, 0, tvsec_diff, MIN5); + decay_time(&user->dsps60, 0, tvsec_diff, HOUR); + decay_time(&user->dsps1440, 0, tvsec_diff, DAY); + decay_time(&user->dsps10080, 0, tvsec_diff, WEEK); } } @@ -2197,6 +2206,7 @@ static void read_workerstats(ckpool_t *ckp, worker_instance_t *worker) worker->dsps5 = dsps_from_key(val, "hashrate5m"); worker->dsps60 = dsps_from_key(val, "hashrate1d"); worker->dsps1440 = dsps_from_key(val, "hashrate1d"); + worker->dsps10080 = dsps_from_key(val, "hashrate7d"); json_get_double(&worker->best_diff, val, "bestshare"); json_get_int64(&worker->last_update.tv_sec, val, "lastupdate"); LOGINFO("Successfully read worker %s stats %f %f %f %f %f", worker->workername, @@ -2207,10 +2217,10 @@ static void read_workerstats(ckpool_t *ckp, worker_instance_t *worker) if (tvsec_diff > 60) { LOGINFO("Old worker stats indicate not logged for %d seconds, decaying stats", tvsec_diff); - decay_time(&worker->dsps1, 0, tvsec_diff, 60); - decay_time(&worker->dsps5, 0, tvsec_diff, 300); - decay_time(&worker->dsps60, 0, tvsec_diff, 3600); - decay_time(&worker->dsps1440, 0, tvsec_diff, 86400); + decay_time(&worker->dsps1, 0, tvsec_diff, MIN1); + decay_time(&worker->dsps5, 0, tvsec_diff, MIN5); + decay_time(&worker->dsps60, 0, tvsec_diff, HOUR); + decay_time(&worker->dsps1440, 0, tvsec_diff, DAY); } } @@ -2685,27 +2695,28 @@ static void add_submit(ckpool_t *ckp, stratum_instance_t *client, const int diff } tdiff = sane_tdiff(&now_t, &client->last_share); - decay_time(&client->dsps1, diff, tdiff, 60); - decay_time(&client->dsps5, diff, tdiff, 300); - decay_time(&client->dsps60, diff, tdiff, 3600); - decay_time(&client->dsps1440, diff, tdiff, 86400); - decay_time(&client->dsps10080, diff, tdiff, 604800); + decay_time(&client->dsps1, diff, tdiff, MIN1); + decay_time(&client->dsps5, diff, tdiff, MIN5); + decay_time(&client->dsps60, diff, tdiff, HOUR); + decay_time(&client->dsps1440, diff, tdiff, DAY); + decay_time(&client->dsps10080, diff, tdiff, WEEK); copy_tv(&client->last_share, &now_t); tdiff = sane_tdiff(&now_t, &worker->last_share); - decay_time(&worker->dsps1, diff, tdiff, 60); - decay_time(&worker->dsps5, diff, tdiff, 300); - decay_time(&worker->dsps60, diff, tdiff, 3600); - decay_time(&worker->dsps1440, diff, tdiff, 86400); + decay_time(&worker->dsps1, diff, tdiff, MIN1); + decay_time(&worker->dsps5, diff, tdiff, MIN5); + decay_time(&worker->dsps60, diff, tdiff, HOUR); + decay_time(&worker->dsps1440, diff, tdiff, DAY); + decay_time(&worker->dsps10080, diff, tdiff, WEEK); copy_tv(&worker->last_share, &now_t); worker->idle = false; tdiff = sane_tdiff(&now_t, &user->last_share); - decay_time(&user->dsps1, diff, tdiff, 60); - decay_time(&user->dsps5, diff, tdiff, 300); - decay_time(&user->dsps60, diff, tdiff, 3600); - decay_time(&user->dsps1440, diff, tdiff, 86400); - decay_time(&user->dsps10080, diff, tdiff, 604800); + decay_time(&user->dsps1, diff, tdiff, MIN1); + decay_time(&user->dsps5, diff, tdiff, MIN5); + decay_time(&user->dsps60, diff, tdiff, HOUR); + decay_time(&user->dsps1440, diff, tdiff, DAY); + decay_time(&user->dsps10080, diff, tdiff, WEEK); copy_tv(&user->last_share, &now_t); client->idle = false; @@ -4110,11 +4121,11 @@ static void *statsupdate(void *arg) /* Decay times per connected instance */ if (per_tdiff > 60) { /* No shares for over a minute, decay to 0 */ - decay_time(&client->dsps1, 0, per_tdiff, 60); - decay_time(&client->dsps5, 0, per_tdiff, 300); - decay_time(&client->dsps60, 0, per_tdiff, 3600); - decay_time(&client->dsps1440, 0, per_tdiff, 86400); - decay_time(&client->dsps10080, 0, per_tdiff, 604800); + decay_time(&client->dsps1, 0, per_tdiff, MIN1); + decay_time(&client->dsps5, 0, per_tdiff, MIN5); + decay_time(&client->dsps60, 0, per_tdiff, HOUR); + decay_time(&client->dsps1440, 0, per_tdiff, DAY); + decay_time(&client->dsps10080, 0, per_tdiff, WEEK); idle_workers++; if (per_tdiff > 600) client->idle = true; @@ -4133,10 +4144,11 @@ static void *statsupdate(void *arg) DL_FOREACH(user->worker_instances, worker) { per_tdiff = tvdiff(&now, &worker->last_share); if (per_tdiff > 60) { - decay_time(&worker->dsps1, 0, per_tdiff, 60); - decay_time(&worker->dsps5, 0, per_tdiff, 300); - decay_time(&worker->dsps60, 0, per_tdiff, 3600); - decay_time(&worker->dsps1440, 0, per_tdiff, 86400); + decay_time(&worker->dsps1, 0, per_tdiff, MIN1); + decay_time(&worker->dsps5, 0, per_tdiff, MIN5); + decay_time(&worker->dsps60, 0, per_tdiff, HOUR); + decay_time(&worker->dsps1440, 0, per_tdiff, DAY); + decay_time(&worker->dsps10080, 0, per_tdiff, WEEK); worker->idle = true; } ghs = worker->dsps1 * nonces; @@ -4151,13 +4163,17 @@ static void *statsupdate(void *arg) ghs = worker->dsps1440 * nonces; suffix_string(ghs, suffix1440, 16, 0); + ghs = worker->dsps10080 * nonces; + suffix_string(ghs, suffix10080, 16, 0); + copy_tv(&worker->last_update, &now); - JSON_CPACK(val, "{ss,ss,ss,ss,si,sf}", + JSON_CPACK(val, "{ss,ss,ss,ss,ss,si,sf}", "hashrate1m", suffix1, "hashrate5m", suffix5, "hashrate1hr", suffix60, "hashrate1d", suffix1440, + "hashrate7d", suffix10080, "lastupdate", now.tv_sec, "bestshare", worker->best_diff); @@ -4170,11 +4186,11 @@ static void *statsupdate(void *arg) /* Decay times per user */ per_tdiff = tvdiff(&now, &user->last_share); if (per_tdiff > 60) { - decay_time(&user->dsps1, 0, per_tdiff, 60); - decay_time(&user->dsps5, 0, per_tdiff, 300); - decay_time(&user->dsps60, 0, per_tdiff, 3600); - decay_time(&user->dsps1440, 0, per_tdiff, 86400); - decay_time(&user->dsps10080, 0, per_tdiff, 604800); + decay_time(&user->dsps1, 0, per_tdiff, MIN1); + decay_time(&user->dsps5, 0, per_tdiff, MIN5); + decay_time(&user->dsps60, 0, per_tdiff, HOUR); + decay_time(&user->dsps1440, 0, per_tdiff, DAY); + decay_time(&user->dsps10080, 0, per_tdiff, WEEK); idle = true; } ghs = user->dsps1 * nonces; @@ -4323,18 +4339,18 @@ static void *statsupdate(void *arg) stats->accounted_diff_shares += stats->unaccounted_diff_shares; stats->accounted_rejects += stats->unaccounted_rejects; - decay_time(&stats->sps1, stats->unaccounted_shares, 1.875, 60); - decay_time(&stats->sps5, stats->unaccounted_shares, 1.875, 300); - decay_time(&stats->sps15, stats->unaccounted_shares, 1.875, 900); - decay_time(&stats->sps60, stats->unaccounted_shares, 1.875, 3600); + decay_time(&stats->sps1, stats->unaccounted_shares, 1.875, MIN1); + decay_time(&stats->sps5, stats->unaccounted_shares, 1.875, MIN5); + decay_time(&stats->sps15, stats->unaccounted_shares, 1.875, MIN15); + decay_time(&stats->sps60, stats->unaccounted_shares, 1.875, HOUR); - decay_time(&stats->dsps1, stats->unaccounted_diff_shares, 1.875, 60); - decay_time(&stats->dsps5, stats->unaccounted_diff_shares, 1.875, 300); - decay_time(&stats->dsps15, stats->unaccounted_diff_shares, 1.875, 900); - decay_time(&stats->dsps60, stats->unaccounted_diff_shares, 1.875, 3600); - decay_time(&stats->dsps360, stats->unaccounted_diff_shares, 1.875, 21600); - decay_time(&stats->dsps1440, stats->unaccounted_diff_shares, 1.875, 86400); - decay_time(&stats->dsps10080, stats->unaccounted_diff_shares, 1.875, 604800); + decay_time(&stats->dsps1, stats->unaccounted_diff_shares, 1.875, MIN1); + decay_time(&stats->dsps5, stats->unaccounted_diff_shares, 1.875, MIN5); + decay_time(&stats->dsps15, stats->unaccounted_diff_shares, 1.875, MIN15); + decay_time(&stats->dsps60, stats->unaccounted_diff_shares, 1.875, HOUR); + decay_time(&stats->dsps360, stats->unaccounted_diff_shares, 1.875, HOUR6); + decay_time(&stats->dsps1440, stats->unaccounted_diff_shares, 1.875, DAY); + decay_time(&stats->dsps10080, stats->unaccounted_diff_shares, 1.875, WEEK); stats->unaccounted_shares = stats->unaccounted_diff_shares = @@ -4453,18 +4469,18 @@ static void read_poolstats(ckpool_t *ckp) if (tvsec_diff > 60) { LOGNOTICE("Old pool stats indicate pool down for %d seconds, decaying stats", tvsec_diff); - decay_time(&stats->sps1, 0, tvsec_diff, 60); - decay_time(&stats->sps5, 0, tvsec_diff, 300); - decay_time(&stats->sps15, 0, tvsec_diff, 900); - decay_time(&stats->sps60, 0, tvsec_diff, 3600); - - decay_time(&stats->dsps1, 0, tvsec_diff, 60); - decay_time(&stats->dsps5, 0, tvsec_diff, 300); - decay_time(&stats->dsps15, 0, tvsec_diff, 900); - decay_time(&stats->dsps60, 0, tvsec_diff, 3600); - decay_time(&stats->dsps360, 0, tvsec_diff, 21600); - decay_time(&stats->dsps1440, 0, tvsec_diff, 86400); - decay_time(&stats->dsps10080, 0, tvsec_diff, 604800); + decay_time(&stats->sps1, 0, tvsec_diff, MIN1); + decay_time(&stats->sps5, 0, tvsec_diff, MIN5); + decay_time(&stats->sps15, 0, tvsec_diff, MIN15); + decay_time(&stats->sps60, 0, tvsec_diff, HOUR); + + decay_time(&stats->dsps1, 0, tvsec_diff, MIN1); + decay_time(&stats->dsps5, 0, tvsec_diff, MIN5); + decay_time(&stats->dsps15, 0, tvsec_diff, MIN15); + decay_time(&stats->dsps60, 0, tvsec_diff, HOUR); + decay_time(&stats->dsps360, 0, tvsec_diff, HOUR6); + decay_time(&stats->dsps1440, 0, tvsec_diff, DAY); + decay_time(&stats->dsps10080, 0, tvsec_diff, WEEK); } } From 814cf36bf78d512bcccddf740f476f726552ed04 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 5 Oct 2015 15:21:08 +1100 Subject: [PATCH 02/17] Log valid shares per user and worker --- src/stratifier.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 8cebb54e..28a15011 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -181,6 +181,7 @@ struct user_instance { double best_diff; /* Best share found by this user */ + int64_t shares; double dsps1; /* Diff shares per second, 1 minute rolling average */ double dsps5; /* ... 5 minute ... */ double dsps60;/* etc */ @@ -204,6 +205,7 @@ struct worker_instance { worker_instance_t *next; worker_instance_t *prev; + int64_t shares; double dsps1; double dsps5; double dsps60; @@ -2154,6 +2156,7 @@ static void read_userstats(ckpool_t *ckp, user_instance_t *user) user->dsps1440 = dsps_from_key(val, "hashrate1d"); user->dsps10080 = dsps_from_key(val, "hashrate7d"); json_get_int64(&user->last_update.tv_sec, val, "lastupdate"); + json_get_int64(&user->shares, val, "shares"); json_get_double(&user->best_diff, val, "bestshare"); LOGINFO("Successfully read user %s stats %f %f %f %f %f %f", user->username, user->dsps1, user->dsps5, user->dsps60, user->dsps1440, @@ -2209,6 +2212,7 @@ static void read_workerstats(ckpool_t *ckp, worker_instance_t *worker) worker->dsps10080 = dsps_from_key(val, "hashrate7d"); json_get_double(&worker->best_diff, val, "bestshare"); json_get_int64(&worker->last_update.tv_sec, val, "lastupdate"); + json_get_int64(&worker->shares, val, "shares"); LOGINFO("Successfully read worker %s stats %f %f %f %f %f", worker->workername, worker->dsps1, worker->dsps5, worker->dsps60, worker->dsps1440, worker->best_diff); json_decref(val); @@ -2676,7 +2680,10 @@ static void add_submit(ckpool_t *ckp, stratum_instance_t *client, const int diff mutex_unlock(&sdata->stats_lock); /* Count only accepted and stale rejects in diff calculation. */ - if (!valid && !submit) + if (valid) { + worker->shares += diff; + user->shares += diff; + } else if (!submit) return; tv_time(&now_t); @@ -4168,13 +4175,14 @@ static void *statsupdate(void *arg) copy_tv(&worker->last_update, &now); - JSON_CPACK(val, "{ss,ss,ss,ss,ss,si,sf}", + JSON_CPACK(val, "{ss,ss,ss,ss,ss,si,sI,sf}", "hashrate1m", suffix1, "hashrate5m", suffix5, "hashrate1hr", suffix60, "hashrate1d", suffix1440, "hashrate7d", suffix10080, "lastupdate", now.tv_sec, + "shares", worker->shares, "bestshare", worker->best_diff); ASPRINTF(&fname, "%s/workers/%s", ckp->logdir, worker->workername); @@ -4210,7 +4218,7 @@ static void *statsupdate(void *arg) copy_tv(&user->last_update, &now); - JSON_CPACK(val, "{ss,ss,ss,ss,ss,si,si,sf}", + JSON_CPACK(val, "{ss,ss,ss,ss,ss,si,si,sI,sf}", "hashrate1m", suffix1, "hashrate5m", suffix5, "hashrate1hr", suffix60, @@ -4218,6 +4226,7 @@ static void *statsupdate(void *arg) "hashrate7d", suffix10080, "lastupdate", now.tv_sec, "workers", user->workers, + "shares", user->shares, "bestshare", user->best_diff); ASPRINTF(&fname, "%s/users/%s", ckp->logdir, user->username); From fa55ab48d8c1603ad7362d98b2730a2337e0cef7 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 5 Oct 2015 16:00:29 +1100 Subject: [PATCH 03/17] Display workername in block solves --- src/stratifier.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 28a15011..7927f339 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1574,12 +1574,12 @@ static void reset_bestshares(sdata_t *sdata) static void block_solve(ckpool_t *ckp, const char *blockhash) { ckmsg_t *block, *tmp, *found = NULL; + char *msg, *workername = NULL; sdata_t *sdata = ckp->data; char cdfield[64]; int height = 0; ts_t ts_now; json_t *val; - char *msg; update_base(ckp, GEN_PRIORITY); @@ -1598,6 +1598,7 @@ static void block_solve(ckpool_t *ckp, const char *blockhash) } if (!strcmp(solvehash, blockhash)) { dealloc(solvehash); + json_get_string(&workername, val, "workername"); found = block; DL_DELETE(sdata->block_solves, block); break; @@ -1619,11 +1620,16 @@ static void block_solve(ckpool_t *ckp, const char *blockhash) ckdbq_add(ckp, ID_BLOCK, val); free(found); - ASPRINTF(&msg, "Block %d solved by %s!", height, ckp->name); + if (unlikely(!workername)) + workername = strdup(""); + + ASPRINTF(&msg, "Block %d solved by %s @ %s!", height, workername, ckp->name); stratum_broadcast_message(sdata, msg); free(msg); - LOGWARNING("Solved and confirmed block %d", height); + LOGWARNING("Solved and confirmed block %d by %s", height, workername); + free(workername); + reset_bestshares(sdata); } From 4ba1fd6156874ffd5702ece64added83540399bf Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 13 Nov 2015 14:52:01 +1100 Subject: [PATCH 04/17] Silence dropping of throttled clients --- src/stratifier.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 7927f339..9c83c1d9 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1302,9 +1302,11 @@ static void __drop_client(sdata_t *sdata, stratum_instance_t *client, bool lazil if (client->workername) { if (user) { - ASPRINTF(msg, "Dropped client %"PRId64" %s %suser %s worker %s %s", - client->id, client->address, user->throttled ? "throttled " : "", - user->username, client->workername, lazily ? "lazily" : ""); + if (!user->throttled) { + ASPRINTF(msg, "Dropped client %"PRId64" %s user %s worker %s %s", + client->id, client->address, user->username, + client->workername, lazily ? "lazily" : ""); + } } else { ASPRINTF(msg, "Dropped client %"PRId64" %s no user worker %s %s", client->id, client->address, client->workername, @@ -1323,7 +1325,7 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *client, const const char *func, const int line) { char_entry_t *entries = NULL; - char *msg; + char *msg = NULL; int ref; ck_wlock(&sdata->instance_lock); @@ -1332,7 +1334,10 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *client, const * moved due to holding a reference and drop them now. */ if (unlikely(client->dropped && !ref)) { __drop_client(sdata, client, true, &msg); - add_msg_entry(&entries, &msg); + /* Make sure there is a message as throttled users don't + * generate a message */ + if (msg) + add_msg_entry(&entries, &msg); } ck_wunlock(&sdata->instance_lock); From 434ce77b3e6aba2c90fdd1ef03dcd73091851142 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 13 Nov 2015 15:16:15 +1100 Subject: [PATCH 05/17] Fix user/worker/client stats decaying too fast by generalising decay in shared functions and noting last time value was decayed --- src/stratifier.c | 111 +++++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 52 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 9c83c1d9..cfe8ec04 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -188,6 +188,7 @@ struct user_instance { double dsps1440; double dsps10080; tv_t last_share; + tv_t last_decay; tv_t last_update; bool authorised; /* Has this username ever been authorised? */ @@ -212,6 +213,7 @@ struct worker_instance { double dsps1440; double dsps10080; tv_t last_share; + tv_t last_decay; tv_t last_update; time_t start_time; @@ -252,6 +254,7 @@ struct stratum_instance { int ssdc; /* Shares since diff change */ tv_t first_share; tv_t last_share; + tv_t last_decay; time_t first_invalid; /* Time of first invalid in run of non stale rejects */ time_t start_time; @@ -2131,6 +2134,52 @@ static double dsps_from_key(json_t *val, const char *key) return ret; } +/* Sanity check to prevent clock adjustments backwards from screwing up stats */ +static double sane_tdiff(tv_t *end, tv_t *start) +{ + double tdiff = tvdiff(end, start); + + if (unlikely(tdiff < 0.001)) + tdiff = 0.001; + return tdiff; +} + +static void decay_client(stratum_instance_t *client, double diff, tv_t *now_t) +{ + double tdiff = sane_tdiff(now_t, &client->last_decay); + + decay_time(&client->dsps1, diff, tdiff, MIN1); + decay_time(&client->dsps5, diff, tdiff, MIN5); + decay_time(&client->dsps60, diff, tdiff, HOUR); + decay_time(&client->dsps1440, diff, tdiff, DAY); + decay_time(&client->dsps10080, diff, tdiff, WEEK); + copy_tv(&client->last_decay, now_t); +} + +static void decay_worker(worker_instance_t *worker, double diff, tv_t *now_t) +{ + double tdiff = sane_tdiff(now_t, &worker->last_decay); + + decay_time(&worker->dsps1, diff, tdiff, MIN1); + decay_time(&worker->dsps5, diff, tdiff, MIN5); + decay_time(&worker->dsps60, diff, tdiff, HOUR); + decay_time(&worker->dsps1440, diff, tdiff, DAY); + decay_time(&worker->dsps10080, diff, tdiff, WEEK); + copy_tv(&worker->last_decay, now_t); +} + +static void decay_user(user_instance_t *user, double diff, tv_t *now_t) +{ + double tdiff = sane_tdiff(now_t, &user->last_decay); + + decay_time(&user->dsps1, diff, tdiff, MIN1); + decay_time(&user->dsps5, diff, tdiff, MIN5); + decay_time(&user->dsps60, diff, tdiff, HOUR); + decay_time(&user->dsps1440, diff, tdiff, DAY); + decay_time(&user->dsps10080, diff, tdiff, WEEK); + copy_tv(&user->last_decay, now_t); +} + /* Enter holding a reference count */ static void read_userstats(ckpool_t *ckp, user_instance_t *user) { @@ -2161,6 +2210,7 @@ static void read_userstats(ckpool_t *ckp, user_instance_t *user) tv_time(&now); copy_tv(&user->last_share, &now); + copy_tv(&user->last_decay, &now); user->dsps1 = dsps_from_key(val, "hashrate1m"); user->dsps5 = dsps_from_key(val, "hashrate5m"); user->dsps60 = dsps_from_key(val, "hashrate1hr"); @@ -2178,11 +2228,7 @@ static void read_userstats(ckpool_t *ckp, user_instance_t *user) if (tvsec_diff > 60) { LOGINFO("Old user stats indicate not logged for %d seconds, decaying stats", tvsec_diff); - decay_time(&user->dsps1, 0, tvsec_diff, MIN1); - decay_time(&user->dsps5, 0, tvsec_diff, MIN5); - decay_time(&user->dsps60, 0, tvsec_diff, HOUR); - decay_time(&user->dsps1440, 0, tvsec_diff, DAY); - decay_time(&user->dsps10080, 0, tvsec_diff, WEEK); + decay_user(user, 0, &now); } } @@ -2216,6 +2262,7 @@ static void read_workerstats(ckpool_t *ckp, worker_instance_t *worker) tv_time(&now); copy_tv(&worker->last_share, &now); + copy_tv(&worker->last_decay, &now); worker->dsps1 = dsps_from_key(val, "hashrate1m"); worker->dsps5 = dsps_from_key(val, "hashrate5m"); worker->dsps60 = dsps_from_key(val, "hashrate1d"); @@ -2232,10 +2279,7 @@ static void read_workerstats(ckpool_t *ckp, worker_instance_t *worker) if (tvsec_diff > 60) { LOGINFO("Old worker stats indicate not logged for %d seconds, decaying stats", tvsec_diff); - decay_time(&worker->dsps1, 0, tvsec_diff, MIN1); - decay_time(&worker->dsps5, 0, tvsec_diff, MIN5); - decay_time(&worker->dsps60, 0, tvsec_diff, HOUR); - decay_time(&worker->dsps1440, 0, tvsec_diff, DAY); + decay_worker(worker, 0, &now); } } @@ -2661,16 +2705,6 @@ static double time_bias(const double tdiff, const double period) return 1.0 - 1.0 / exp(dexp); } -/* Sanity check to prevent clock adjustments backwards from screwing up stats */ -static double sane_tdiff(tv_t *end, tv_t *start) -{ - double tdiff = tvdiff(end, start); - - if (unlikely(tdiff < 0.001)) - tdiff = 0.001; - return tdiff; -} - /* Needs to be entered with client holding a ref count. */ static void add_submit(ckpool_t *ckp, stratum_instance_t *client, const int diff, const bool valid, const bool submit) @@ -2712,29 +2746,14 @@ static void add_submit(ckpool_t *ckp, stratum_instance_t *client, const int diff copy_tv(&client->ldc, &now_t); } - tdiff = sane_tdiff(&now_t, &client->last_share); - decay_time(&client->dsps1, diff, tdiff, MIN1); - decay_time(&client->dsps5, diff, tdiff, MIN5); - decay_time(&client->dsps60, diff, tdiff, HOUR); - decay_time(&client->dsps1440, diff, tdiff, DAY); - decay_time(&client->dsps10080, diff, tdiff, WEEK); + decay_client(client, diff, &now_t); copy_tv(&client->last_share, &now_t); - tdiff = sane_tdiff(&now_t, &worker->last_share); - decay_time(&worker->dsps1, diff, tdiff, MIN1); - decay_time(&worker->dsps5, diff, tdiff, MIN5); - decay_time(&worker->dsps60, diff, tdiff, HOUR); - decay_time(&worker->dsps1440, diff, tdiff, DAY); - decay_time(&worker->dsps10080, diff, tdiff, WEEK); + decay_worker(worker, diff, &now_t); copy_tv(&worker->last_share, &now_t); worker->idle = false; - tdiff = sane_tdiff(&now_t, &user->last_share); - decay_time(&user->dsps1, diff, tdiff, MIN1); - decay_time(&user->dsps5, diff, tdiff, MIN5); - decay_time(&user->dsps60, diff, tdiff, HOUR); - decay_time(&user->dsps1440, diff, tdiff, DAY); - decay_time(&user->dsps10080, diff, tdiff, WEEK); + decay_user(user, diff, &now_t); copy_tv(&user->last_share, &now_t); client->idle = false; @@ -4139,11 +4158,7 @@ static void *statsupdate(void *arg) /* Decay times per connected instance */ if (per_tdiff > 60) { /* No shares for over a minute, decay to 0 */ - decay_time(&client->dsps1, 0, per_tdiff, MIN1); - decay_time(&client->dsps5, 0, per_tdiff, MIN5); - decay_time(&client->dsps60, 0, per_tdiff, HOUR); - decay_time(&client->dsps1440, 0, per_tdiff, DAY); - decay_time(&client->dsps10080, 0, per_tdiff, WEEK); + decay_client(client, 0, &now); idle_workers++; if (per_tdiff > 600) client->idle = true; @@ -4162,11 +4177,7 @@ static void *statsupdate(void *arg) DL_FOREACH(user->worker_instances, worker) { per_tdiff = tvdiff(&now, &worker->last_share); if (per_tdiff > 60) { - decay_time(&worker->dsps1, 0, per_tdiff, MIN1); - decay_time(&worker->dsps5, 0, per_tdiff, MIN5); - decay_time(&worker->dsps60, 0, per_tdiff, HOUR); - decay_time(&worker->dsps1440, 0, per_tdiff, DAY); - decay_time(&worker->dsps10080, 0, per_tdiff, WEEK); + decay_worker(worker, 0, &now); worker->idle = true; } ghs = worker->dsps1 * nonces; @@ -4205,11 +4216,7 @@ static void *statsupdate(void *arg) /* Decay times per user */ per_tdiff = tvdiff(&now, &user->last_share); if (per_tdiff > 60) { - decay_time(&user->dsps1, 0, per_tdiff, MIN1); - decay_time(&user->dsps5, 0, per_tdiff, MIN5); - decay_time(&user->dsps60, 0, per_tdiff, HOUR); - decay_time(&user->dsps1440, 0, per_tdiff, DAY); - decay_time(&user->dsps10080, 0, per_tdiff, WEEK); + decay_user(user, 0, &now); idle = true; } ghs = user->dsps1 * nonces; From 5cc1812271c9ec35442c62cecacb8225f68ba08b Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 13 Nov 2015 15:59:25 +1100 Subject: [PATCH 06/17] Allow add_msg_entry to be called with a null buffer safely --- src/stratifier.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index cfe8ec04..7902db36 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -454,8 +454,11 @@ struct json_entry { * to the log outside of lock */ static void add_msg_entry(char_entry_t **entries, char **buf) { - char_entry_t *entry = ckalloc(sizeof(char_entry_t)); + char_entry_t *entry; + if (!*buf) + return; + entry = ckalloc(sizeof(char_entry_t)); entry->buf = *buf; *buf = NULL; DL_APPEND(*entries, entry); @@ -1337,10 +1340,7 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *client, const * moved due to holding a reference and drop them now. */ if (unlikely(client->dropped && !ref)) { __drop_client(sdata, client, true, &msg); - /* Make sure there is a message as throttled users don't - * generate a message */ - if (msg) - add_msg_entry(&entries, &msg); + add_msg_entry(&entries, &msg); } ck_wunlock(&sdata->instance_lock); From f42f1875294e6cb9081183b77450e61a70206300 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 13 Nov 2015 16:12:25 +1100 Subject: [PATCH 07/17] Revert "Allow add_msg_entry to be called with a null buffer safely" This reverts commit 5cc1812271c9ec35442c62cecacb8225f68ba08b. --- src/stratifier.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 7902db36..cfe8ec04 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -454,11 +454,8 @@ struct json_entry { * to the log outside of lock */ static void add_msg_entry(char_entry_t **entries, char **buf) { - char_entry_t *entry; + char_entry_t *entry = ckalloc(sizeof(char_entry_t)); - if (!*buf) - return; - entry = ckalloc(sizeof(char_entry_t)); entry->buf = *buf; *buf = NULL; DL_APPEND(*entries, entry); @@ -1340,7 +1337,10 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *client, const * moved due to holding a reference and drop them now. */ if (unlikely(client->dropped && !ref)) { __drop_client(sdata, client, true, &msg); - add_msg_entry(&entries, &msg); + /* Make sure there is a message as throttled users don't + * generate a message */ + if (msg) + add_msg_entry(&entries, &msg); } ck_wunlock(&sdata->instance_lock); From b709dbea44d26e7163626e009fad0b5c68d4ba66 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 13 Nov 2015 16:12:35 +1100 Subject: [PATCH 08/17] Revert "Silence dropping of throttled clients" This reverts commit 4ba1fd6156874ffd5702ece64added83540399bf. --- src/stratifier.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index cfe8ec04..358055b2 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1305,11 +1305,9 @@ static void __drop_client(sdata_t *sdata, stratum_instance_t *client, bool lazil if (client->workername) { if (user) { - if (!user->throttled) { - ASPRINTF(msg, "Dropped client %"PRId64" %s user %s worker %s %s", - client->id, client->address, user->username, - client->workername, lazily ? "lazily" : ""); - } + ASPRINTF(msg, "Dropped client %"PRId64" %s %suser %s worker %s %s", + client->id, client->address, user->throttled ? "throttled " : "", + user->username, client->workername, lazily ? "lazily" : ""); } else { ASPRINTF(msg, "Dropped client %"PRId64" %s no user worker %s %s", client->id, client->address, client->workername, @@ -1328,7 +1326,7 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *client, const const char *func, const int line) { char_entry_t *entries = NULL; - char *msg = NULL; + char *msg; int ref; ck_wlock(&sdata->instance_lock); @@ -1337,10 +1335,7 @@ static void _dec_instance_ref(sdata_t *sdata, stratum_instance_t *client, const * moved due to holding a reference and drop them now. */ if (unlikely(client->dropped && !ref)) { __drop_client(sdata, client, true, &msg); - /* Make sure there is a message as throttled users don't - * generate a message */ - if (msg) - add_msg_entry(&entries, &msg); + add_msg_entry(&entries, &msg); } ck_wunlock(&sdata->instance_lock); From 3f83abab8d40f7ea3c30d7faec6bf3fb880f299b Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 17 Nov 2015 18:52:05 +1100 Subject: [PATCH 09/17] Fix url_from_socket to work with IPV6 sized names --- src/libckpool.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libckpool.c b/src/libckpool.c index 91799eff..0c1b891e 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -570,14 +570,15 @@ out: * INET6_ADDRSTRLEN size, port at least a string of 6 bytes */ bool url_from_socket(const int sockd, char *url, char *port) { - socklen_t addrlen = sizeof(struct sockaddr); - struct sockaddr addr; + struct sockaddr_storage storage; + socklen_t addrlen = sizeof(struct sockaddr_storage); + struct sockaddr *addr = (struct sockaddr *)&storage; if (sockd < 1) return false; - if (getsockname(sockd, &addr, &addrlen)) + if (getsockname(sockd, addr, &addrlen)) return false; - if (!url_from_sockaddr(&addr, url, port)) + if (!url_from_sockaddr(addr, url, port)) return false; return true; } From 449e60511385a66428d79deaa1b9444f64729ba6 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 17 Nov 2015 19:05:36 +1100 Subject: [PATCH 10/17] Specify what message didn't receive a response in send_recv_path --- src/ckpool.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ckpool.c b/src/ckpool.c index 6fbffb98..350876cc 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -1467,7 +1467,8 @@ static bool send_recv_path(const char *path, const char *msg) ret = true; LOGWARNING("Received: %s in response to %s request", response, msg); dealloc(response); - } + } else + LOGWARNING("Received not response to %s request", msg); Close(sockd); return ret; } From 08fcf808a70ec8ecfdc27266720591f7acbb2793 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Tue, 17 Nov 2015 19:12:37 +1100 Subject: [PATCH 11/17] Specify what url has been inherited upon restart if possible --- src/ckpool.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/ckpool.c b/src/ckpool.c index 350876cc..eca22e9c 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -1708,6 +1708,7 @@ int main(int argc, char **argv) if (send_recv_path(path, "ping")) { for (i = 0; i < ckp.serverurls; i++) { + char oldurl[INET6_ADDRSTRLEN], oldport[8]; char getfd[16]; int sockd; @@ -1719,10 +1720,16 @@ int main(int argc, char **argv) break; ckp.oldconnfd[i] = get_fd(sockd); Close(sockd); - if (!ckp.oldconnfd[i]) + sockd = ckp.oldconnfd[i]; + if (!sockd) break; - LOGWARNING("Inherited old server socket %d with new file descriptor %d!", - i, ckp.oldconnfd[i]); + if (url_from_socket(sockd, oldurl, oldport)) { + LOGWARNING("Inherited old server socket %d url %s:%s !", + i, oldurl, oldport); + } else { + LOGWARNING("Inherited old server socket %d with new file descriptor %d!", + i, ckp.oldconnfd[i]); + } } send_recv_path(path, "reject"); send_recv_path(path, "reconnect"); From b0c30a3f7deb558d71a5a43a2528b817d6f815d9 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 20 Nov 2015 10:09:19 +1100 Subject: [PATCH 12/17] Disconnect clients whose sends block for more than 60 seconds --- src/connector.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/connector.c b/src/connector.c index a7b776ab..981e8173 100644 --- a/src/connector.c +++ b/src/connector.c @@ -57,6 +57,9 @@ struct client_instance { /* Are we currently sending a blocked message from this client */ sender_send_t *sending; bool passthrough; + + /* Time this client started blocking, 0 when not blocked */ + time_t blocked_time; }; struct sender_send { @@ -556,6 +559,7 @@ out: static bool send_sender_send(ckpool_t *ckp, cdata_t *cdata, sender_send_t *sender_send) { client_instance_t *client = sender_send->client; + time_t now_t; if (unlikely(client->invalid)) goto out_true; @@ -563,14 +567,26 @@ static bool send_sender_send(ckpool_t *ckp, cdata_t *cdata, sender_send_t *sende /* Make sure we only send one message at a time to each client */ if (unlikely(client->sending && client->sending != sender_send)) return false; + client->sending = sender_send; + now_t = time(NULL); while (sender_send->len) { int ret = write(client->fd, sender_send->buf + sender_send->ofs, sender_send->len); if (unlikely(ret < 1)) { - if (errno == EAGAIN || errno == EWOULDBLOCK || !ret) + /* Invalidate clients that block for more than 60 seconds */ + if (unlikely(client->blocked_time && now_t - client->blocked_time >= 60)) { + LOGNOTICE("Client id %"PRId64" fd %d blocked for >60 seconds, disconnecting", + client->id, client->fd); + invalidate_client(ckp, cdata, client); + goto out_true; + } + if (errno == EAGAIN || errno == EWOULDBLOCK || !ret) { + if (!client->blocked_time) + client->blocked_time = now_t; return false; + } LOGINFO("Client id %"PRId64" fd %d disconnected with write errno %d:%s", client->id, client->fd, errno, strerror(errno)); invalidate_client(ckp, cdata, client); @@ -578,6 +594,7 @@ static bool send_sender_send(ckpool_t *ckp, cdata_t *cdata, sender_send_t *sende } sender_send->ofs += ret; sender_send->len -= ret; + client->blocked_time = 0; } out_true: client->sending = NULL; From e413e0e97b9e73b1845a11d69724aa988b406990 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 21 Nov 2015 14:34:51 +1100 Subject: [PATCH 13/17] Increase size of address storage for clients to store full inet6 name --- src/connector.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/connector.c b/src/connector.c index 981e8173..6ddd3f53 100644 --- a/src/connector.c +++ b/src/connector.c @@ -45,7 +45,8 @@ struct client_instance { client_instance_t *next; client_instance_t *prev; - struct sockaddr address; + struct sockaddr_storage address_storage; + struct sockaddr *address; char address_name[INET6_ADDRSTRLEN]; /* Which serverurl is this instance connected to */ @@ -195,8 +196,9 @@ static int accept_client(cdata_t *cdata, const int epfd, const uint64_t server) sockd = cdata->serverfd[server]; client = recruit_client(cdata); client->server = server; - address_len = sizeof(client->address); - fd = accept(sockd, &client->address, &address_len); + client->address = (struct sockaddr *)&client->address_storage; + address_len = sizeof(client->address_storage); + fd = accept(sockd, client->address, &address_len); if (unlikely(fd < 0)) { /* Handle these errors gracefully should we ever share this * socket */ @@ -209,17 +211,17 @@ static int accept_client(cdata_t *cdata, const int epfd, const uint64_t server) return -1; } - switch (client->address.sa_family) { + switch (client->address->sa_family) { const struct sockaddr_in *inet4_in; const struct sockaddr_in6 *inet6_in; case AF_INET: - inet4_in = (struct sockaddr_in *)&client->address; + inet4_in = (struct sockaddr_in *)client->address; inet_ntop(AF_INET, &inet4_in->sin_addr, client->address_name, INET6_ADDRSTRLEN); port = htons(inet4_in->sin_port); break; case AF_INET6: - inet6_in = (struct sockaddr_in6 *)&client->address; + inet6_in = (struct sockaddr_in6 *)client->address; inet_ntop(AF_INET6, &inet6_in->sin6_addr, client->address_name, INET6_ADDRSTRLEN); port = htons(inet6_in->sin6_port); break; From 759ac0ccbcf70561c1573a512e507838816e7b2c Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 20 Nov 2015 11:20:42 +1100 Subject: [PATCH 14/17] Display user and worker stats on block solve --- src/stratifier.c | 119 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 108 insertions(+), 11 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 358055b2..61a41e24 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1574,6 +1574,85 @@ static void reset_bestshares(sdata_t *sdata) ck_runlock(&sdata->instance_lock); } +static user_instance_t *get_user(sdata_t *sdata, const char *username); + +static user_instance_t *user_by_workername(sdata_t *sdata, const char *workername) +{ + char *username = strdupa(workername), *ignore; + user_instance_t *user; + + ignore = username; + strsep(&ignore, "._"); + + /* Find the user first */ + user = get_user(sdata, username); + return user; +} + +static worker_instance_t *get_worker(sdata_t *sdata, user_instance_t *user, const char *workername); + +static const double nonces = 4294967296; + +static json_t *worker_stats(const worker_instance_t *worker) +{ + char suffix1[16], suffix5[16], suffix60[16], suffix1440[16], suffix10080[16]; + json_t *val; + double ghs; + + ghs = worker->dsps1 * nonces; + suffix_string(ghs, suffix1, 16, 0); + + ghs = worker->dsps5 * nonces; + suffix_string(ghs, suffix5, 16, 0); + + ghs = worker->dsps60 * nonces; + suffix_string(ghs, suffix60, 16, 0); + + ghs = worker->dsps1440 * nonces; + suffix_string(ghs, suffix1440, 16, 0); + + ghs = worker->dsps10080 * nonces; + suffix_string(ghs, suffix10080, 16, 0); + + JSON_CPACK(val, "{ss,ss,ss,ss,ss}", + "hashrate1m", suffix1, + "hashrate5m", suffix5, + "hashrate1hr", suffix60, + "hashrate1d", suffix1440, + "hashrate7d", suffix10080); + return val; +} + +static json_t *user_stats(const user_instance_t *user) +{ + char suffix1[16], suffix5[16], suffix60[16], suffix1440[16], suffix10080[16]; + json_t *val; + double ghs; + + ghs = user->dsps1 * nonces; + suffix_string(ghs, suffix1, 16, 0); + + ghs = user->dsps5 * nonces; + suffix_string(ghs, suffix5, 16, 0); + + ghs = user->dsps60 * nonces; + suffix_string(ghs, suffix60, 16, 0); + + ghs = user->dsps1440 * nonces; + suffix_string(ghs, suffix1440, 16, 0); + + ghs = user->dsps10080 * nonces; + suffix_string(ghs, suffix10080, 16, 0); + + JSON_CPACK(val, "{ss,ss,ss,ss,ss}", + "hashrate1m", suffix1, + "hashrate5m", suffix5, + "hashrate1hr", suffix60, + "hashrate1d", suffix1440, + "hashrate7d", suffix10080); + return val; +} + static void block_solve(ckpool_t *ckp, const char *blockhash) { ckmsg_t *block, *tmp, *found = NULL; @@ -1623,14 +1702,38 @@ static void block_solve(ckpool_t *ckp, const char *blockhash) ckdbq_add(ckp, ID_BLOCK, val); free(found); - if (unlikely(!workername)) - workername = strdup(""); + if (unlikely(!workername)) { + /* This should be impossible! */ + ASPRINTF(&msg, "Block %d solved by %s!", height, ckp->name); + LOGWARNING("Solved and confirmed block %d", height); + } else { + json_t *user_val, *worker_val; + worker_instance_t *worker; + user_instance_t *user; + char *s; + + ASPRINTF(&msg, "Block %d solved by %s @ %s!", height, workername, ckp->name); + LOGWARNING("Solved and confirmed block %d by %s", height, workername); + user = user_by_workername(sdata, workername); + worker = get_worker(sdata, user, workername); - ASPRINTF(&msg, "Block %d solved by %s @ %s!", height, workername, ckp->name); + ck_rlock(&sdata->instance_lock); + user_val = user_stats(user); + worker_val = worker_stats(worker); + ck_runlock(&sdata->instance_lock); + + s = json_dumps(user_val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); + json_decref(user_val); + LOGWARNING("User %s:%s", user->username, s); + dealloc(s); + s = json_dumps(worker_val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); + json_decref(worker_val); + LOGWARNING("Worker %s:%s", workername, s); + dealloc(s); + } stratum_broadcast_message(sdata, msg); free(msg); - LOGWARNING("Solved and confirmed block %d by %s", height, workername); free(workername); reset_bestshares(sdata); @@ -2096,8 +2199,6 @@ static bool test_address(ckpool_t *ckp, const char *address) return ret; } -static const double nonces = 4294967296; - static double dsps_from_key(json_t *val, const char *key) { char *string, *endptr; @@ -3345,17 +3446,13 @@ static json_params_t static void set_worker_mindiff(ckpool_t *ckp, const char *workername, int mindiff) { - char *username = strdupa(workername), *ignore; stratum_instance_t *client; sdata_t *sdata = ckp->data; worker_instance_t *worker; user_instance_t *user; - ignore = username; - strsep(&ignore, "._"); - /* Find the user first */ - user = get_user(sdata, username); + user = user_by_workername(sdata, workername); /* Then find the matching worker user */ worker = get_worker(sdata, user, workername); From 690084b7351ead852bf3fb803e000d5dd2293509 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Nov 2015 14:37:31 +1100 Subject: [PATCH 15/17] Clear line when writing log to console --- src/ckpool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ckpool.c b/src/ckpool.c index eca22e9c..a57adb34 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -84,6 +84,7 @@ void logmsg(int loglevel, const char *fmt, ...) { tm.tm_min, tm.tm_sec, ms); if (loglevel <= LOG_WARNING) { + fprintf(stderr, "\33[2K\r"); if (loglevel <= LOG_ERR && errno != 0) fprintf(stderr, "%s %s with errno %d: %s\n", stamp, buf, errno, strerror(errno)); else From b062a8e29a86c14ce6b2446eb5c2fc0d8b534357 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 26 Nov 2015 14:37:53 +1100 Subject: [PATCH 16/17] Add basic stats to console throbber line --- src/stratifier.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 61a41e24..6274e488 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -40,6 +40,7 @@ static const char *workpadding = "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000"; static const char *scriptsig_header = "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff"; static uchar scriptsig_header_bin[41]; +static const double nonces = 4294967296; /* Add unaccounted shares when they arrive, remove them with each update of * rolling stats. */ @@ -693,10 +694,15 @@ static void _ckdbq_add(ckpool_t *ckp, const int idtype, json_t *val, const char now_t = time(NULL); if (now_t != time_counter) { + pool_stats_t *stats = &sdata->stats; + char hashrate[16]; + /* Rate limit to 1 update per second */ time_counter = now_t; + suffix_string(stats->dsps1 * nonces, hashrate, 16, 0); ch = status_chars[(counter++) & 0x3]; - fprintf(stdout, "%c\r", ch); + fprintf(stdout, "\33[2K\r%c %sH/s %.1f SPS %d users %d workers", + ch, hashrate, stats->sps1, stats->users, stats->workers); fflush(stdout); } @@ -1591,8 +1597,6 @@ static user_instance_t *user_by_workername(sdata_t *sdata, const char *workernam static worker_instance_t *get_worker(sdata_t *sdata, user_instance_t *user, const char *workername); -static const double nonces = 4294967296; - static json_t *worker_stats(const worker_instance_t *worker) { char suffix1[16], suffix5[16], suffix60[16], suffix1440[16], suffix10080[16]; From 0635c75560ee1823650d81008da2385f69843624 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 27 Nov 2015 14:30:49 +1100 Subject: [PATCH 17/17] Keep significant digits constant on displayed hashrate --- src/stratifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/stratifier.c b/src/stratifier.c index 6274e488..f93d0f99 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -699,7 +699,7 @@ static void _ckdbq_add(ckpool_t *ckp, const int idtype, json_t *val, const char /* Rate limit to 1 update per second */ time_counter = now_t; - suffix_string(stats->dsps1 * nonces, hashrate, 16, 0); + suffix_string(stats->dsps1 * nonces, hashrate, 16, 3); ch = status_chars[(counter++) & 0x3]; fprintf(stdout, "\33[2K\r%c %sH/s %.1f SPS %d users %d workers", ch, hashrate, stats->sps1, stats->users, stats->workers);