From f11f957cdae66843977425705e4171ab356d809e Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Thu, 30 Oct 2014 17:25:51 +1100 Subject: [PATCH] Read off worker and user stats from saved logs if they exist --- src/stratifier.c | 119 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 111 insertions(+), 8 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 6b0222a0..d2a2088c 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -1603,6 +1603,108 @@ 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; + double ret = 0; + + json_get_string(&string, val, key); + if (!string) + return ret; + ret = strtod(string, &endptr) / nonces; + if (endptr) { + switch (endptr[0]) { + case 'E': + ret *= (double)1000; + case 'P': + ret *= (double)1000; + case 'T': + ret *= (double)1000; + case 'G': + ret *= (double)1000; + case 'M': + ret *= (double)1000; + case 'K': + ret *= (double)1000; + default: + break; + } + } + free(string); + return ret; +} + +static void read_userstats(ckpool_t *ckp, user_instance_t *instance) +{ + char s[512]; + json_t *val; + FILE *fp; + int ret; + + snprintf(s, 511, "%s/users/%s", ckp->logdir, instance->username); + fp = fopen(s, "re"); + if (!fp) { + LOGINFO("User %s does not have a logfile to read", instance->username); + return; + } + memset(s, 0, 512); + ret = fread(s, 1, 511, fp); + fclose(fp); + if (ret < 1) { + LOGINFO("Failed to read user %s logfile", instance->username); + return; + } + val = json_loads(s, 0, NULL); + if (!val) { + LOGINFO("Failed to json decode user %s logfile: %s", instance->username, s); + return; + } + + instance->dsps1 = dsps_from_key(val, "hashrate1m"); + instance->dsps5 = dsps_from_key(val, "hashrate5m"); + instance->dsps60 = dsps_from_key(val, "hashrate1hr"); + instance->dsps1440 = dsps_from_key(val, "hashrate1d"); + instance->dsps10080 = dsps_from_key(val, "hashrate7d"); + LOGINFO("Successfully read user %s stats", instance->username); + json_decref(val); +} + +static void read_workerstats(ckpool_t *ckp, worker_instance_t *worker) +{ + char s[512]; + json_t *val; + FILE *fp; + int ret; + + snprintf(s, 511, "%s/workers/%s", ckp->logdir, worker->workername); + fp = fopen(s, "re"); + if (!fp) { + LOGINFO("Worker %s does not have a logfile to read"); + return; + } + memset(s, 0, 512); + ret = fread(s, 1, 511, fp); + fclose(fp); + if (ret < 1) { + LOGINFO("Failed to read worker %s logfile", worker->workername); + return; + } + val = json_loads(s, 0, NULL); + if (!val) { + LOGINFO("Failed to json decode worker %s logfile: %s", worker->workername, s); + return; + } + worker->dsps1 = dsps_from_key(val, "hashrate1m"); + worker->dsps5 = dsps_from_key(val, "hashrate5m"); + worker->dsps60 = dsps_from_key(val, "hashrate1d"); + worker->dsps1440 = dsps_from_key(val, "hashrate1d"); + LOGINFO("Successfully read worker %s stats", worker->workername); + json_decref(val); +} + + /* This simply strips off the first part of the workername and matches it to a * user or creates a new one. */ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, @@ -1631,6 +1733,7 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, instance->id = user_instance_id++; HASH_ADD_STR(user_instances, username, instance); + read_userstats(ckp, instance); } DL_FOREACH(instance->instances, tmp) { if (!safecmp(workername, tmp->workername)) { @@ -1645,6 +1748,7 @@ static user_instance_t *generate_user(ckpool_t *ckp, stratum_instance_t *client, client->worker_instance->workername = strdup(workername); client->worker_instance->instance = instance; DL_APPEND(instance->worker_instances, client->worker_instance); + read_workerstats(ckp, client->worker_instance); } DL_APPEND(instance->instances, client); ck_wunlock(&instance_lock); @@ -3059,8 +3163,6 @@ out: discard_json_params(&jp); } -static const double nonces = 4294967296; - /* Called every 20 seconds, we send the updated stats to ckdb of those users * who have gone 10 minutes between updates. This ends up staggering stats to * avoid floods of stat data coming at once. */ @@ -3274,13 +3376,13 @@ static void *statsupdate(void *arg) ghs = worker->dsps1 * nonces; suffix_string(ghs, suffix1, 16, 0); - ghs = worker->dsps5 * nonces / bias5; + ghs = worker->dsps5 * nonces; suffix_string(ghs, suffix5, 16, 0); - ghs = worker->dsps60 * nonces / bias60; + ghs = worker->dsps60 * nonces; suffix_string(ghs, suffix60, 16, 0); - ghs = worker->dsps1440 * nonces / bias1440; + ghs = worker->dsps1440 * nonces; suffix_string(ghs, suffix1440, 16, 0); JSON_CPACK(val, "{ss,ss,ss,ss}", @@ -3315,14 +3417,15 @@ static void *statsupdate(void *arg) ghs = instance->dsps1 * nonces; suffix_string(ghs, suffix1, 16, 0); - ghs = instance->dsps5 * nonces / bias5; + ghs = instance->dsps5 * nonces; suffix_string(ghs, suffix5, 16, 0); - ghs = instance->dsps60 * nonces / bias60; + ghs = instance->dsps60 * nonces; suffix_string(ghs, suffix60, 16, 0); - ghs = instance->dsps1440 * nonces / bias1440; + ghs = instance->dsps1440 * nonces; suffix_string(ghs, suffix1440, 16, 0); + ghs = instance->dsps10080 * nonces; suffix_string(ghs, suffix10080, 16, 0);