diff --git a/pool/db.php b/pool/db.php index 302b9dae..e1939f2f 100644 --- a/pool/db.php +++ b/pool/db.php @@ -116,12 +116,12 @@ function homeInfo($user) else { $ans = repDecode($rep); - if ($ans['lastblock'] == '?') - { +// if ($ans['lastblock'] == '?') +// { // $ans['lastblock'] = 1401237522; // $ans['lastblock'] = 1403819191; - $ans['lastblock'] = 1407113822; - } +// $ans['lastblock'] = 1407113822; +// } } return $ans; @@ -188,6 +188,16 @@ function userSettings($user, $email = null, $addr = null, $pass = null) return repDecode($rep); } # +function workerSet($user, $settings) +{ + $flds = array_merge(array('username' => $user), $settings); + $msg = msgEncode('workerset', 'workerset', $flds, $user); + $rep = sendsockreply('workerSet', $msg); + if (!$rep) + dbdown(); + return repDecode($rep); +} +# function getAllUsers($user) { $flds = array(); @@ -198,11 +208,11 @@ function getAllUsers($user) return repDecode($rep); } # -function getWorkers($user) +function getWorkers($user, $stats = 'Y') { if ($user == false) showIndex(); - $flds = array('username' => $user, 'stats' => 'Y'); + $flds = array('username' => $user, 'stats' => $stats); $msg = msgEncode('workers', 'work', $flds, $user); $rep = sendsockreply('getWorkers', $msg); if (!$rep) diff --git a/pool/page_workmgt.php b/pool/page_workmgt.php new file mode 100644 index 00000000..ef3a1161 --- /dev/null +++ b/pool/page_workmgt.php @@ -0,0 +1,89 @@ +Worker Management'; + + if ($err != '') + $pg .= "$err

"; + + $pg .= makeForm('workmgt'); + $pg .= "\n"; + $pg .= ''; + $pg .= ''; + $pg .= ''; + $pg .= ''; + + $ans = getWorkers($user, 'N'); + + $offset = 0; + if ($ans['STATUS'] == 'ok') + { + $count = $ans['rows']; + for ($i = 0; $i < $count; $i++) + { + if ((($offset) % 2) == 0) + $row = 'even'; + else + $row = 'odd'; + + $pg .= ""; + + $wn = $ans['workername:'.$i]; + $pg .= ''; + + $md = $ans['difficultydefault:'.$i]; + $pg .= '"; + + $pg .= "\n"; + + $offset++; + } + } + $pg .= "
Worker NameMinimum Diff
'; + $pg .= ""; + $pg .= $wn.''; + $pg .= ""; + $pg .= ""; + $pg .= "
\n"; + + return $pg; +} +# +function doworkmgt($data, $user) +{ + $err = ''; + $OK = getparam('OK', false); + $count = getparam('rows', false); + if ($OK == 'OK' && !nuem($count)) + { + if ($count > 0 && $count < 9999) + { + $settings = array(); + for ($i = 0; $i < $count; $i++) + { + $wn = getparam('workername:'.$i, false); + $md = getparam('difficultydefault:'.$i, false); + if (!nuem($wn) && !nuem($md)) + { + $settings['workername:'.$i] = $wn; + $settings['difficultydefault:'.$i] = $md; + } + } + $ans = workerSet($user, $settings); + if ($ans['STATUS'] != 'ok') + $err = $ans['ERROR']; + } + } + + $pg = workmgtuser($data, $user, $err); + + return $pg; +} +# +function show_workmgt($page, $menu, $name, $user) +{ + gopage(NULL, 'doworkmgt', $page, $menu, $name, $user); +} +# +?> diff --git a/pool/prime.php b/pool/prime.php index 1ef7c2e3..4252a447 100644 --- a/pool/prime.php +++ b/pool/prime.php @@ -49,11 +49,14 @@ function check() 'Home' => '' ), 'Account' => array( - 'Workers' => 'workers', 'Payments' => 'payments', 'Settings' => 'settings', 'User Settings' => 'userset' ), + 'Workers' => array( + 'Workers ' => 'workers', + 'Management' => 'workmgt', + ), 'Pool' => array( 'Stats' => 'stats', 'Blocks' => 'blocks' diff --git a/src/ckdb.c b/src/ckdb.c index 1826b1be..59c43b47 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -49,7 +49,7 @@ #define DB_VLOCK "1" #define DB_VERSION "0.9.2" -#define CKDB_VERSION DB_VERSION"-0.334" +#define CKDB_VERSION DB_VERSION"-0.336" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -807,6 +807,7 @@ enum cmd_values { CMD_NEWPASS, CMD_CHKPASS, CMD_USERSET, + CMD_WORKERSET, CMD_POOLSTAT, CMD_USERSTAT, CMD_BLOCK, @@ -3814,9 +3815,14 @@ unitem: return ret; } +/* The assumption is that the worker already exists in the DB + * and in the RAM tables and the item passed is already in the tree + * Since there is no change to the key, there's no tree reorg required + * check = false means just update it, ignore the passed char* vars */ static bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault, - char *idlenotificationenabled, char *idlenotificationtime, - char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root) + char *idlenotificationenabled, + char *idlenotificationtime, char *by, char *code, + char *inet, tv_t *cd, K_TREE *trf_root, bool check) { ExecStatusType rescode; bool conned = false; @@ -3834,42 +3840,49 @@ static bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault, DATA_WORKERS(row, item); - if (difficultydefault && *difficultydefault) { - diffdef = atoi(difficultydefault); - if (diffdef < DIFFICULTYDEFAULT_MIN) - diffdef = row->difficultydefault; - if (diffdef > DIFFICULTYDEFAULT_MAX) + if (check) { + if (difficultydefault && *difficultydefault) { + diffdef = atoi(difficultydefault); + if (diffdef < DIFFICULTYDEFAULT_MIN) + diffdef = row->difficultydefault; + if (diffdef > DIFFICULTYDEFAULT_MAX) + diffdef = row->difficultydefault; + } else diffdef = row->difficultydefault; - } else - diffdef = row->difficultydefault; - - if (idlenotificationenabled && *idlenotificationenabled) { - if (tolower(*idlenotificationenabled) == IDLENOTIFICATIONENABLED[0]) - idlenot = IDLENOTIFICATIONENABLED[0]; - else - idlenot = IDLENOTIFICATIONDISABLED[0]; - } else - idlenot = row->idlenotificationenabled[0]; - if (idlenotificationtime && *idlenotificationtime) { - nottime = atoi(idlenotificationtime); - if (nottime < IDLENOTIFICATIONTIME_MIN) - nottime = row->idlenotificationtime; - if (nottime > IDLENOTIFICATIONTIME_MAX) + if (idlenotificationenabled && *idlenotificationenabled) { + if (tolower(*idlenotificationenabled) == IDLENOTIFICATIONENABLED[0]) + idlenot = IDLENOTIFICATIONENABLED[0]; + else + idlenot = IDLENOTIFICATIONDISABLED[0]; + } else + idlenot = row->idlenotificationenabled[0]; + + if (idlenotificationtime && *idlenotificationtime) { + nottime = atoi(idlenotificationtime); + if (nottime < IDLENOTIFICATIONTIME_MIN) + nottime = row->idlenotificationtime; + if (nottime > IDLENOTIFICATIONTIME_MAX) + nottime = row->idlenotificationtime; + } else nottime = row->idlenotificationtime; - } else - nottime = row->idlenotificationtime; - HISTORYDATEINIT(row, cd, by, code, inet); - HISTORYDATETRANSFER(trf_root, row); + if (diffdef == row->difficultydefault && + idlenot == row->idlenotificationenabled[0] && + nottime == row->idlenotificationtime) { + ok = true; + goto early; + } - if (diffdef == row->difficultydefault && - idlenot == row->idlenotificationenabled[0] && - nottime == row->idlenotificationtime) { - ok = true; - goto early; + row->difficultydefault = diffdef; + row->idlenotificationenabled[0] = idlenot; + row->idlenotificationenabled[1] = '\0'; + row->idlenotificationtime = nottime; } + HISTORYDATEINIT(row, cd, by, code, inet); + HISTORYDATETRANSFER(trf_root, row); + upd = "update workers set expirydate=$1 where workerid=$2 and expirydate=$3"; par = 0; params[par++] = tv_to_buf(cd, NULL, 0); @@ -3906,11 +3919,6 @@ static bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault, "idlenotificationenabled,idlenotificationtime" HISTORYDATECONTROL ") values (" PQPARAM11 ")"; - row->difficultydefault = diffdef; - row->idlenotificationenabled[0] = idlenot; - row->idlenotificationenabled[1] = '\0'; - row->idlenotificationtime = nottime; - par = 0; params[par++] = bigint_to_buf(row->workerid, NULL, 0); params[par++] = bigint_to_buf(row->userid, NULL, 0); @@ -3958,7 +3966,7 @@ static K_ITEM *new_worker(PGconn *conn, bool update, int64_t userid, char *worke if (!confirm_sharesummary && update) { workers_update(conn, item, diffdef, idlenotificationenabled, idlenotificationtime, by, code, inet, cd, - trf_root); + trf_root, true); } } else { if (confirm_sharesummary) { @@ -9200,6 +9208,118 @@ struckout: return strdup(reply); } +static char *cmd_workerset(PGconn *conn, char *cmd, char *id, tv_t *now, + char *by, char *code, char *inet, + __maybe_unused tv_t *notcd, K_TREE *trf_root) +{ + K_ITEM *i_username, *i_workername, *i_diffdef, *u_item, *w_item; + char workername_buf[32]; // 'workername:' + digits + char diffdef_buf[32]; // 'difficultydefault:' + digits + char reply[1024] = ""; + size_t siz = sizeof(reply); + WORKERS *workers; + USERS *users; + int32_t difficultydefault; + char *reason = NULL; + char *answer = NULL; + int workernum; + bool ok; + + LOGDEBUG("%s(): cmd '%s'", __func__, cmd); + + i_username = require_name(trf_root, "username", 3, (char *)userpatt, reply, siz); + if (!i_username) { + // For web this message is detailed enough + reason = "System error"; + goto struckout; + } + + K_RLOCK(users_free); + u_item = find_users(transfer_data(i_username)); + K_RUNLOCK(users_free); + + if (!u_item) { + reason = "Unknown user"; + goto struckout; + } else { + DATA_USERS(users, u_item); + + // Default answer if no problems + answer = strdup("updated"); + + // Loop through the list of workers and do any changes + for (workernum = 0; workernum < 9999; workernum++) { + snprintf(workername_buf, sizeof(workername_buf), + "workername:%d", workernum); + + i_workername = optional_name(trf_root, workername_buf, + 1, NULL, reply, siz); + if (!i_workername) + break; + + w_item = find_workers(users->userid, + transfer_data(i_workername)); + // Abort if any dont exist + if (!w_item) { + reason = "Unknown worker"; + break; + } + + DATA_WORKERS(workers, w_item); + + snprintf(diffdef_buf, sizeof(diffdef_buf), + "difficultydefault:%d", workernum); + + i_diffdef = optional_name(trf_root, diffdef_buf, + 1, (char *)intpatt, + reply, siz); + + // Abort if any are invalid + if (*reply) { + reason = "Invalid diff"; + break; + } + + if (!i_diffdef) + continue; + + difficultydefault = atoi(transfer_data(i_diffdef)); + if (difficultydefault < DIFFICULTYDEFAULT_MIN) + difficultydefault = DIFFICULTYDEFAULT_MIN; + if (difficultydefault > DIFFICULTYDEFAULT_MAX) + difficultydefault = DIFFICULTYDEFAULT_MAX; + + if (workers->difficultydefault != difficultydefault) { + /* This uses a seperate txn per update + thus will update all up to a failure + Since the web then re-gets the values, + it will show what was updated */ + workers->difficultydefault = difficultydefault; + ok = workers_update(conn, w_item, NULL, NULL, + NULL, by, code, inet, + now, trf_root, false); + if (!ok) { + reason = "DB error"; + break; + } + } + } + } + +struckout: + if (reason) { + if (answer) + free(answer); + snprintf(reply, siz, "ERR.%s", reason); + LOGERR("%s.%s.%s", cmd, id, reply); + return strdup(reply); + } + snprintf(reply, siz, "ok.%s", answer); + LOGDEBUG("%s.%s", id, answer); + free(answer); + return strdup(reply); +} + static char *cmd_poolstats_do(PGconn *conn, char *cmd, char *id, char *by, char *code, char *inet, tv_t *cd, bool igndup, K_TREE *trf_root) @@ -12170,6 +12290,7 @@ static struct CMDS { { CMD_NEWPASS, "newpass", false, false, cmd_newpass, ACCESS_WEB }, { CMD_CHKPASS, "chkpass", false, false, cmd_chkpass, ACCESS_WEB }, { CMD_USERSET, "usersettings", false, false, cmd_userset, ACCESS_WEB }, + { CMD_WORKERSET,"workerset", false, false, cmd_workerset, ACCESS_WEB }, { CMD_POOLSTAT, "poolstats", false, true, cmd_poolstats, ACCESS_POOL }, { CMD_USERSTAT, "userstats", false, true, cmd_userstats, ACCESS_POOL }, { CMD_BLOCK, "block", false, true, cmd_blocks, ACCESS_POOL }, @@ -12852,6 +12973,7 @@ static void *socketer(__maybe_unused void *arg) char *last_adduser = NULL, *reply_adduser = NULL; char *last_newpass = NULL, *reply_newpass = NULL; char *last_userset = NULL, *reply_userset = NULL; + char *last_workerset = NULL, *reply_workerset = NULL; char *last_newid = NULL, *reply_newid = NULL; char *last_setatts = NULL, *reply_setatts = NULL; char *last_setopts = NULL, *reply_setopts = NULL; @@ -12866,7 +12988,7 @@ static void *socketer(__maybe_unused void *arg) K_ITEM *item; size_t siz; tv_t now, cd; - bool dup, want_first; + bool dup, want_first, show_dup; int loglevel, oldloglevel; pthread_detach(pthread_self()); @@ -12924,6 +13046,7 @@ static void *socketer(__maybe_unused void *arg) * command arrived between two duplicate commands */ dup = false; + show_dup = true; // These are ordered approximately most likely first if (last_auth && strcmp(last_auth, buf) == 0) { reply_last = reply_auth; @@ -12946,6 +13069,9 @@ static void *socketer(__maybe_unused void *arg) } else if (last_userset && strcmp(last_userset, buf) == 0) { reply_last = reply_userset; dup = true; + } else if (last_workerset && strcmp(last_workerset, buf) == 0) { + reply_last = reply_workerset; + dup = true; } else if (last_setatts && strcmp(last_setatts, buf) == 0) { reply_last = reply_setatts; dup = true; @@ -12955,6 +13081,7 @@ static void *socketer(__maybe_unused void *arg) } else if (last_web && strcmp(last_web, buf) == 0) { reply_last = reply_web; dup = true; + show_dup = false; } if (dup) { send_unix_msg(sockd, reply_last); @@ -12965,7 +13092,10 @@ static void *socketer(__maybe_unused void *arg) snprintf(reply, sizeof(reply), "%s%ld,%ld.%s", LOGDUP, now.tv_sec, now.tv_usec, duptype); LOGQUE(reply); - LOGWARNING("Duplicate '%s' message received", duptype); + if (show_dup) + LOGWARNING("Duplicate '%s' message received", duptype); + else + LOGDEBUG("Duplicate '%s' message received", duptype); } else { LOGQUE(buf); cmdnum = breakdown(&trf_root, &trf_store, buf, &which_cmds, cmd, id, &cd); @@ -13039,6 +13169,7 @@ static void *socketer(__maybe_unused void *arg) case CMD_ADDUSER: case CMD_NEWPASS: case CMD_USERSET: + case CMD_WORKERSET: case CMD_GETATTS: case CMD_SETATTS: case CMD_EXPATTS: @@ -13077,6 +13208,9 @@ static void *socketer(__maybe_unused void *arg) case CMD_USERSET: STORELASTREPLY(userset); break; + case CMD_WORKERSET: + STORELASTREPLY(workerset); + break; case CMD_NEWID: STORELASTREPLY(newid); break; @@ -13274,6 +13408,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf) case CMD_NEWPASS: case CMD_CHKPASS: case CMD_USERSET: + case CMD_WORKERSET: case CMD_BLOCKLIST: case CMD_BLOCKSTATUS: case CMD_NEWID: