From f0bb50667db257cb66fd60335e11f0237dd1d6c0 Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 12 Jul 2015 16:04:38 +1000 Subject: [PATCH 01/24] ckdb - update version number for logmsg change --- src/ckdb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ckdb.h b/src/ckdb.h index 0c9f80bb..05052701 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.0" -#define CKDB_VERSION DB_VERSION"-1.112" +#define CKDB_VERSION DB_VERSION"-1.113" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ From 733664cc80ca050b0bb30adb1ccdde08be289d4a Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 12 Jul 2015 16:27:42 +1000 Subject: [PATCH 02/24] ckpool - report details of rpc request on failure or when slow --- src/ckpool.c | 47 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/src/ckpool.c b/src/ckpool.c index 52ca62dd..86ad3890 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -733,31 +733,33 @@ json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) char *http_req = NULL; json_error_t err_val; json_t *val = NULL; + tv_t stt_tv, fin_tv; + double elapsed; int len, ret; if (unlikely(cs->fd < 0)) { - LOGWARNING("FD %d invalid in json_rpc_call", cs->fd); + LOGWARNING("FD %d invalid in %s", cs->fd, __func__); goto out; } if (unlikely(!cs->url)) { - LOGWARNING("No URL in json_rpc_call"); + LOGWARNING("No URL in %s", __func__); goto out; } if (unlikely(!cs->port)) { - LOGWARNING("No port in json_rpc_call"); + LOGWARNING("No port in %s", __func__); goto out; } if (unlikely(!cs->auth)) { - LOGWARNING("No auth in json_rpc_call"); + LOGWARNING("No auth in %s", __func__); goto out; } if (unlikely(!rpc_req)) { - LOGWARNING("Null rpc_req passed to json_rpc_call"); + LOGWARNING("Null rpc_req passed to %s", __func__); goto out; } len = strlen(rpc_req); if (unlikely(!len)) { - LOGWARNING("Zero length rpc_req passed to json_rpc_call"); + LOGWARNING("Zero length rpc_req passed to %s", __func__); goto out; } http_req = ckalloc(len + 256); // Leave room for headers @@ -770,31 +772,52 @@ json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) cs->auth, cs->url, cs->port, len, rpc_req); len = strlen(http_req); + tv_time(&stt_tv); ret = write_socket(cs->fd, http_req, len); if (ret != len) { - LOGWARNING("Failed to write to socket in json_rpc_call"); + tv_time(&fin_tv); + elapsed = tvdiff(&fin_tv, &stt_tv); + LOGWARNING("Failed to write to socket in %s (%.10s...) %.3fs", + __func__, rpc_req, elapsed); goto out_empty; } ret = read_socket_line(cs, &timeout); if (ret < 1) { - LOGWARNING("Failed to read socket line in json_rpc_call"); + tv_time(&fin_tv); + elapsed = tvdiff(&fin_tv, &stt_tv); + LOGWARNING("Failed to read socket line in %s (%.10s...) %.3fs", + __func__, rpc_req, elapsed); goto out_empty; } if (strncasecmp(cs->buf, "HTTP/1.1 200 OK", 15)) { - LOGWARNING("HTTP response not ok: %s", cs->buf); + tv_time(&fin_tv); + elapsed = tvdiff(&fin_tv, &stt_tv); + LOGWARNING("HTTP response to (%.10s...) %.3fs not ok: %s", + rpc_req, elapsed, cs->buf); goto out_empty; } do { ret = read_socket_line(cs, &timeout); if (ret < 1) { - LOGWARNING("Failed to read http socket lines in json_rpc_call"); + tv_time(&fin_tv); + elapsed = tvdiff(&fin_tv, &stt_tv); + LOGWARNING("Failed to read http socket lines in %s (%.10s...) %.3fs", + __func__, rpc_req, elapsed); goto out_empty; } } while (strncmp(cs->buf, "{", 1)); + tv_time(&fin_tv); + elapsed = tvdiff(&fin_tv, &stt_tv); + if (elapsed > 5.0) { + LOGWARNING("HTTP socket read+write took %.3fs in %s (%.10s...)", + elapsed, __func__, rpc_req); + } val = json_loads(cs->buf, 0, &err_val); - if (!val) - LOGWARNING("JSON decode failed(%d): %s", err_val.line, err_val.text); + if (!val) { + LOGWARNING("JSON decode (%.10s...) failed(%d): %s", + rpc_req, err_val.line, err_val.text); + } out_empty: empty_socket(cs->fd); empty_buffer(cs); From da285f8ab4c85bca8d2906329fc7c030aa20019a Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 12 Jul 2015 17:07:52 +1000 Subject: [PATCH 03/24] ckpool - display the rpc request warn messages from the method --- src/ckpool.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/ckpool.c b/src/ckpool.c index 86ad3890..ff7bc602 100644 --- a/src/ckpool.c +++ b/src/ckpool.c @@ -727,6 +727,14 @@ char *_ckdb_msg_call(const ckpool_t *ckp, const char *msg, const char *file, co return buf; } +static const char *rpc_method(const char *rpc_req) +{ + const char *ptr = strchr(rpc_req, ':'); + if (ptr) + return ptr+1; + return rpc_req; +} + json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) { float timeout = RPC_TIMEOUT; @@ -778,7 +786,7 @@ json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) tv_time(&fin_tv); elapsed = tvdiff(&fin_tv, &stt_tv); LOGWARNING("Failed to write to socket in %s (%.10s...) %.3fs", - __func__, rpc_req, elapsed); + __func__, rpc_method(rpc_req), elapsed); goto out_empty; } ret = read_socket_line(cs, &timeout); @@ -786,14 +794,14 @@ json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) tv_time(&fin_tv); elapsed = tvdiff(&fin_tv, &stt_tv); LOGWARNING("Failed to read socket line in %s (%.10s...) %.3fs", - __func__, rpc_req, elapsed); + __func__, rpc_method(rpc_req), elapsed); goto out_empty; } if (strncasecmp(cs->buf, "HTTP/1.1 200 OK", 15)) { tv_time(&fin_tv); elapsed = tvdiff(&fin_tv, &stt_tv); LOGWARNING("HTTP response to (%.10s...) %.3fs not ok: %s", - rpc_req, elapsed, cs->buf); + rpc_method(rpc_req), elapsed, cs->buf); goto out_empty; } do { @@ -802,7 +810,7 @@ json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) tv_time(&fin_tv); elapsed = tvdiff(&fin_tv, &stt_tv); LOGWARNING("Failed to read http socket lines in %s (%.10s...) %.3fs", - __func__, rpc_req, elapsed); + __func__, rpc_method(rpc_req), elapsed); goto out_empty; } } while (strncmp(cs->buf, "{", 1)); @@ -810,13 +818,13 @@ json_t *json_rpc_call(connsock_t *cs, const char *rpc_req) elapsed = tvdiff(&fin_tv, &stt_tv); if (elapsed > 5.0) { LOGWARNING("HTTP socket read+write took %.3fs in %s (%.10s...)", - elapsed, __func__, rpc_req); + elapsed, __func__, rpc_method(rpc_req)); } val = json_loads(cs->buf, 0, &err_val); if (!val) { LOGWARNING("JSON decode (%.10s...) failed(%d): %s", - rpc_req, err_val.line, err_val.text); + rpc_method(rpc_req), err_val.line, err_val.text); } out_empty: empty_socket(cs->fd); From e7aa081d43ec22b3513cefcb5c7c64dbc68c8021 Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 12 Jul 2015 22:29:30 +1000 Subject: [PATCH 04/24] libckpool - report errno with _write_length failure --- src/libckpool.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libckpool.c b/src/libckpool.c index 50358ab9..745eba49 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -1005,7 +1005,7 @@ out: int _write_length(int sockd, const void *buf, int len, const char *file, const char *func, const int line) { - int ret, ofs = 0; + int ret, ofs = 0, ern; if (unlikely(len < 1)) { LOGWARNING("Invalid write length of %d requested in write_length from %s %s:%d", @@ -1013,6 +1013,7 @@ int _write_length(int sockd, const void *buf, int len, const char *file, const c return -1; } if (unlikely(sockd < 0)) { + ern = errno; LOGWARNING("Attempt to write to invalidated sock in write_length from %s %s:%d", file, func, line); return -1; @@ -1020,8 +1021,9 @@ int _write_length(int sockd, const void *buf, int len, const char *file, const c while (len) { ret = write(sockd, buf + ofs, len); if (unlikely(ret < 0)) { - LOGERR("Failed to write %d bytes in write_length from %s %s:%d", - len, file, func, line); + ern = errno; + LOGERR("Failed to write %d bytes in write_length (%d) from %s %s:%d", + len, ern, file, func, line); return -1; } ofs += ret; From 0608a79f14bdf3cc9b22bcb1d40b3866a531c02d Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 12 Jul 2015 22:37:27 +1000 Subject: [PATCH 05/24] libckpool - report errno with _recv_unix_msg errors --- src/libckpool.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libckpool.c b/src/libckpool.c index 745eba49..91799eff 100644 --- a/src/libckpool.c +++ b/src/libckpool.c @@ -948,17 +948,19 @@ char *_recv_unix_msg(int sockd, int timeout1, int timeout2, const char *file, co { char *buf = NULL; uint32_t msglen; - int ret; + int ret, ern; ret = wait_read_select(sockd, timeout1); if (unlikely(ret < 1)) { - LOGERR("Select1 failed in recv_unix_msg"); + ern = errno; + LOGERR("Select1 failed in recv_unix_msg (%d)", ern); goto out; } /* Get message length */ ret = read_length(sockd, &msglen, 4); if (unlikely(ret < 4)) { - LOGERR("Failed to read 4 byte length in recv_unix_msg"); + ern = errno; + LOGERR("Failed to read 4 byte length in recv_unix_msg (%d?)", ern); goto out; } msglen = le32toh(msglen); @@ -968,13 +970,15 @@ char *_recv_unix_msg(int sockd, int timeout1, int timeout2, const char *file, co } ret = wait_read_select(sockd, timeout2); if (unlikely(ret < 1)) { - LOGERR("Select2 failed in recv_unix_msg"); + ern = errno; + LOGERR("Select2 failed in recv_unix_msg (%d)", ern); goto out; } buf = ckzalloc(msglen + 1); ret = read_length(sockd, buf, msglen); if (unlikely(ret < (int)msglen)) { - LOGERR("Failed to read %u bytes in recv_unix_msg", msglen); + ern = errno; + LOGERR("Failed to read %u bytes in recv_unix_msg (%d?)", msglen, ern); dealloc(buf); } out: From c469ad83c0978ec81ddb1eef518a843f8e83ad69 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 16 Jul 2015 10:16:46 +1000 Subject: [PATCH 06/24] php - update payout explanation --- pool/inc.php | 2 ++ pool/page_payout.php | 63 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/pool/inc.php b/pool/inc.php index 9710fe8b..dea5baf0 100644 --- a/pool/inc.php +++ b/pool/inc.php @@ -91,6 +91,8 @@ span.login {float:right;margin-left:8px;margin-right:24px;} span.hil {color:blue;} span.user {color:green;} span.addr {color:brown;} +span.hdr {font-weight:bold;text-decoration:underline;} +span.nn {font-weight:bold;color:red;} span.warn {color:orange;font-weight:bold;} span.urg {color:red;font-weight:bold;} span.err {color:red;font-weight:bold;font-size:120%;} diff --git a/pool/page_payout.php b/pool/page_payout.php index 2363c1a3..a4fda932 100644 --- a/pool/page_payout.php +++ b/pool/page_payout.php @@ -2,20 +2,55 @@ # function dopayout($data, $user) { - $pg = '

Payouts

'; - $pg .= ''; - $pg .= '
'; - $pg .= 'We use PPLNS (pay per last N shares)

'; - $pg .= 'The N value used for PPLNS is 5 times the network difficulty'; - $pg .= ' when a block is found,
'; - $pg .= 'but includes the full shift at the start and end of the range,
'; - $pg .= 'so it usually will be a bit more than 5N.

'; - $pg .= 'Shifts are ~50min long, however, when we find any pool blocks
'; - $pg .= 'the current shift ends at the point the block was found.
'; - $pg .= 'A ckpool restart will also start a new shift.

'; - $pg .= 'Transaction fees are included in the miner payout.
'; - $pg .= 'Pool fee is 0.9% of the total.
'; - $pg .= '
'; + $t = '5'; + $ot = '1/5'; + $n = '5Nd'; + $n1 = 'N'; + $bc = '+101 Confirms'; + $bm = 'Matured'; + $nd = 0; + if (isset($data['info']['currndiff'])) + $nd = $data['info']['currndiff']; + $nv = number_format($nd, 1); + $nv5 = number_format(5.0*$nd, 1); + $pg = "

Payouts

+
+ +What payout method does the pool use?

+We use PPL${n1}S (Pay Per Last $n1 Shares)

+PPL${n1}S means that when a block is found, the block reward is shared among the last $n1 shares that miners sent to the pool, up to when the block was found.
+The $n1 value the pool uses is $t times the network difficulty when the block is found - '$n'.

+ +How much of each block does the pool reward?

+Transaction fees are included in the miner reward.
+Pool fee is 0.9% of the total.

+ +How do the payments work?

+The $n means the pool rewards $t times the expected number of shares, each time a block is found.
+So each share will be paid appoximately $ot of it's expected value, in each block it gets a reward,
+but each share is also expected, on average, to be rewarded $t times in blocks found after the share is submitted to the pool.
+i.e. if pool luck was always 100% then each share is expected to be rewarded $t times.

+If pool luck is better than 100%, then the average share reward wil be better than $t times.
+If pool luck is lower than 100%, then the average share reward will be less than $t times.

+ +What's a shift?

+When your miner sends shares to the pool, the shares are not stored individually, but rather summarised into shifts.
+Shifts are ~50min or less in length, however, when we find any pool blocks the current shift ends early,
+at the point the block was found.
+A ckpool restart will also end the current shift and start a new one.

+ +So, what's the $n value?

+The current Bitcoin network value for $n1 is $nv and thus $n is $nv5
+Bitcoin adjusts the $n1 value every 2016 blocks, which is about every 2 weeks.

+When a block is found, the reward process counts back shifts until the total share difficulty included is $n.
+Since shares are summaried into shifts, it will includes the full shift at the end of the range counting backwards,
+so it usually will be a bit more than $n.

+ +When are payments sent out?

+The block 'Status' must first reach '$bc' on the Blocks page, and then is flagged as '$bm', before the reward is distributed.
+The block reward is sent out manually soon after that.

+ +
"; return $pg; } # From 73e767925c23b0b5a5d94a3b250c56ad5c34bbf2 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 16 Jul 2015 10:26:08 +1000 Subject: [PATCH 07/24] php - typo --- pool/page_payout.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pool/page_payout.php b/pool/page_payout.php index a4fda932..edc1a82a 100644 --- a/pool/page_payout.php +++ b/pool/page_payout.php @@ -43,7 +43,7 @@ A ckpool restart will also end the current shift and start a new one.

The current Bitcoin network value for $n1 is $nv and thus $n is $nv5
Bitcoin adjusts the $n1 value every 2016 blocks, which is about every 2 weeks.

When a block is found, the reward process counts back shifts until the total share difficulty included is $n.
-Since shares are summaried into shifts, it will includes the full shift at the end of the range counting backwards,
+Since shares are summaried into shifts, it will include the full shift at the end of the range counting backwards,
so it usually will be a bit more than $n.

When are payments sent out?

From 8eac065f1fff1009f6378e6f989234a2a818c2ee Mon Sep 17 00:00:00 2001 From: kanoi Date: Fri, 17 Jul 2015 08:48:16 +1000 Subject: [PATCH 08/24] php - more update payout --- pool/page_payout.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pool/page_payout.php b/pool/page_payout.php index edc1a82a..e2ae2e6e 100644 --- a/pool/page_payout.php +++ b/pool/page_payout.php @@ -6,6 +6,7 @@ function dopayout($data, $user) $ot = '1/5'; $n = '5Nd'; $n1 = 'N'; + $n1d = 'Nd'; $bc = '+101 Confirms'; $bm = 'Matured'; $nd = 0; @@ -13,6 +14,7 @@ function dopayout($data, $user) $nd = $data['info']['currndiff']; $nv = number_format($nd, 1); $nv5 = number_format(5.0*$nd, 1); + $pg = "

Payouts

'; $pg .= ""; $pg .= ""; - $pg .= ""; + $pg .= ""; $pg .= ""; $pg .= "\n"; } From 9f76f6256c023f5770068b9649acb661ab3736da Mon Sep 17 00:00:00 2001 From: kanoi Date: Mon, 20 Jul 2015 08:11:48 +1000 Subject: [PATCH 10/24] php - add workers sort on invalid --- pool/page_workers.php | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/pool/page_workers.php b/pool/page_workers.php index d87ea691..c0f638c2 100644 --- a/pool/page_workers.php +++ b/pool/page_workers.php @@ -10,7 +10,7 @@ function worktitle($data, $user) $pg .= ""; $pg .= ''; $pg .= ""; - $pg .= ''; + $pg .= ""; $pg .= ''; $pg .= ""; $pg .= "\n"; @@ -92,25 +92,33 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, $shareacc = number_format($all[$i]['w_shareacc'], 0); $totshare += $all[$i]['w_shareacc']; - $diffacc = number_format($all[$i]['w_diffacc'], 0); - $ds = round($all[$i]['w_diffacc']); - $totdiff += $all[$i]['w_diffacc']; + $dacc = $all[$i]['w_diffacc']; + $diffacc = number_format($dacc, 0); + $ds = round($dacc); + $totdiff += $dacc; $pg .= ""; $pg .= ""; - $dtot = $all[$i]['w_diffacc'] + $all[$i]['w_diffinv']; + $dinv = $all[$i]['w_diffinv']; + $dtot = $dacc + $dinv; if ($dtot > 0) - $rej = number_format(100.0 * $all[$i]['w_diffinv'] / $dtot, 3); + { + $rejf = $dinv / $dtot; + $rej = number_format(100.0 * $rejf, 3); + } else + { + $rejf = 0; $rej = '0'; - $totinvalid += $all[$i]['w_diffinv']; + } + $totinvalid += $dinv; - $pg .= ""; + $pg .= ""; if ($blockacc <= 0) $blkpct = ' '; else - $blkpct = number_format(100.0 * $all[$i]['w_diffacc'] / $blockacc, 3) . '%'; + $blkpct = number_format(100.0 * $dacc / $blockacc, 3) . '%'; $pg .= ""; From 405da3cb34c7f27453371f0479afbc684e156f82 Mon Sep 17 00:00:00 2001 From: kanoi Date: Mon, 20 Jul 2015 11:19:53 +1000 Subject: [PATCH 11/24] php - set header invalids to show for both shares and diff --- pool/page.php | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/pool/page.php b/pool/page.php index 6a64d2eb..58edbc07 100644 --- a/pool/page.php +++ b/pool/page.php @@ -165,6 +165,7 @@ function pgtop($info, $dotop, $user, $douser) $nlb = '?'; $pac = '0'; $per = '0'; + $perset = false; $uhr = '?GHs'; $u1hr = ''; if ($info !== false) @@ -244,12 +245,46 @@ function pgtop($info, $dotop, $user, $douser) } } + if (isset($info['blockshareinv'])) + { + $shinv = $info['blockshareinv']; + $per = siprefmt($shinv, 1); + $perset = true; + if (isset($info['blockshareacc'])) + { + $shacc = $info['blockshareacc']; + if (($shacc+$shinv) > 0) + { + $amt = 100.0 * $shinv / ($shacc + $shinv); + if (round($amt, 2) > 9.99) + $per .= ' ('.number_format($amt, 1).'%)'; + else + $per .= ' ('.number_format($amt, 2).'%)'; + } + } + } + if (isset($info['blockerr'])) { - $rej = $info['blockerr']; - $per = number_format($info['blockerr'], 0); - if (isset($info['blockacc']) && ($acc+$rej) > 0) - $per .= ' ('.number_format(100.0*$rej/($acc+$rej), 3).'%)'; + if ($perset == false) + $per = ''; + else + $per .= ' · '; + + $inv = $info['blockerr']; + $per .= siprefmt($inv, 1); + if (isset($info['blockacc'])) + { + $acc = $info['blockacc']; + if (($acc+$inv) > 0) + { + $amt = 100.0 * $inv / ($acc + $inv); + if (round($amt, 2) > 9.99) + $per .= ' ('.number_format($amt, 1).'%)'; + else + $per .= ' ('.number_format($amt, 2).'%)'; + } + } } if (isset($info['u_hashrate5m'])) @@ -350,7 +385,7 @@ function pgtop($info, $dotop, $user, $douser) $top .= ""; $top .= ''; $top .= ""; - $top .= ''; + $top .= ''; $top .= "
@@ -40,10 +42,10 @@ at the point the block was found.
A ckpool restart will also end the current shift and start a new one.

So, what's the $n value?

-The current Bitcoin network value for $n1 is $nv and thus $n is $nv5
-Bitcoin adjusts the $n1 value every 2016 blocks, which is about every 2 weeks.

+The current Bitcoin network value for $n1d is $nv and thus $n is $nv5
+Bitcoin adjusts the $n1d value every 2016 blocks, which is about every 2 weeks.

When a block is found, the reward process counts back shifts until the total share difficulty included is $n.
-Since shares are summaried into shifts, it will include the full shift at the end of the range counting backwards,
+Since shares are summarised into shifts, it will include the full shift at the end of the range counting backwards,
so it usually will be a bit more than $n.

When are payments sent out?

From 60cfbac4d51c244760790a9f18ea3feb8eee15c3 Mon Sep 17 00:00:00 2001 From: kanoi Date: Fri, 17 Jul 2015 09:03:10 +1000 Subject: [PATCH 09/24] php - blocks: make the ~ colour match the Diff% colour --- pool/page_blocks.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pool/page_blocks.php b/pool/page_blocks.php index c294ba4c..6582ee96 100644 --- a/pool/page_blocks.php +++ b/pool/page_blocks.php @@ -204,7 +204,7 @@ function doblocks($data, $user) { $pct = 100.0 * $diffratio; list($fg, $bg) = pctcolour($pct); - $bpct = "".number_format($pct, 2).'%'; + $bpct = "$approx".number_format($pct, 2).'%'; $bg = " bgcolor=$bg"; $blktot += $diffacc; if ($stat != 'Orphan') @@ -230,7 +230,7 @@ function doblocks($data, $user) $pg .= "
".utcd($ans['firstcreatedate:'.$i]).'$stat$stara$approx$acc$approx$bpct$bpct$cdfdsp
<$r id=srtlst data-sf=n2>:Last ShareShares<$r id=srtdiff data-sf=r4>:DiffInvalid<$r id=srtinv data-sf=r5>:InvalidBlock %<$r id=srtrate data-sf=r7>:Hash Rate
$shareacc$diffacc$rej%$rej%$blkpct $phr
Shares:  $pac
Invalid: 
Invalids:  $per
"; $top .= ''; $top .= ''; From 3f24108955d70a95250d9316b37ce272b17d1089 Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 22 Jul 2015 11:49:12 +1000 Subject: [PATCH 12/24] ckdb/php - add a share based hash rate to the workers page --- pool/page_allwork.php | 7 +- pool/page_workers.php | 41 +++++++++--- src/ckdb.h | 40 +++++++---- src/ckdb_cmd.c | 78 +++++++++++++--------- src/ckdb_data.c | 152 +++++++++++++++++++++++++++--------------- 5 files changed, 209 insertions(+), 109 deletions(-) diff --git a/pool/page_allwork.php b/pool/page_allwork.php index d190f398..e289e8ac 100644 --- a/pool/page_allwork.php +++ b/pool/page_allwork.php @@ -10,6 +10,7 @@ function doallwork($data, $user) $totshare = 0; $totdiff = 0; + $totshrate = 0; $totinvalid = 0; $totrate = 0; $offset = 0; @@ -26,13 +27,13 @@ function doallwork($data, $user) { $pg .= workuser($data, $ans['username:'.$i], $offset, $totshare, $totdiff, - $totinvalid, $totrate, + $totshrate, $totinvalid, $totrate, $blockacc, $blockreward, 3600); } } - $pg .= worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate, - $blockacc, $blockreward); + $pg .= worktotal($offset, $totshare, $totdiff, $totshrate, $totinvalid, + $totrate, $blockacc, $blockreward); $pg .= "
\n"; diff --git a/pool/page_workers.php b/pool/page_workers.php index c0f638c2..07987311 100644 --- a/pool/page_workers.php +++ b/pool/page_workers.php @@ -10,9 +10,10 @@ function worktitle($data, $user) $pg .= "<$r id=srtlst data-sf=n2>:Last Share"; $pg .= 'Shares'; $pg .= "<$r id=srtdiff data-sf=r4>:Diff"; - $pg .= "<$r id=srtinv data-sf=r5>:Invalid"; + $pg .= "<$r id=srtshrate data-sf=r5>:Share Rate"; + $pg .= "<$r id=srtinv data-sf=r6>:Invalid"; $pg .= 'Block %'; - $pg .= "<$r id=srtrate data-sf=r7>:Hash Rate"; + $pg .= "<$r id=srtrate data-sf=r8>:Hash Rate"; $pg .= "\n"; return $pg; } @@ -23,7 +24,7 @@ function workhashorder($a, $b) } # function workuser($data, $user, &$offset, &$totshare, &$totdiff, - &$totinvalid, &$totrate, &$blockacc, + &$totshrate, &$totinvalid, &$totrate, &$blockacc, &$blockreward, $old = false, $srt = false, $one = false, &$title) { @@ -63,6 +64,8 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, 'w_diffacc' => $ans['w_diffacc:'.$i], 'w_diffinv' => $ans['w_diffinv:'.$i], 'w_lastdiff' => $ans['w_lastdiff:'.$i], + 'w_active_diffacc' => $ans['w_active_diffacc:'.$i], + 'w_active_start' => $ans['w_active_start:'.$i], 'w_uhr' => $uhr); } @@ -99,6 +102,22 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, $pg .= "$shareacc"; $pg .= "$diffacc"; + $acthr = '0'; + $acthrv = 0; + $actstt = $all[$i]['w_active_start']; + if ($actstt > 0) + { + $elapsed = $ans['STAMP'] - $actstt; + if ($elapsed > 0) + { + $acthrv = $all[$i]['w_active_diffacc'] * + pow(2,32) / $elapsed; + $acthr = dsprate($acthrv); + $totshrate += $acthrv; + } + } + $pg .= "$acthr"; + $dinv = $all[$i]['w_diffinv']; $dtot = $dacc + $dinv; if ($dtot > 0) @@ -144,9 +163,11 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, return $pg; } # -function worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate, $blockacc, $blockreward) +function worktotal($offset, $totshare, $totdiff, $totshrate, $totinvalid, + $totrate, $blockacc, $blockreward) { $pg = ''; + $totshrate = dsprate($totshrate); $totrate = dsprate($totrate); if (($offset % 2) == 0) $row = 'even'; @@ -157,6 +178,7 @@ function worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate, $blockac $pg .= "$shareacc"; $diffacc = number_format($totdiff, 0); $pg .= "$diffacc"; + $pg .= "$totshrate"; $dtot = $totdiff + $totinvalid; if ($dtot > 0) $rej = number_format(100.0 * $totinvalid / $dtot, 3); @@ -180,6 +202,7 @@ function doworker($data, $user) $totshare = 0; $totdiff = 0; + $totshrate = 0; $totinvalid = 0; $totrate = 0; $offset = 0; @@ -187,11 +210,11 @@ function doworker($data, $user) $blockreward = 0; $pg .= worktitle($data, $user); - $pg .= workuser($data, $user, $offset, $totshare, $totdiff, $totinvalid, - $totrate, $blockacc, $blockreward, false, true, true, - $title); - $pg .= worktotal($offset, $totshare, $totdiff, $totinvalid, $totrate, - $blockacc, $blockreward); + $pg .= workuser($data, $user, $offset, $totshare, $totdiff, $totshrate, + $totinvalid, $totrate, $blockacc, $blockreward, + false, true, true, $title); + $pg .= worktotal($offset, $totshare, $totdiff, $totshrate, $totinvalid, + $totrate, $blockacc, $blockreward); if (false && $blockacc > 0 && $blockreward > 0) { diff --git a/src/ckdb.h b/src/ckdb.h index 05052701..b3feaaa7 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.0" -#define CKDB_VERSION DB_VERSION"-1.113" +#define CKDB_VERSION DB_VERSION"-1.120" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -1735,18 +1735,32 @@ typedef struct workerstatus { tv_t last_stats; tv_t last_idle; // Below gets reset on each block - double diffacc; - double diffinv; // Non-acc - double diffsta; - double diffdup; - double diffhi; - double diffrej; - double shareacc; - double shareinv; // Non-acc - double sharesta; - double sharedup; - double sharehi; - double sharerej; + double block_diffacc; + double block_diffinv; // Non-acc + double block_diffsta; + double block_diffdup; + double block_diffhi; + double block_diffrej; + double block_shareacc; + double block_shareinv; // Non-acc + double block_sharesta; + double block_sharedup; + double block_sharehi; + double block_sharerej; + // Below gets reset on each idle + double active_diffacc; + double active_diffinv; // Non-acc + double active_diffsta; + double active_diffdup; + double active_diffhi; + double active_diffrej; + double active_shareacc; + double active_shareinv; // Non-acc + double active_sharesta; + double active_sharedup; + double active_sharehi; + double active_sharerej; + tv_t active_start; } WORKERSTATUS; #define ALLOC_WORKERSTATUS 1000 diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 656ac868..c7b4565a 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -1395,18 +1395,18 @@ static char *cmd_percent(char *cmd, char *id, tv_t *now, USERS *users) ws_item = get_workerstatus(users->userid, workers->workername); if (ws_item) { DATA_WORKERSTATUS(workerstatus, ws_item); - t_diffacc += workerstatus->diffacc; - t_diffinv += workerstatus->diffinv; - t_diffsta += workerstatus->diffsta; - t_diffdup += workerstatus->diffdup; - t_diffhi += workerstatus->diffhi; - t_diffrej += workerstatus->diffrej; - t_shareacc += workerstatus->shareacc; - t_shareinv += workerstatus->shareinv; - t_sharesta += workerstatus->sharesta; - t_sharedup += workerstatus->sharedup; - t_sharehi += workerstatus->sharehi; - t_sharerej += workerstatus->sharerej; + t_diffacc += workerstatus->block_diffacc; + t_diffinv += workerstatus->block_diffinv; + t_diffsta += workerstatus->block_diffsta; + t_diffdup += workerstatus->block_diffdup; + t_diffhi += workerstatus->block_diffhi; + t_diffrej += workerstatus->block_diffrej; + t_shareacc += workerstatus->block_shareacc; + t_shareinv += workerstatus->block_shareinv; + t_sharesta += workerstatus->block_sharesta; + t_sharedup += workerstatus->block_sharedup; + t_sharehi += workerstatus->block_sharehi; + t_sharerej += workerstatus->block_sharerej; } /* TODO: workers_root userid+worker is ordered @@ -1692,6 +1692,8 @@ static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id, double w_shareacc, w_shareinv; double w_sharesta, w_sharedup; double w_sharehi, w_sharerej; + double w_active_diffacc; + tv_t w_active_start; w_hashrate5m = w_hashrate1hr = w_hashrate24hr = 0.0; @@ -1699,30 +1701,34 @@ static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id, if (!ws_item) { w_lastshare.tv_sec = 0; - w_lastdiff = w_diffacc = w_diffinv = - w_diffsta = w_diffdup = - w_diffhi = w_diffrej = - w_shareacc = w_shareinv = - w_sharesta = w_sharedup = - w_sharehi = w_sharerej = 0; + w_lastdiff = w_diffacc = + w_diffinv = w_diffsta = + w_diffdup = w_diffhi = + w_diffrej = w_shareacc = + w_shareinv = w_sharesta = + w_sharedup = w_sharehi = + w_sharerej = w_active_diffacc = 0; + w_active_start.tv_sec = 0; } else { DATA_WORKERSTATUS(workerstatus, ws_item); // It's bad to read possibly changing data K_RLOCK(workerstatus_free); w_lastshare.tv_sec = workerstatus->last_share.tv_sec; w_lastdiff = workerstatus->last_diff; - w_diffacc = workerstatus->diffacc; - w_diffinv = workerstatus->diffinv; - w_diffsta = workerstatus->diffsta; - w_diffdup = workerstatus->diffdup; - w_diffhi = workerstatus->diffhi; - w_diffrej = workerstatus->diffrej; - w_shareacc = workerstatus->shareacc; - w_shareinv = workerstatus->shareinv; - w_sharesta = workerstatus->sharesta; - w_sharedup = workerstatus->sharedup; - w_sharehi = workerstatus->sharehi; - w_sharerej = workerstatus->sharerej; + w_diffacc = workerstatus->block_diffacc; + w_diffinv = workerstatus->block_diffinv; + w_diffsta = workerstatus->block_diffsta; + w_diffdup = workerstatus->block_diffdup; + w_diffhi = workerstatus->block_diffhi; + w_diffrej = workerstatus->block_diffrej; + w_shareacc = workerstatus->block_shareacc; + w_shareinv = workerstatus->block_shareinv; + w_sharesta = workerstatus->block_sharesta; + w_sharedup = workerstatus->block_sharedup; + w_sharehi = workerstatus->block_sharehi; + w_sharerej = workerstatus->block_sharerej; + w_active_diffacc = workerstatus->active_diffacc; + w_active_start.tv_sec = workerstatus->active_start.tv_sec; K_RUNLOCK(workerstatus_free); } @@ -1815,6 +1821,15 @@ static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id, double_to_buf(w_sharerej, reply, sizeof(reply)); snprintf(tmp, sizeof(tmp), "w_sharerej:%d=%s%c", rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); + + double_to_buf(w_active_diffacc, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "w_active_diffacc:%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + int_to_buf((int)(w_active_start.tv_sec), reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "w_active_start:%d=%s%c", rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + } rows++; } @@ -1832,7 +1847,8 @@ static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id, "w_lastdiff,w_diffacc,w_diffinv," "w_diffsta,w_diffdup,w_diffhi,w_diffrej," "w_shareacc,w_shareinv," - "w_sharesta,w_sharedup,w_sharehi,w_sharerej" : "", + "w_sharesta,w_sharedup,w_sharehi,w_sharerej," + "w_active_diffacc,w_active_start" : "", FLDSEP); APPEND_REALLOC(buf, off, len, tmp); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 96af3b90..cc5ca7b5 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -871,6 +871,18 @@ K_ITEM *_find_create_workerstatus(int64_t userid, char *workername, return ws_item; } +// workerstatus must be locked +static void zero_on_idle(tv_t *when, WORKERSTATUS *workerstatus) +{ + copy_tv(&(workerstatus->active_start), when); + workerstatus->active_diffacc = workerstatus->active_diffinv = + workerstatus->active_diffsta = workerstatus->active_diffdup = + workerstatus->active_diffhi = workerstatus->active_diffrej = + workerstatus->active_shareacc = workerstatus->active_shareinv = + workerstatus->active_sharesta = workerstatus->active_sharedup = + workerstatus->active_sharehi = workerstatus->active_sharerej = 0.0; +} + /* All data is loaded, now update workerstatus fields TODO: combine set_block_share_counters() with this? */ void workerstatus_ready() @@ -939,6 +951,8 @@ void _workerstatus_update(AUTHS *auths, SHARES *shares, K_WLOCK(workerstatus_free); if (tv_newer(&(row->last_auth), &(auths->createdate))) copy_tv(&(row->last_auth), &(auths->createdate)); + if (row->active_start.tv_sec == 0) + copy_tv(&(row->active_start), &(auths->createdate)); K_WUNLOCK(workerstatus_free); } } @@ -960,34 +974,54 @@ void _workerstatus_update(AUTHS *auths, SHARES *shares, copy_tv(&(row->last_share), &(shares->createdate)); row->last_diff = shares->diff; } + if (row->active_start.tv_sec == 0) + copy_tv(&(row->active_start), &(shares->createdate)); switch (shares->errn) { case SE_NONE: - row->diffacc += shares->diff; - row->shareacc++; + row->block_diffacc += shares->diff; + row->block_shareacc++; + row->active_diffacc += shares->diff; + row->active_shareacc++; break; case SE_STALE: - row->diffinv += shares->diff; - row->shareinv++; - row->diffsta += shares->diff; - row->sharesta++; + row->block_diffinv += shares->diff; + row->block_shareinv++; + row->block_diffsta += shares->diff; + row->block_sharesta++; + row->active_diffinv += shares->diff; + row->active_shareinv++; + row->active_diffsta += shares->diff; + row->active_sharesta++; break; case SE_DUPE: - row->diffinv += shares->diff; - row->shareinv++; - row->diffdup += shares->diff; - row->sharedup++; + row->block_diffinv += shares->diff; + row->block_shareinv++; + row->block_diffdup += shares->diff; + row->block_sharedup++; + row->active_diffinv += shares->diff; + row->active_shareinv++; + row->active_diffdup += shares->diff; + row->active_sharedup++; break; case SE_HIGH_DIFF: - row->diffinv += shares->diff; - row->shareinv++; - row->diffhi += shares->diff; - row->sharehi++; + row->block_diffinv += shares->diff; + row->block_shareinv++; + row->block_diffhi += shares->diff; + row->block_sharehi++; + row->active_diffinv += shares->diff; + row->active_shareinv++; + row->active_diffhi += shares->diff; + row->active_sharehi++; break; default: - row->diffinv += shares->diff; - row->shareinv++; - row->diffrej += shares->diff; - row->sharerej++; + row->block_diffinv += shares->diff; + row->block_shareinv++; + row->block_diffrej += shares->diff; + row->block_sharerej++; + row->active_diffinv += shares->diff; + row->active_shareinv++; + row->active_diffrej += shares->diff; + row->active_sharerej++; break; } K_WUNLOCK(workerstatus_free); @@ -1001,8 +1035,10 @@ void _workerstatus_update(AUTHS *auths, SHARES *shares, DATA_WORKERSTATUS(row, item); K_WLOCK(workerstatus_free); if (userstats->idle) { - if (tv_newer(&(row->last_idle), &(userstats->statsdate))) + if (tv_newer(&(row->last_idle), &(userstats->statsdate))) { copy_tv(&(row->last_idle), &(userstats->statsdate)); + zero_on_idle(&(userstats->statsdate), row); + } } else { if (tv_newer(&(row->last_stats), &(userstats->statsdate))) copy_tv(&(row->last_stats), &(userstats->statsdate)); @@ -2436,12 +2472,12 @@ void zero_on_new_block() ws_item = first_in_ktree(workerstatus_root, ctx); while (ws_item) { DATA_WORKERSTATUS(workerstatus, ws_item); - workerstatus->diffacc = workerstatus->diffinv = - workerstatus->diffsta = workerstatus->diffdup = - workerstatus->diffhi = workerstatus->diffrej = - workerstatus->shareacc = workerstatus->shareinv = - workerstatus->sharesta = workerstatus->sharedup = - workerstatus->sharehi = workerstatus->sharerej = 0.0; + workerstatus->block_diffacc = workerstatus->block_diffinv = + workerstatus->block_diffsta = workerstatus->block_diffdup = + workerstatus->block_diffhi = workerstatus->block_diffrej = + workerstatus->block_shareacc = workerstatus->block_shareinv = + workerstatus->block_sharesta = workerstatus->block_sharedup = + workerstatus->block_sharehi = workerstatus->block_sharerej = 0.0; ws_item = next_in_ktree(ctx); } K_WUNLOCK(workerstatus_free); @@ -2511,20 +2547,25 @@ void set_block_share_counters() pool.diffacc += sharesummary->diffacc; pool.diffinv += sharesummary->diffsta + sharesummary->diffdup + sharesummary->diffhi + sharesummary->diffrej; - workerstatus->diffacc += sharesummary->diffacc; - workerstatus->diffinv += sharesummary->diffsta + sharesummary->diffdup + - sharesummary->diffhi + sharesummary->diffrej; - workerstatus->diffsta += sharesummary->diffsta; - workerstatus->diffdup += sharesummary->diffdup; - workerstatus->diffhi += sharesummary->diffhi; - workerstatus->diffrej += sharesummary->diffrej; - workerstatus->shareacc += sharesummary->shareacc; - workerstatus->shareinv += sharesummary->sharesta + sharesummary->sharedup + - sharesummary->sharehi + sharesummary->sharerej; - workerstatus->sharesta += sharesummary->sharesta; - workerstatus->sharedup += sharesummary->sharedup; - workerstatus->sharehi += sharesummary->sharehi; - workerstatus->sharerej += sharesummary->sharerej; + // Block stats only + workerstatus->block_diffacc += sharesummary->diffacc; + workerstatus->block_diffinv += sharesummary->diffsta + + sharesummary->diffdup + + sharesummary->diffhi + + sharesummary->diffrej; + workerstatus->block_diffsta += sharesummary->diffsta; + workerstatus->block_diffdup += sharesummary->diffdup; + workerstatus->block_diffhi += sharesummary->diffhi; + workerstatus->block_diffrej += sharesummary->diffrej; + workerstatus->block_shareacc += sharesummary->shareacc; + workerstatus->block_shareinv += sharesummary->sharesta + + sharesummary->sharedup + + sharesummary->sharehi + + sharesummary->sharerej; + workerstatus->block_sharesta += sharesummary->sharesta; + workerstatus->block_sharedup += sharesummary->sharedup; + workerstatus->block_sharehi += sharesummary->sharehi; + workerstatus->block_sharerej += sharesummary->sharerej; ss_item = prev_in_ktree(ctx); } @@ -2589,20 +2630,25 @@ void set_block_share_counters() pool.diffacc += markersummary->diffacc; pool.diffinv += markersummary->diffsta + markersummary->diffdup + markersummary->diffhi + markersummary->diffrej; - workerstatus->diffacc += markersummary->diffacc; - workerstatus->diffinv += markersummary->diffsta + markersummary->diffdup + - markersummary->diffhi + markersummary->diffrej; - workerstatus->diffsta += markersummary->diffsta; - workerstatus->diffdup += markersummary->diffdup; - workerstatus->diffhi += markersummary->diffhi; - workerstatus->diffrej += markersummary->diffrej; - workerstatus->shareacc += markersummary->shareacc; - workerstatus->shareinv += markersummary->sharesta + markersummary->sharedup + - markersummary->sharehi + markersummary->sharerej; - workerstatus->sharesta += markersummary->sharesta; - workerstatus->sharedup += markersummary->sharedup; - workerstatus->sharehi += markersummary->sharehi; - workerstatus->sharerej += markersummary->sharerej; + // Block stats only + workerstatus->block_diffacc += markersummary->diffacc; + workerstatus->block_diffinv += markersummary->diffsta + + markersummary->diffdup + + markersummary->diffhi + + markersummary->diffrej; + workerstatus->block_diffsta += markersummary->diffsta; + workerstatus->block_diffdup += markersummary->diffdup; + workerstatus->block_diffhi += markersummary->diffhi; + workerstatus->block_diffrej += markersummary->diffrej; + workerstatus->block_shareacc += markersummary->shareacc; + workerstatus->block_shareinv += markersummary->sharesta + + markersummary->sharedup + + markersummary->sharehi + + markersummary->sharerej; + workerstatus->block_sharesta += markersummary->sharesta; + workerstatus->block_sharedup += markersummary->sharedup; + workerstatus->block_sharehi += markersummary->sharehi; + workerstatus->block_sharerej += markersummary->sharerej; ms_item = prev_in_ktree(ctx_ms); } From 017da5965d574c16a53323cbca6e7fd5000436c8 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 23 Jul 2015 09:15:17 +1000 Subject: [PATCH 13/24] php - update details for: what's a shift? --- pool/page_payout.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/pool/page_payout.php b/pool/page_payout.php index e2ae2e6e..8f7ff36b 100644 --- a/pool/page_payout.php +++ b/pool/page_payout.php @@ -32,13 +32,16 @@ The $n means the pool rewards $t times the expected number of shares, each time So each share will be paid appoximately $ot of it's expected value, in each block it gets a reward,
but each share is also expected, on average, to be rewarded $t times in blocks found after the share is submitted to the pool.
i.e. if pool luck was always 100% then each share is expected to be rewarded $t times.

-If pool luck is better than 100%, then the average share reward wil be better than $t times.
+If pool luck is better than 100%, then the average share reward will be better than $t times.
If pool luck is lower than 100%, then the average share reward will be less than $t times.

What's a shift?

When your miner sends shares to the pool, the shares are not stored individually, but rather summarised into shifts.
-Shifts are ~50min or less in length, however, when we find any pool blocks the current shift ends early,
-at the point the block was found.
+Shifts are ~50min or less in length.
+Aproximately every 30s, the pool generates new work and sends that to all the miners.
+The pool also sends new work every time a block is found on the Bitcoin network.
+A shift summarises all the shares submitted to the pool for 100 work changes.
+However, when we find pool blocks, the current shift ends at the work in which the block was found.
A ckpool restart will also end the current shift and start a new one.

So, what's the $n value?

From 74436234baf0eb163d6c36bfee23aec82fd69072 Mon Sep 17 00:00:00 2001 From: kanoi Date: Mon, 27 Jul 2015 00:22:51 +1000 Subject: [PATCH 14/24] ckdb - db v1.0.1 new users and workers fields - basic support --- sql/ckdb.sql | 3 ++ sql/v1.0.0-v1.0.1.sql | 38 +++++++++++++++++++++ src/ckdb.h | 25 ++++++++++++-- src/ckdb_cmd.c | 4 +-- src/ckdb_data.c | 4 +-- src/ckdb_dbio.c | 77 ++++++++++++++++++++++++++++++++++--------- 6 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 sql/v1.0.0-v1.0.1.sql diff --git a/sql/ckdb.sql b/sql/ckdb.sql index a14896e9..5774ef4f 100644 --- a/sql/ckdb.sql +++ b/sql/ckdb.sql @@ -21,6 +21,8 @@ CREATE TABLE users ( passwordhash character varying(256) NOT NULL, secondaryuserid character varying(64) NOT NULL, salt character varying(256) DEFAULT ''::character varying NOT NULL, + userdata text DEFAULT ''::text NOT NULL, + userbits bigint NOT NULL, createdate timestamp with time zone NOT NULL, createby character varying(64) DEFAULT ''::character varying NOT NULL, createcode character varying(128) DEFAULT ''::character varying NOT NULL, @@ -57,6 +59,7 @@ CREATE TABLE workers ( difficultydefault integer DEFAULT 0 NOT NULL, -- 0 means default idlenotificationenabled char DEFAULT 'n'::character varying NOT NULL, idlenotificationtime integer DEFAULT 10 NOT NULL, + workerbits bigint NOT NULL, createdate timestamp with time zone NOT NULL, createby character varying(64) DEFAULT ''::character varying NOT NULL, createcode character varying(128) DEFAULT ''::character varying NOT NULL, diff --git a/sql/v1.0.0-v1.0.1.sql b/sql/v1.0.0-v1.0.1.sql new file mode 100644 index 00000000..1fa009a6 --- /dev/null +++ b/sql/v1.0.0-v1.0.1.sql @@ -0,0 +1,38 @@ +SET SESSION AUTHORIZATION 'postgres'; + +BEGIN transaction; + +DO $$ +DECLARE ver TEXT; +BEGIN + + UPDATE version set version='1.0.1' where vlock=1 and version='1.0.0'; + + IF found THEN + RETURN; + END IF; + + SELECT version into ver from version + WHERE vlock=1; + + RAISE EXCEPTION 'Wrong DB version - expect "1.0.0" - found "%"', ver; + +END $$; + +ALTER TABLE ONLY users + ADD COLUMN userdata text DEFAULT ''::text NOT NULL, + ADD COLUMN userbits bigint NOT NULL DEFAULT 0; + +ALTER TABLE ONLY users + ALTER COLUMN userbits DROP DEFAULT; + +-- match based on ckdb_data.c like_address() +UPDATE users set userbits=1 where username ~ '[13][A-HJ-NP-Za-km-z1-9]{15,}'; + +ALTER TABLE ONLY workers + ADD COLUMN workerbits bigint NOT NULL DEFAULT 0; + +ALTER TABLE ONLY workers + ALTER COLUMN workerbits DROP DEFAULT; + +END transaction; diff --git a/src/ckdb.h b/src/ckdb.h index b3feaaa7..80b95f7b 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -54,7 +54,7 @@ */ #define DB_VLOCK "1" -#define DB_VERSION "1.0.0" +#define DB_VERSION "1.0.1" #define CKDB_VERSION DB_VERSION"-1.120" #define WHERE_FFL " - from %s %s() line %d" @@ -1017,6 +1017,9 @@ typedef struct users { char passwordhash[TXT_BIG+1]; char secondaryuserid[TXT_SML+1]; char salt[TXT_BIG+1]; + char *userdata; + int64_t databits; // non-DB field, Bitmask of userdata content + int64_t userbits; // Bitmask of user attributes HISTORYDATECONTROLFIELDS; } USERS; @@ -1031,6 +1034,19 @@ typedef struct users { #define SALTSIZHEX 32 #define SALTSIZBIN 16 +#define DATABITS_SEP ',' +#define DATABITS_SEP_STR "," + +// databits attributes +// These are generated at dbload time from userdata +// Google Auth 2FA +#define USER_GOOGLEAUTH_NAME "gauth" +#define USER_GOOGLEAUTH 0x1 + +// userbits attributes +// Address account, not a username account +#define USER_ADDRESS 0x1 + extern K_TREE *users_root; extern K_TREE *userid_root; extern K_LIST *users_free; @@ -1073,6 +1089,7 @@ typedef struct workers { int32_t difficultydefault; char idlenotificationenabled[TXT_FLAG+1]; int32_t idlenotificationtime; + int64_t workerbits; // Bitmask of worker attributes HISTORYDATECONTROLFIELDS; } WORKERS; @@ -1086,6 +1103,8 @@ extern K_TREE *workers_root; extern K_LIST *workers_free; extern K_STORE *workers_store; +// Currently no workerbits attributes + #define DIFFICULTYDEFAULT_MIN 10 #define DIFFICULTYDEFAULT_MAX 0x7fffffff // 0 means it's not set @@ -2299,8 +2318,8 @@ extern bool users_update(PGconn *conn, K_ITEM *u_item, char *oldhash, char *newhash, char *email, char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root, char *status); extern K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, - char *passwordhash, char *by, char *code, char *inet, - tv_t *cd, K_TREE *trf_root); + char *passwordhash, int64_t userbits, char *by, + char *code, char *inet, tv_t *cd, K_TREE *trf_root); extern bool users_fill(PGconn *conn); extern bool useratts_item_add(PGconn *conn, K_ITEM *ua_item, tv_t *cd, bool begun); extern K_ITEM *useratts_add(PGconn *conn, char *username, char *attname, diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index c7b4565a..7bf914d3 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -67,7 +67,7 @@ static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by, u_item = users_add(conn, transfer_data(i_username), transfer_data(i_emailaddress), - transfer_data(i_passwordhash), + transfer_data(i_passwordhash), 0, by, code, inet, now, trf_root); } @@ -2476,7 +2476,7 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by, if (!u_item) { DATA_OPTIONCONTROL(optioncontrol, oc_item); u_item = users_add(conn, username, EMPTY, - optioncontrol->optionvalue, + optioncontrol->optionvalue, 0, by, code, inet, cd, trf_root); } } diff --git a/src/ckdb_data.c b/src/ckdb_data.c index cc5ca7b5..c3f596d1 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -2971,7 +2971,7 @@ double payout_stats(PAYOUTS *payouts, char *statname) pos += len+1; // They should only contain +ve numbers if (*pos && isdigit(*pos)) { - tab = strchr(pos, '\t'); + tab = strchr(pos, FLDSEP); if (!tab) numlen = strlen(pos); else @@ -2984,7 +2984,7 @@ double payout_stats(PAYOUTS *payouts, char *statname) } break; } - pos = strchr(pos, '\t'); + pos = strchr(pos, FLDSEP); if (pos) pos++; } diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index a0ea1bc5..775583ed 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -527,8 +527,8 @@ unparam: } K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, - char *passwordhash, char *by, char *code, char *inet, - tv_t *cd, K_TREE *trf_root) + char *passwordhash, int64_t userbits, char *by, + char *code, char *inet, tv_t *cd, K_TREE *trf_root) { ExecStatusType rescode; bool conned = false; @@ -540,7 +540,7 @@ K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, uint64_t hash; __maybe_unused uint64_t tmp; bool dup, ok = false; - char *params[8 + HISTORYDATECOUNT]; + char *params[10 + HISTORYDATECOUNT]; int n, par = 0; LOGDEBUG("%s(): add", __func__); @@ -592,6 +592,9 @@ K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, row->passwordhash, sizeof(row->passwordhash)); } + row->userdata = EMPTY; + row->userbits = userbits; + HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATETRANSFER(trf_root, row); @@ -608,13 +611,15 @@ K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress, params[par++] = str_to_buf(row->passwordhash, NULL, 0); params[par++] = str_to_buf(row->secondaryuserid, NULL, 0); params[par++] = str_to_buf(row->salt, NULL, 0); + params[par++] = str_to_buf(row->userdata, NULL, 0); + params[par++] = bigint_to_buf(row->userbits, NULL, 0); HISTORYDATEPARAMS(params, par, row); PARCHK(par, params); ins = "insert into users " "(userid,username,status,emailaddress,joineddate,passwordhash," - "secondaryuserid,salt" - HISTORYDATECONTROL ") values (" PQPARAM13 ")"; + "secondaryuserid,salt,userdata,userbits" + HISTORYDATECONTROL ") values (" PQPARAM15 ")"; if (!conn) { conn = dbconnect(); @@ -652,6 +657,26 @@ unitem: return NULL; } +static void users_checkfor(USERS *row, char *name, int64_t bits) +{ + char *ptr; + + ptr = strstr(row->userdata, name); + if (ptr) { + size_t len = strlen(name); + if ((ptr == row->userdata || *(ptr-1) == DATABITS_SEP) && + *(ptr+len) == '=') { + row->databits |= bits; + } + } +} + +static void users_databits(USERS *row) +{ + if (row->userdata && *(row->userdata)) + users_checkfor(row, USER_GOOGLEAUTH_NAME, USER_GOOGLEAUTH); +} + bool users_fill(PGconn *conn) { ExecStatusType rescode; @@ -661,14 +686,14 @@ bool users_fill(PGconn *conn) USERS *row; char *field; char *sel; - int fields = 8; + int fields = 10; bool ok; LOGDEBUG("%s(): select", __func__); sel = "select " "userid,username,status,emailaddress,joineddate," - "passwordhash,secondaryuserid,salt" + "passwordhash,secondaryuserid,salt,userdata,userbits" HISTORYDATECONTROL " from users"; res = PQexec(conn, sel, CKPQ_READ); @@ -741,6 +766,18 @@ bool users_fill(PGconn *conn) break; TXT_TO_STR("salt", field, row->salt); + PQ_GET_FLD(res, i, "userdata", field, ok); + if (!ok) + break; + TXT_TO_PTR("userdata", field, row->userdata); + LIST_MEM_ADD(users_free, row->userdata); + users_databits(row); + + PQ_GET_FLD(res, i, "userbits", field, ok); + if (!ok) + break; + TXT_TO_BIGINT("userbits", field, row->userbits); + HISTORYDATEFLDS(res, i, row, ok); if (!ok) break; @@ -1159,7 +1196,7 @@ K_ITEM *workers_add(PGconn *conn, int64_t userid, char *workername, K_ITEM *item, *ret = NULL; WORKERS *row; char *ins; - char *params[6 + HISTORYDATECOUNT]; + char *params[7 + HISTORYDATECOUNT]; int n, par = 0; int32_t diffdef; int32_t nottime; @@ -1222,6 +1259,8 @@ K_ITEM *workers_add(PGconn *conn, int64_t userid, char *workername, if (row->idlenotificationtime == IDLENOTIFICATIONTIME_DEF) row->idlenotificationenabled[0] = IDLENOTIFICATIONDISABLED[0]; + row->workerbits = 0; + HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATETRANSFER(trf_root, row); @@ -1232,13 +1271,14 @@ K_ITEM *workers_add(PGconn *conn, int64_t userid, char *workername, params[par++] = int_to_buf(row->difficultydefault, NULL, 0); params[par++] = str_to_buf(row->idlenotificationenabled, NULL, 0); params[par++] = int_to_buf(row->idlenotificationtime, NULL, 0); + params[par++] = bigint_to_buf(row->workerbits, NULL, 0); HISTORYDATEPARAMS(params, par, row); PARCHK(par, params); ins = "insert into workers " "(workerid,userid,workername,difficultydefault," - "idlenotificationenabled,idlenotificationtime" - HISTORYDATECONTROL ") values (" PQPARAM11 ")"; + "idlenotificationenabled,idlenotificationtime,workerbits" + HISTORYDATECONTROL ") values (" PQPARAM12 ")"; res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); rescode = PQresultStatus(res); @@ -1371,8 +1411,8 @@ bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault, ins = "insert into workers " "(workerid,userid,workername,difficultydefault," - "idlenotificationenabled,idlenotificationtime" - HISTORYDATECONTROL ") values (" PQPARAM11 ")"; + "idlenotificationenabled,idlenotificationtime,workerbits" + HISTORYDATECONTROL ") values (" PQPARAM12 ")"; par = 0; params[par++] = bigint_to_buf(row->workerid, NULL, 0); @@ -1381,6 +1421,7 @@ bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault, params[par++] = int_to_buf(row->difficultydefault, NULL, 0); params[par++] = str_to_buf(row->idlenotificationenabled, NULL, 0); params[par++] = int_to_buf(row->idlenotificationtime, NULL, 0); + params[par++] = bigint_to_buf(row->workerbits, NULL, 0); HISTORYDATEPARAMS(params, par, row); PARCHK(par, params); @@ -1418,14 +1459,14 @@ bool workers_fill(PGconn *conn) WORKERS *row; char *field; char *sel; - int fields = 6; + int fields = 7; bool ok; LOGDEBUG("%s(): select", __func__); sel = "select " "userid,workername,difficultydefault," - "idlenotificationenabled,idlenotificationtime" + "idlenotificationenabled,idlenotificationtime,workerbits" HISTORYDATECONTROL ",workerid from workers"; res = PQexec(conn, sel, CKPQ_READ); @@ -1483,6 +1524,11 @@ bool workers_fill(PGconn *conn) break; TXT_TO_INT("idlenotificationtime", field, row->idlenotificationtime); + PQ_GET_FLD(res, i, "workerbits", field, ok); + if (!ok) + break; + TXT_TO_BIGINT("workerbits", field, row->workerbits); + HISTORYDATEFLDS(res, i, row, ok); if (!ok) break; @@ -5495,7 +5541,8 @@ bool auths_add(PGconn *conn, char *poolinstance, char *username, if (!u_item) { if (addressuser) { u_item = users_add(conn, username, EMPTY, EMPTY, - by, code, inet, cd, trf_root); + USER_ADDRESS, by, code, inet, cd, + trf_root); } else { LOGDEBUG("%s(): unknown user '%s'", __func__, From 73cab3e57786b9cc12ba721c2b4ef749bc503596 Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 29 Jul 2015 15:24:49 +1000 Subject: [PATCH 15/24] php - add to reg: username can't be a BTC address --- pool/page_reg.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pool/page_reg.php b/pool/page_reg.php index 05021106..b27f7a69 100644 --- a/pool/page_reg.php +++ b/pool/page_reg.php @@ -34,8 +34,8 @@ function doregres($data, $u)  
* - All fields are required -
". passrequires() . " + All fields are required
Your Username can't be a BTC address +
". passrequires() . " "; From 44f7141fe8f37f85a13533b48f2cf753c10abf4d Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 29 Jul 2015 20:16:52 +1000 Subject: [PATCH 16/24] php - 2fa password input (but not yet available) --- pool/base.php | 12 +++++++----- pool/db.php | 31 ++++++++++++++++--------------- pool/page.php | 15 ++++----------- pool/page_reg.php | 40 +++++++++++++++++++++++++++++++--------- pool/page_reset.php | 7 +++++-- pool/page_settings.php | 16 +++++++++++----- pool/prime.php | 2 +- 7 files changed, 75 insertions(+), 48 deletions(-) diff --git a/pool/base.php b/pool/base.php index 496ded31..e388a538 100644 --- a/pool/base.php +++ b/pool/base.php @@ -323,12 +323,12 @@ session_start(); # include_once('db.php'); # -function validUserPass($user, $pass) +function validUserPass($user, $pass, $twofa) { - $rep = checkPass($user, $pass); + $rep = checkPass($user, $pass, $twofa); if ($rep != null) $ans = repDecode($rep); - usleep(100000); // Max 10x per second + usleep(500000); // Max twice per second if ($rep != null && $ans['STATUS'] == 'ok') { $key = 'ckp'.rand(1000000,9999999); @@ -352,7 +352,7 @@ function logout() } } # -function requestRegister() +function requestLoginRegReset() { $reg = getparam('Register', true); $reg2 = getparam('Reset', false); @@ -397,7 +397,9 @@ function tryLogInOut() return; } - $valid = validUserPass($user, $pass); + $twofa = getparam('2fa', false); + + $valid = validUserPass($user, $pass, $twofa); if (!$valid) $loginfailed = true; } diff --git a/pool/db.php b/pool/db.php index 39e9f577..7d87beee 100644 --- a/pool/db.php +++ b/pool/db.php @@ -166,23 +166,18 @@ function homeInfo($user) if ($rep === false) $ans = false; else - { $ans = repDecode($rep); -// if ($ans['lastblock'] == '?') -// { -// $ans['lastblock'] = 1401237522; -// $ans['lastblock'] = 1403819191; -// $ans['lastblock'] = 1407113822; -// } - } return $ans; } # -function checkPass($user, $pass) +function checkPass($user, $pass, $twofa) { $passhash = myhash($pass); - $flds = array('username' => $user, 'passwordhash' => $passhash); + if ($twofa === null) + $twofa = ''; + $flds = array('username' => $user, 'passwordhash' => $passhash, + '2fa' => $twofa); $msg = msgEncode('chkpass', 'chkpass', $flds, $user); $rep = sendsockreply('checkPass', $msg); if (!$rep) @@ -190,11 +185,14 @@ function checkPass($user, $pass) return $rep; } # -function setPass($user, $oldpass, $newpass) +function setPass($user, $oldpass, $newpass, $twofa) { $oldhash = myhash($oldpass); $newhash = myhash($newpass); - $flds = array('username' => $user, 'oldhash' => $oldhash, 'newhash' => $newhash); + if ($twofa === null) + $twofa = ''; + $flds = array('username' => $user, 'oldhash' => $oldhash, + 'newhash' => $newhash, '2fa' => $twofa); $msg = msgEncode('newpass', 'newpass', $flds, $user); $rep = sendsockreply('setPass', $msg); if (!$rep) @@ -202,10 +200,12 @@ function setPass($user, $oldpass, $newpass) return repDecode($rep); } # -function resetPass($user, $newpass) +function resetPass($user, $newpass, $twofa) { $newhash = myhash($newpass); - $flds = array('username' => $user, 'newhash' => $newhash); + if ($twofa === null) + $twofa = ''; + $flds = array('username' => $user, 'newhash' => $newhash, '2fa' => $twofa); $msg = msgEncode('newpass', 'newpass', $flds, $user); $rep = sendsockreply('resetPass', $msg); if (!$rep) @@ -216,7 +216,8 @@ function resetPass($user, $newpass) function userReg($user, $email, $pass) { $passhash = myhash($pass); - $flds = array('username' => $user, 'emailaddress' => $email, 'passwordhash' => $passhash); + $flds = array('username' => $user, 'emailaddress' => $email, + 'passwordhash' => $passhash); $msg = msgEncode('adduser', 'reg', $flds, $user); $rep = sendsockreply('userReg', $msg); if (!$rep) diff --git a/pool/page.php b/pool/page.php index 58edbc07..3b9780ad 100644 --- a/pool/page.php +++ b/pool/page.php @@ -409,17 +409,10 @@ function pgtop($info, $dotop, $user, $douser) list($who, $whoid) = validate(); if ($who == false) { - $top .= makeForm('')." -
- - - - -
User:
Pass:
- - -
 
  
-
"; + $top .= ' - + - + - +If you enter the details correctly,
+an Email will be sent to you to let you reset your password
'; + $top .= '

"; + $pg .= makeForm(''); + $pg .= " + + + + + + + + + + +
Username:
Password:
*2nd Authentication:
* + Leave blank if you haven't enabled it
 
+"; + + $pg.= '
'; $pg .= '

Register

'; if (isset($data['data']['error'])) @@ -28,9 +51,9 @@ function doregres($data, $u)
Email:
Password:
Retype Password:
 

* @@ -51,10 +74,9 @@ function doregres($data, $u)
 

* - All fields are required

-An Email will be sent to you, to let you reset your password
"; @@ -184,9 +206,6 @@ function try_reset($info, $page, $menu, $name, $u) $user = getparam('user', false); $mail = trim(getparam('mail', false)); - // Slow this right down - usleep(500000); - $data = array(); if (!nuem($user)) @@ -208,6 +227,9 @@ function try_reset($info, $page, $menu, $name, $u) # function show_reg($info, $page, $menu, $name, $u) { + // Slow this right down + usleep(1000000); + $reg = getparam('Register', false); if ($reg !== NULL) try_reg($info, $page, $menu, $name, $u); diff --git a/pool/page_reset.php b/pool/page_reset.php index 57be33fc..1b636194 100644 --- a/pool/page_reset.php +++ b/pool/page_reset.php @@ -20,10 +20,12 @@ function allow_reset($error) Retype Password: +*2nd Authentication: + +
* + Leave blank if you haven't enabled it   -
* - All fields are required "; @@ -61,6 +63,7 @@ function dbreset() $pass = getparam('pass', true); $pass2 = getparam('pass2', true); + $twofa = getparam('2fa', true); if (nuem($pass) || nuem($pass2)) return allow_reset('Enter both passwords'); diff --git a/pool/page_settings.php b/pool/page_settings.php index aa06ebcf..91818c18 100644 --- a/pool/page_settings.php +++ b/pool/page_settings.php @@ -83,6 +83,14 @@ function settings($data, $user, $email, $addr, $err) $pg .= ''; $pg .= ''; $pg .= ''; + $pg .= ''; + $pg .= '*2nd Authentication:'; + $pg .= ''; + $pg .= ''; + $pg .= ''; + $pg .= ''; + $pg .= "*Leave blank if you haven't enabled it"; + $pg .= '' $pg .= ''; $pg .= 'Change: '; $pg .= ''; @@ -123,16 +131,14 @@ function dosettings($data, $user) $oldpass = getparam('oldpass', false); $pass1 = getparam('pass1', false); $pass2 = getparam('pass2', false); + $twofa = getparam('2fa', false); if (!safepass($pass1)) - { - $err = "Password is unsafe - requires 6 or more characters, including
" . - "at least one of each uppercase, lowercase and digits, but not Tab"; - } + $err = 'Unsafe password. ' . passrequires(); elseif ($pass1 != $pass2) $err = "Passwords don't match"; else { - $ans = setPass($user, $oldpass, $pass1); + $ans = setPass($user, $oldpass, $pass1, $twofa); $err = 'Password changed'; $check = true; } diff --git a/pool/prime.php b/pool/prime.php index 0aafe808..3db83a6f 100644 --- a/pool/prime.php +++ b/pool/prime.php @@ -105,7 +105,7 @@ function check() showPage(NULL, 'reset', $dmenu, '', $who); else { - if (requestRegister() == true) + if (requestLoginRegReset() == true) showPage(NULL, 'reg', $dmenu, '', $who); else { From 4af09a4851384c2afae2db409b26e2ff18b13060 Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 29 Jul 2015 21:17:27 +1000 Subject: [PATCH 17/24] php - add 2fa to settings --- pool/db.php | 7 ++++++- pool/page_addrmgt.php | 24 ++++++++++++++++++------ pool/page_settings.php | 16 +++++++++++++--- 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/pool/db.php b/pool/db.php index 7d87beee..edccad1d 100644 --- a/pool/db.php +++ b/pool/db.php @@ -225,7 +225,7 @@ function userReg($user, $email, $pass) return repDecode($rep); } # -function userSettings($user, $email = null, $addr = null, $pass = null) +function userSettings($user, $email = null, $addr = null, $pass = null, $twofa = null) { $tmo = false; $flds = array('username' => $user); @@ -247,7 +247,12 @@ function userSettings($user, $email = null, $addr = null, $pass = null) $tmo = 3; # 3x the timeout } if ($pass != null) + { $flds['passwordhash'] = myhash($pass); + if ($twofa === null) + $twofa = ''; + $flds['2fa'] = $twofa; + } $msg = msgEncode('usersettings', 'userset', $flds, $user); $rep = sendsockreply('userSettings', $msg, $tmo); if (!$rep) diff --git a/pool/page_addrmgt.php b/pool/page_addrmgt.php index 0ef12d85..33b3e21f 100644 --- a/pool/page_addrmgt.php +++ b/pool/page_addrmgt.php @@ -72,13 +72,24 @@ function addrmgtuser($data, $user, $err) else $row = 'odd'; $pg .= ""; - $pg .= ''; + $pg .= ''; $pg .= 'Password: '; - $pg .= ' '; + $pg .= ' '; + + if ((($offset++) % 2) == 0) + $row = 'even'; + else + $row = 'odd'; + $pg .= ""; + $pg .= ''; + $pg .= '*2nd Authentication: '; + $pg .= ''; + + $pg .= ""; + $pg .= 'You must enter your password to save changes
'; + $pg .= "*Leave blank if you haven't enabled it
"; + $pg .= 'A ratio of 0, will remove the address from the payouts
'; } - $pg .= '*'; - $pg .= ' You must enter your password to save changes
'; - $pg .= 'A ratio of 0, will remove the address from the payouts
'; $pg .= "\n"; $pg .= "