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;