diff --git a/pool/db.php b/pool/db.php index b98f0ab3..146749b9 100644 --- a/pool/db.php +++ b/pool/db.php @@ -107,7 +107,7 @@ function getWorkers($user) { if ($user == false) showIndex(); - $flds = array('username' => $user); + $flds = array('username' => $user, 'stats' => 'Y'); $msg = msgEncode('workers', 'work', $flds); $rep = sendsockreply('getworkers', $msg); if (!$rep) diff --git a/pool/page_worker.php b/pool/page_worker.php deleted file mode 100644 index 4a730a27..00000000 --- a/pool/page_worker.php +++ /dev/null @@ -1,44 +0,0 @@ -Workers'; - - $rep = getWorkers($user); - $ans = repDecode($rep); - - $pg .= "\n"; - $pg .= ""; - $pg .= ""; - $pg .= ""; - $pg .= ""; - $pg .= ""; - $pg .= "\n"; - if ($ans['STATUS'] == 'ok') - { - $count = $ans['rows']; - for ($i = 0; $i < $count; $i++) - { - if (($i % 2) == 0) - $row = 'even'; - else - $row = 'odd'; - - $pg .= ""; - $pg .= ''; - $pg .= ''; - $pg .= ''; - $pg .= "\n"; - } - } - $pg .= "
NameDifficultyIdle NotificationsIdle Notification Time
'.$ans['paydate'.$i].''.$ans['payaddress'.$i].''.btcfmt($ans['amount'.$i]).'
\n"; - - return $pg; -} -# -function show_workers($menu, $name, $user) -{ - gopage(NULL, 'doworkers', $menu, $name, $user); -} -# -?> diff --git a/pool/page_workers.php b/pool/page_workers.php new file mode 100644 index 00000000..136cd3b2 --- /dev/null +++ b/pool/page_workers.php @@ -0,0 +1,96 @@ +Workers'; + + $rep = getWorkers($user); + $ans = repDecode($rep); + + $pg .= "\n"; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= "\n"; + if ($ans['STATUS'] == 'ok') + { + $count = $ans['rows']; + for ($i = 0; $i < $count; $i++) + { + if (($i % 2) == 0) + $row = 'even'; + else + $row = 'odd'; + + $pg .= ""; + $pg .= ''; + $pg .= ''; + $nots = $ans['idlenotificationenabled'.$i]; + switch ($nots) + { + case 'Y': + case 'y': + $nots = 'Y'; + break; + default: + $nots = 'N'; + } + $pg .= ''; + $pg .= ''; + $lst = $ans['STAMP'] - $ans['w_lastshare'.$i]; + if ($lst < 60) + $lstdes = $lst.'s'; + else + { + $lst = round($lst/60); + if ($lst < 60) + $lstdes = $lst.'m'; + else + { + $lst = round($lst/60); + if ($lst < 24) + $lstdes = $lst.'hr'; + else + { + $lst = round($lst/24); + if ($lst < 9999) + $lstdes = $lst.'days'; + else + $lstdes = 'never'; + } + } + } + $pg .= ""; + if ($ans['w_elapsed'.$i] > 3600) + $uhr = $ans['w_hashrate1hr'.$i]; + else + $uhr = $ans['w_hashrate5m'.$i]; + if ($uhr == '?') + $uhr = '?GHs'; + else + { + $uhr /= 10000000; + if ($uhr < 100000) + $uhr = (round($uhr)/100).'GHs'; + else + $uhr = (round($uhr/1000)/100).'THs'; + } + $pg .= ""; + $pg .= "\n"; + } + } + $pg .= "
Worker NameDifficultyIdle NotificationsIdle Notification TimeLast ShareHash Rate
'.$ans['workername'.$i].''.$ans['difficultydefault'.$i].''.$nots.''.$ans['idlenotificationtime'.$i].'$lstdes$uhr
\n"; + + return $pg; +} +# +function show_workers($menu, $name, $user) +{ + gopage(NULL, 'doworkers', $menu, $name, $user); +} +# +?> diff --git a/src/ckdb.c b/src/ckdb.c index 1dc84486..a10089a9 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -1065,7 +1065,7 @@ static K_ITEM *optional_name(char *name, int len, char *patt) return NULL; value = DATA_TRANSFER(item)->data; - if (!*value || (int)strlen(value) < len) + if (!value || (int)strlen(value) < len) return NULL; if (patt) { @@ -4742,9 +4742,9 @@ foil: static char *cmd_payments(char *cmd, char *id, __maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused char *code, __maybe_unused char *inet) { - K_ITEM *i_username, *look, *u_item, *p_item; + K_ITEM *i_username, look, *u_item, *p_item; K_TREE_CTX ctx[1]; - PAYMENTS *row; + PAYMENTS payments; char reply[1024] = ""; char tmp[1024]; size_t siz = sizeof(reply); @@ -4762,14 +4762,11 @@ static char *cmd_payments(char *cmd, char *id, __maybe_unused tv_t *now, __maybe if (!u_item) return strdup("bad"); - K_WLOCK(payments_list); - look = k_unlink_head(payments_list); - K_WUNLOCK(payments_list); - row = DATA_PAYMENTS(look); - row->userid = DATA_USERS(u_item)->userid; - row->paydate.tv_sec = 0; - row->paydate.tv_usec = 0; - p_item = find_after_in_ktree(payments_root, look, cmp_payments, ctx); + payments.userid = DATA_USERS(u_item)->userid; + payments.paydate.tv_sec = 0; + payments.paydate.tv_usec = 0; + look.data = (void *)(&payments); + p_item = find_after_in_ktree(payments_root, &look, cmp_payments, ctx); APPEND_REALLOC_INIT(buf, off, len); APPEND_REALLOC(buf, off, len, "ok."); rows = 0; @@ -4792,9 +4789,138 @@ static char *cmd_payments(char *cmd, char *id, __maybe_unused tv_t *now, __maybe snprintf(tmp, sizeof(tmp), "rows=%d", rows); APPEND_REALLOC(buf, off, len, tmp); - K_WLOCK(payments_list); - k_add_head(payments_list, look); - K_WUNLOCK(payments_list); + LOGDEBUG("%s.ok.%s", id, DATA_TRANSFER(i_username)->data); + return buf; +} + +static char *cmd_workers(char *cmd, char *id, __maybe_unused tv_t *now, __maybe_unused char *by, + __maybe_unused char *code, __maybe_unused char *inet) +{ + K_ITEM *i_username, *i_stats, wlook, *u_item, *w_item, uslook, *us_item; + K_TREE_CTX wctx[1], usctx[1]; + WORKERS workers; + USERSTATS userstats; + char reply[1024] = ""; + char tmp[1024]; + size_t siz = sizeof(reply); + char *buf; + size_t len, off; + bool stats; + int rows; + + LOGDEBUG("%s(): cmd '%s'", __func__, cmd); + + i_username = require_name("username", 3, (char *)userpatt, reply, siz); + if (!i_username) + return strdup(reply); + + u_item = find_users(DATA_TRANSFER(i_username)->data); + if (!u_item) + return strdup("bad"); + + i_stats = optional_name("stats", 1, NULL); + if (!i_stats) + stats = false; + else + stats = (strcasecmp(DATA_TRANSFER(i_stats)->data, TRUE_STR) == 0); + + workers.userid = DATA_USERS(u_item)->userid; + workers.workername[0] = '\0'; + workers.expirydate.tv_sec = 0; + workers.expirydate.tv_usec = 0; + wlook.data = (void *)(&workers); + w_item = find_after_in_ktree(workers_root, &wlook, cmp_workers, wctx); + APPEND_REALLOC_INIT(buf, off, len); + APPEND_REALLOC(buf, off, len, "ok."); + rows = 0; + while (w_item && DATA_WORKERS(w_item)->userid == DATA_USERS(u_item)->userid) { + if (tvdiff(&(DATA_WORKERS(w_item)->expirydate), (tv_t *)&default_expiry) == 0.0) { + str_to_buf(DATA_WORKERS(w_item)->workername, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "workername%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + int_to_buf(DATA_WORKERS(w_item)->difficultydefault, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "difficultydefault%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + str_to_buf(DATA_WORKERS(w_item)->idlenotificationenabled, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "idlenotificationenabled%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + int_to_buf(DATA_WORKERS(w_item)->idlenotificationtime, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "idlenotificationtime%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + if (stats) { + K_TREE *userstats_workername_root = new_ktree(); + K_TREE_CTX uswctx[1]; + double w_hashrate5m, w_hashrate1hr; + int64_t w_elapsed; + tv_t w_lastshare; + + w_lastshare.tv_sec = 0; + w_hashrate5m = w_hashrate1hr = 0.0; + w_elapsed = -1; + + // find last stored userid record + userstats.userid = DATA_USERS(u_item)->userid; + userstats.createdate.tv_sec = date_eot.tv_sec; + userstats.createdate.tv_usec = date_eot.tv_usec; + // find/cmp doesn't get to here + userstats.poolinstance[0] = '\0'; + userstats.workername[0] = '\0'; + uslook.data = (void *)(&userstats); + us_item = find_before_in_ktree(userstats_root, &uslook, cmp_userstats, usctx); + while (us_item && DATA_USERSTATS(us_item)->userid == userstats.userid) { + if (strcmp(DATA_USERSTATS(us_item)->workername, DATA_WORKERS(w_item)->workername) == 0) { + // first found is the newest share + if (w_lastshare.tv_sec == 0) + w_lastshare.tv_sec = DATA_USERSTATS(us_item)->createdate.tv_sec; + + if (tvdiff(now, &(DATA_USERSTATS(us_item)->createdate)) < USERSTATS_PER_S) { + // TODO: add together the latest per pool instance (this is the latest per worker) + if (!find_in_ktree(userstats_workername_root, us_item, cmp_userstats_workername, uswctx)) { + w_hashrate5m += DATA_USERSTATS(us_item)->hashrate5m; + w_hashrate1hr += DATA_USERSTATS(us_item)->hashrate1hr; + if (w_elapsed == -1 || w_elapsed > DATA_USERSTATS(us_item)->elapsed) + w_elapsed = DATA_USERSTATS(us_item)->elapsed; + + userstats_workername_root = add_to_ktree(userstats_workername_root, + us_item, + cmp_userstats_workername); + } + } else + break; + + } + us_item = prev_in_ktree(usctx); + } + + double_to_buf(w_hashrate5m, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "w_hashrate5m%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + double_to_buf(w_hashrate1hr, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "w_hashrate1hr%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + bigint_to_buf(w_elapsed, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "w_elapsed%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + int_to_buf((int)(w_lastshare.tv_sec), reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "w_lastshare%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + userstats_workername_root = free_ktree(userstats_workername_root, NULL); + } + + rows++; + } + w_item = next_in_ktree(wctx); + } + snprintf(tmp, sizeof(tmp), "rows=%d", rows); + APPEND_REALLOC(buf, off, len, tmp); LOGDEBUG("%s.ok.%s", id, DATA_TRANSFER(i_username)->data); return buf; @@ -5249,6 +5375,7 @@ static char *cmd_homepage(char *cmd, char *id, __maybe_unused tv_t *now, __maybe while (us_item && DATA_USERSTATS(us_item)->userid == userstats.userid && tvdiff(now, &(DATA_USERSTATS(us_item)->createdate)) < USERSTATS_PER_S) { + // TODO: add the latest per pool instance (this is the latest per worker) if (!find_in_ktree(userstats_workername_root, us_item, cmp_userstats_workername, wctx)) { u_hashrate5m += DATA_USERSTATS(us_item)->hashrate5m; u_hashrate1hr += DATA_USERSTATS(us_item)->hashrate1hr; @@ -5331,6 +5458,7 @@ enum cmd_values { CMD_BLOCK, CMD_NEWID, CMD_PAYMENTS, + CMD_WORKERS, CMD_HOMEPAGE, CMD_DSP, CMD_END @@ -5361,6 +5489,7 @@ static struct CMDS { { CMD_BLOCK, "block", cmd_blocks, ACCESS_POOL }, { CMD_NEWID, "newid", cmd_newid, ACCESS_SYSTEM }, { CMD_PAYMENTS, "payments", cmd_payments, ACCESS_WEB }, + { CMD_WORKERS, "workers", cmd_workers, ACCESS_WEB }, { CMD_HOMEPAGE, "homepage", cmd_homepage, ACCESS_WEB }, { CMD_DSP, "dsp", cmd_dsp, ACCESS_SYSTEM }, { CMD_END, NULL, NULL, NULL }