From 951f9019a9192808dd60ab28f55274ce96bb8c7e Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 11 Mar 2015 18:38:32 +1100 Subject: [PATCH 1/7] ckdb/php - more block statistics --- configure.ac | 7 ++- pool/page_blocks.php | 112 +++++++++++++++++++---------------- src/Makefile.am | 2 +- src/ckdb.c | 2 + src/ckdb.h | 29 ++++++++- src/ckdb_cmd.c | 136 +++++++++++++++++++++++++++++++++++-------- src/ckdb_data.c | 108 ++++++++++++++++++++++++++++++++++ src/ckdb_dbio.c | 12 +++- 8 files changed, 327 insertions(+), 81 deletions(-) diff --git a/configure.ac b/configure.ac index 49d28ee2..d55e77b6 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AC_CHECK_HEADERS(alloca.h pthread.h stdio.h math.h signal.h sys/prctl.h) AC_CHECK_HEADERS(sys/types.h sys/socket.h sys/stat.h linux/un.h netdb.h) AC_CHECK_HEADERS(stdint.h netinet/in.h netinet/tcp.h sys/ioctl.h getopt.h) AC_CHECK_HEADERS(sys/epoll.h libpq-fe.h postgresql/libpq-fe.h grp.h) +AC_CHECK_HEADERS(gsl/gsl_math.h gsl/gsl_cdf.h) PTHREAD_LIBS="-lpthread" MATH_LIBS="-lm" @@ -59,8 +60,12 @@ AC_ARG_WITH([ckdb], if test "x$ckdb" != "xno"; then AC_CHECK_LIB([pq], [main],[PQ=-lpq],echo "Error: Required library libpq-dev not found. Install it or disable postgresql support with --without-ckdb" && exit 1) + AC_CHECK_LIB([gsl], [main],[GSL=-lgsl],echo "Error: Required library gsl-dev + not found. Install it or disable support with --without-ckdb" && exit 1) + AC_CHECK_LIB([gslcblas], [main],[GSLCBLAS=-lgslcblas],echo "Error: Required library gslcblas + not found. Install it or disable support with --without-ckdb" && exit 1) AC_DEFINE([USE_CKDB], [1], [Defined to 1 if ckdb support required]) - PQ_LIBS="-lpq" + PQ_LIBS="-lpq -lgsl -lgslcblas" else PQ_LIBS="" fi diff --git a/pool/page_blocks.php b/pool/page_blocks.php index d7b7d189..1556323c 100644 --- a/pool/page_blocks.php +++ b/pool/page_blocks.php @@ -56,6 +56,43 @@ function doblocks($data, $user) if ($wantcsv === false) { + if ($ans['STATUS'] == 'ok' and isset($ans['s_rows']) and $ans['s_rows'] > 0) + { + $pg .= '

Block Statistics

'; + $pg .= "\n"; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= "\n"; + + $count = $ans['s_rows']; + for ($i = 0; $i < $count; $i++) + { + if (($i % 2) == 0) + $row = 'even'; + else + $row = 'odd'; + + $desc = $ans['s_desc:'.$i]; + $diff = number_format(100 * $ans['s_diffratio:'.$i], 2); + $mean = number_format(100 * $ans['s_diffmean:'.$i], 2); + $cdferl = number_format($ans['s_cdferl:'.$i], 4); + $luck = number_format(100 * $ans['s_luck:'.$i], 2); + + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= ""; + $pg .= "\n"; + } + $pg .= "
DescriptionDiff%Mean%CDF[Erl]Luck%
$desc Blocks$diff%$mean%$cdferl$luck%
\n"; + } + if ($ans['STATUS'] == 'ok') { $count = $ans['rows']; @@ -70,15 +107,15 @@ function doblocks($data, $user) $s = 's'; } - $pg = "

Last$num Block$s

"; + $pg .= "

Last$num Block$s

"; } else - $pg = '

Blocks

'; + $pg .= '

Blocks

'; list($fg, $bg) = pctcolour(25.0); $pg .= ""; $pg .= " Green  "; - $pg .= 'is good luck. Lower Diff% and brighter green is best luck.
'; + $pg .= 'is good luck. Lower Diff% and brighter green is better luck.
'; list($fg, $bg) = pctcolour(100.0); $pg .= ""; $pg .= " 100%  "; @@ -94,7 +131,7 @@ function doblocks($data, $user) $pg .= "Height"; if ($user !== null) $pg .= "Who"; - $pg .= "Reward"; + $pg .= "Block Reward"; $pg .= "When"; $pg .= "Status"; $pg .= "Diff"; @@ -109,7 +146,6 @@ function doblocks($data, $user) $csv = "Sequence,Height,Status,Timestamp,DiffAcc,NetDiff,Hash\n"; if ($ans['STATUS'] == 'ok') { - $tot = $ans['tot']; $count = $ans['rows']; for ($i = 0; $i < $count; $i++) { @@ -130,7 +166,7 @@ function doblocks($data, $user) $seq = ''; } else - $seq = $tot--; + $seq = $ans['seq:'.$i]; if ($stat == '1-Confirm') { if (isset($data['info']['lastheight'])) @@ -143,37 +179,34 @@ function doblocks($data, $user) } $stara = ''; - $starp = ''; - if (isset($ans['status:'.($i+1)])) - if ($ans['status:'.($i+1)] == 'Orphan' - && $stat != 'Orphan') - { - $stara = '*'; - $starp = '*'; - } + if ($stat == 'Orphan') + $stara = '*'; $diffacc = $ans['diffacc:'.$i]; $acc = number_format($diffacc, 0); $netdiff = $ans['netdiff:'.$i]; - if ($netdiff > 0) + $diffratio = $ans['diffratio:'.$i]; + $cdf = $ans['cdf:'.$i]; + $luck = $ans['luck:'.$i]; + + if ($diffratio > 0) { - $pct = 100.0 * $diffacc / $netdiff; + $pct = 100.0 * $diffratio; list($fg, $bg) = pctcolour($pct); - $bpct = "$starp".number_format($pct, 2).'%'; + $bpct = "".number_format($pct, 2).'%'; $bg = " bgcolor=$bg"; $blktot += $diffacc; if ($stat != 'Orphan') $nettot += $netdiff; - $cdfv = 1 - exp(-1 * $diffacc / $netdiff); - $cdf = number_format($cdfv, 2); + $cdfdsp = number_format($cdf, 2); } else { $bg = ''; $bpct = '?'; - $cdf = '?'; + $cdfdsp = '?'; } if ($wantcsv === false) @@ -188,7 +221,7 @@ function doblocks($data, $user) $pg .= "".$stat.''; $pg .= "$stara$acc"; $pg .= "$bpct"; - $pg .= "$cdf"; + $pg .= "$cdfdsp"; $pg .= "\n"; } else @@ -208,39 +241,16 @@ function doblocks($data, $user) echo $csv; exit(0); } - if ($nettot > 0) + if ($orph === true) { - if (($i % 2) == 0) - $row = 'even'; - else - $row = 'odd'; - - $pct = 100.0 * $blktot / $nettot; - list($fg, $bg) = pctcolour($pct); - $bpct = "".number_format($pct, 2).'%'; - $bg = " bgcolor=$bg"; - - $pg .= ""; - $pg .= 'Total:'; - $pg .= ''; - $pg .= "\n"; - if ($orph === true) - { - $pg .= ' #endif +#include +#include + #include "ckpool.h" #include "libckpool.h" @@ -52,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.0" -#define CKDB_VERSION DB_VERSION"-1.012" +#define CKDB_VERSION DB_VERSION"-1.020" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -192,6 +195,11 @@ extern POOLSTATUS pool; _dstoff += _srclen; \ } while(0) +#define APPEND_REALLOC_RESET(_buf, _off) do { \ + (_buf)[0] = '\0'; \ + _off = 0; \ + } while(0) + enum data_type { TYPE_STR, TYPE_BIGINT, @@ -1095,6 +1103,22 @@ typedef struct blocks { char statsconfirmed[TXT_FLAG+1]; HISTORYDATECONTROLFIELDS; bool ignore; // Non DB field + + // Calculated only when = 0 + double netdiff; + + /* Non DB fields for the web page + * Calculate them once off/recalc them when required */ + double blockdiffratio; + double blockcdf; + double blockluck; + + /* From the last found block to this one + * Orphans have these set to zero */ + double diffratio; + double diffmean; + double cdferl; + double luck; } BLOCKS; #define ALLOC_BLOCKS 100 @@ -1134,6 +1158,8 @@ extern const char *blocks_unknown; extern K_TREE *blocks_root; extern K_LIST *blocks_free; extern K_STORE *blocks_store; +extern tv_t blocks_stats_time; +extern bool blocks_stats_rebuild; // MININGPAYOUTS typedef struct miningpayouts { @@ -1750,6 +1776,7 @@ extern K_ITEM *find_prev_blocks(int32_t height); extern const char *blocks_confirmed(char *confirmed); extern void zero_on_new_block(); extern void set_block_share_counters(); +extern bool check_update_blocks_stats(tv_t *stats); extern cmp_t cmp_miningpayouts(K_ITEM *a, K_ITEM *b); extern K_ITEM *find_miningpayouts(int64_t payoutid, int64_t userid); extern K_ITEM *first_miningpayouts(int64_t payoutid, K_TREE_CTX *ctx); diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 303be5cd..411507e6 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -811,23 +811,30 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id, __maybe_unused K_TREE *trf_root) { K_TREE_CTX ctx[1]; - K_ITEM *b_item, *w_item; + K_ITEM *b_item; BLOCKS *blocks; char reply[1024] = ""; char tmp[1024]; - char *buf; + char *buf, *desc, desc_buf[64]; size_t len, off; int32_t height = -1; - tv_t first_cd = {0,0}; - int rows, tot; + tv_t first_cd = {0,0}, stats_tv = {0,0}, stats_tv2 = {0,0}; + int rows, srows, tot, seq; + bool has_stats; LOGDEBUG("%s(): cmd '%s'", __func__, cmd); APPEND_REALLOC_INIT(buf, off, len); APPEND_REALLOC(buf, off, len, "ok."); - rows = 0; + +redo: + K_WLOCK(blocks_free); + has_stats = check_update_blocks_stats(&stats_tv); + K_WUNLOCK(blocks_free); + + srows = rows = 0; K_RLOCK(blocks_free); - b_item = last_in_ktree(blocks_root, ctx); + b_item = first_in_ktree(blocks_root, ctx); tot = 0; while (b_item) { DATA_BLOCKS(blocks, b_item); @@ -835,16 +842,31 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id, if (blocks->confirmed[0] != BLOCKS_ORPHAN) tot++; } - b_item = prev_in_ktree(ctx); + b_item = next_in_ktree(ctx); } + seq = tot; b_item = last_in_ktree(blocks_root, ctx); while (b_item && rows < 42) { DATA_BLOCKS(blocks, b_item); + /* For each block remember the initial createdate + * Reverse sort order the oldest expirydate is first + * which should be the 'n' record */ if (height != blocks->height) { height = blocks->height; copy_tv(&first_cd, &(blocks->createdate)); } if (CURRENT(&(blocks->expirydate))) { + if (blocks->confirmed[0] == BLOCKS_ORPHAN) { + snprintf(tmp, sizeof(tmp), + "seq:%d=o%c", + rows, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + } else { + snprintf(tmp, sizeof(tmp), + "seq:%d=%d%c", + rows, seq--, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + } int_to_buf(blocks->height, reply, sizeof(reply)); snprintf(tmp, sizeof(tmp), "height:%d=%s%c", rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); @@ -900,21 +922,21 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id, snprintf(tmp, sizeof(tmp), "elapsed:%d=%s%c", rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); - w_item = find_workinfo(blocks->workinfoid, NULL); - if (w_item) { - char wdiffbin[TXT_SML+1]; - double wdiff; - WORKINFO *workinfo; - DATA_WORKINFO(workinfo, w_item); - hex2bin(wdiffbin, workinfo->bits, 4); - wdiff = diff_from_nbits(wdiffbin); - snprintf(tmp, sizeof(tmp), - "netdiff:%d=%.1f%c", - rows, wdiff, FLDSEP); - APPEND_REALLOC(buf, off, len, tmp); + if (has_stats) { + snprintf(tmp, sizeof(tmp), + "netdiff:%d=%.8f%cdiffratio:%d=%.8f%c" + "cdf:%d=%.8f%cluck:%d=%.8f%c", + rows, blocks->netdiff, FLDSEP, + rows, blocks->blockdiffratio, FLDSEP, + rows, blocks->blockcdf, FLDSEP, + rows, blocks->blockluck, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); } else { snprintf(tmp, sizeof(tmp), - "netdiff:%d=?%c", rows, FLDSEP); + "netdiff:%d=?%cdiffratio:%d=?%c" + "cdf:%d=?%cluck:%d=?%c", + rows, FLDSEP, rows, FLDSEP, + rows, FLDSEP, rows, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); } @@ -922,17 +944,81 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id, } b_item = prev_in_ktree(ctx); } + if (has_stats) { + seq = tot; + b_item = last_in_ktree(blocks_root, ctx); + while (b_item) { + DATA_BLOCKS(blocks, b_item); + if (CURRENT(&(blocks->expirydate)) && + blocks->confirmed[0] != BLOCKS_ORPHAN) { + desc = NULL; + if (seq == 1) { + snprintf(desc_buf, sizeof(desc_buf), + "All - Last %d", tot); + desc = desc_buf; + } else if (seq == tot - 4) { + desc = "Last 5"; + } else if (seq == tot - 9) { + desc = "Last 10"; + } else if (seq == tot - 19) { + desc = "Last 20"; + } else if (seq == tot - 41) { + desc = "Last 42"; + } + if (desc) { + snprintf(tmp, sizeof(tmp), + "s_seq:%d=%d%c" + "s_desc:%d=%s%c" + "s_diffratio:%d=%.8f%c" + "s_diffmean:%d=%.8f%c" + "s_cdferl:%d=%.8f%c" + "s_luck:%d=%.8f%c", + srows, seq, FLDSEP, + srows, desc, FLDSEP, + srows, blocks->diffratio, FLDSEP, + srows, blocks->diffmean, FLDSEP, + srows, blocks->cdferl, FLDSEP, + srows, blocks->luck, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + srows++; + } + seq--; + } + b_item = prev_in_ktree(ctx); + } + copy_tv(&stats_tv2, &blocks_stats_time); + } K_RUNLOCK(blocks_free); + + // Only check for a redo if we used the stats values + if (has_stats) { + /* If the stats changed then redo with the new corrected values + * This isn't likely at all, but it guarantees the blocks + * page shows correct information since any code that wants + * to modify the blocks table must have it under write lock + * then flag the stats as needing to be recalculated */ + if (!tv_equal(&stats_tv, &stats_tv2)) { + APPEND_REALLOC_RESET(buf, off); + goto redo; + } + } + + snprintf(tmp, sizeof(tmp), + "s_rows=%d%cs_flds=%s%c", + srows, FLDSEP, + "s_seq,s_desc,s_diffratio,s_diffmean,s_cdferl,s_luck", + FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), - "tot=%d%crows=%d%cflds=%s%c", - tot, FLDSEP, + "rows=%d%cflds=%s%c", rows, FLDSEP, - "height,blockhash,nonce,reward,workername,firstcreatedate," + "seq,height,blockhash,nonce,reward,workername,firstcreatedate," "createdate,status,diffacc,diffinv,shareacc,shareinv,elapsed," - "netdiff", FLDSEP); + "netdiff,diffratio,cdf,luck", FLDSEP); APPEND_REALLOC(buf, off, len, tmp); - snprintf(tmp, sizeof(tmp), "arn=%s%carp=%s", "Blocks", FLDSEP, ""); + snprintf(tmp, sizeof(tmp), "arn=%s%carp=%s", "Blocks,BlockStats", FLDSEP, ",s"); APPEND_REALLOC(buf, off, len, tmp); LOGDEBUG("%s.ok.%d_blocks", id, rows); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 3878f342..5d9907f6 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -2399,6 +2399,114 @@ void set_block_share_counters() LOGWARNING("%s(): Update block counters complete", __func__); } +/* Must be under K_WLOCK(blocks_free) when called + * Call this before using the block stats and again check (under lock) + * the blocks_stats_time didn't change after you finish processing + * If it has changed, redo the processing from scratch + * If return is false, then stats aren't available + * TODO: consider storing the partial calculations in the BLOCKS structure + * and only recalc from the last block modified (remembered) + * Will be useful with a large block history */ +bool check_update_blocks_stats(tv_t *stats) +{ + static int64_t last_missing_workinfoid = 0; + static tv_t last_message = { 0L, 0L }; + K_TREE_CTX ctx[1]; + K_ITEM *b_item, *w_item; + WORKINFO *workinfo; + BLOCKS *blocks; + char ndiffbin[TXT_SML+1]; + double ok, diffacc, netsumm, diffmean, pending; + tv_t now; + + /* Wait for startup_complete rather than db_load_complete + * This avoids doing a 'long' lock stats update while reloading */ + if (!startup_complete) + return false; + + if (blocks_stats_rebuild) { + ok = diffacc = netsumm = diffmean = pending = 0.0; + b_item = last_in_ktree(blocks_root, ctx); + while (b_item) { + DATA_BLOCKS(blocks, b_item); + if (CURRENT(&(blocks->expirydate))) { + if (blocks->netdiff == 0) { + // Deadlock alert + K_RLOCK(workinfo_free); + w_item = find_workinfo(blocks->workinfoid, NULL); + K_RUNLOCK(workinfo_free); + if (!w_item) { + setnow(&now); + if (!blocks->workinfoid != last_missing_workinfoid || + tvdiff(&now, &last_message) >= 5.0) { + LOGEMERG("%s(): missing block workinfoid %" + PRId32"/%"PRId64"/%s", + __func__, blocks->height, + blocks->workinfoid, + blocks->confirmed); + } + last_missing_workinfoid = blocks->workinfoid; + copy_tv(&last_message, &now); + return false; + } + DATA_WORKINFO(workinfo, w_item); + hex2bin(ndiffbin, workinfo->bits, 4); + blocks->netdiff = diff_from_nbits(ndiffbin); + } + pending += blocks->diffacc; + + /* Stats for each blocks are independent of + * if they are orphans or not */ + if (blocks->netdiff == 0.0) + blocks->blockdiffratio = 0.0; + else + blocks->blockdiffratio = blocks->diffacc / blocks->netdiff; + blocks->blockcdf = 1.0 - exp(-1.0 * blocks->blockdiffratio); + if (blocks->blockdiffratio == 0.0) + blocks->blockluck = 0.0; + else + blocks->blockluck = 1.0 / blocks->blockdiffratio; + + /* Orphans are treated as +diffacc but no block + * i.e. they simply add shares to the later block + * and have running stats set to zero */ + if (blocks->confirmed[0] == BLOCKS_ORPHAN) { + blocks->diffratio = 0.0; + blocks->diffmean = 0.0; + blocks->cdferl = 0.0; + blocks->luck = 0.0; + } else { + ok++; + diffacc += pending; + pending = 0.0; + netsumm += blocks->netdiff; + + if (netsumm == 0.0) + blocks->diffratio = 0.0; + else + blocks->diffratio = diffacc / netsumm; + + diffmean = (diffmean * (ok - 1) + blocks->blockdiffratio) / ok; + blocks->diffmean = diffmean; + + if (diffmean == 0.0) { + blocks->cdferl = 0.0; + blocks->luck = 0.0; + } else { + blocks->cdferl = gsl_cdf_gamma_P(diffmean, ok, 1.0 / ok); + blocks->luck = 1.0 / diffmean; + } + } + } + b_item = prev_in_ktree(ctx); + } + setnow(&blocks_stats_time); + blocks_stats_rebuild = false; + } + copy_tv(stats, &blocks_stats_time); + return true; +} + /* order by payoutid asc,userid asc,expirydate asc * i.e. only one payout amount per block per user */ cmp_t cmp_miningpayouts(K_ITEM *a, K_ITEM *b) diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index 4db4f0ba..91e43fd8 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -3996,9 +3996,13 @@ unparam: blocks_root = remove_from_ktree(blocks_root, old_b_item, cmp_blocks); copy_tv(&(oldblocks->expirydate), cd); blocks_root = add_to_ktree(blocks_root, old_b_item, cmp_blocks); - } + // Copy it over to avoid having to recalculate it + row->netdiff = oldblocks->netdiff; + } else + row->netdiff = 0; blocks_root = add_to_ktree(blocks_root, b_item, cmp_blocks); k_add_head(blocks_store, b_item); + blocks_stats_rebuild = true; } K_WUNLOCK(blocks_free); @@ -4300,9 +4304,13 @@ flail: blocks_root = remove_from_ktree(blocks_root, old_b_item, cmp_blocks); copy_tv(&(oldblocks->expirydate), cd); blocks_root = add_to_ktree(blocks_root, old_b_item, cmp_blocks); - } + // Copy it over to avoid having to recalculate it + row->netdiff = oldblocks->netdiff; + } else + row->netdiff = 0; blocks_root = add_to_ktree(blocks_root, b_item, cmp_blocks); k_add_head(blocks_store, b_item); + blocks_stats_rebuild = true; } K_WUNLOCK(blocks_free); From deda01d7581d89e80bf37816d37b468cf3afcd36 Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 11 Mar 2015 20:44:58 +1100 Subject: [PATCH 2/7] ckdb - allow payouts to be orphaned --- src/ckdb.h | 6 ++++- src/ckdb_cmd.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/ckdb.h b/src/ckdb.h index 54074dfb..3e02c6e2 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.020" +#define CKDB_VERSION DB_VERSION"-1.021" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -1219,6 +1219,10 @@ extern cklock_t process_pplns_lock; #define PAYOUTS_PROCESSING 'P' #define PAYOUTS_PROCESSING_STR "P" #define PAYPROCESSING(_status) ((_status)[0] == PAYOUTS_PROCESSING) +// An orphaned payout must be ignored +#define PAYOUTS_ORPHAN 'O' +#define PAYOUTS_ORPHAN_STR "O" +#define PAYORPHAN(_status) ((_status)[0] == PAYOUTS_ORPHAN) /* // EVENTLOG diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 411507e6..43741df6 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -4272,6 +4272,70 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, copy_tv(&(payouts2->lastshareacc), &(payouts->lastshareacc)); payouts2->stats = strdup(payouts->stats); + ok = payouts_add(conn, true, p2_item, &old_p2_item, + by, code, inet, now, NULL, false); + if (!ok) { + snprintf(reply, siz, "failed payout %"PRId64, payoutid); + return strdup(reply); + } + DATA_PAYOUTS(payouts2, p2_item); + DATA_PAYOUTS(old_payouts2, old_p2_item); + snprintf(msg, sizeof(msg), + "payout %"PRId64" changed from '%s' to '%s' for" + "%"PRId32"/%s", + payoutid, old_payouts2->status, payouts2->status, + payouts2->height, payouts2->blockhash); + } else if (strcasecmp(action, "orphan") == 0) { + /* Change the status of a generated payout to orphaned + * Require payoutid + * Use this if the orphan process didn't automatically + * update a generated payout to orphaned + * TODO: get orphaned blocks to automatically do this */ + i_payoutid = require_name(trf_root, "payoutid", 1, + (char *)intpatt, reply, siz); + if (!i_payoutid) + return strdup(reply); + TXT_TO_BIGINT("payoutid", transfer_data(i_payoutid), payoutid); + + K_WLOCK(payouts_free); + p_item = find_payoutid(payoutid); + if (!p_item) { + K_WUNLOCK(payouts_free); + snprintf(reply, siz, + "no payout with id %"PRId64, payoutid); + return strdup(reply); + } + DATA_PAYOUTS(payouts, p_item); + if (!PAYGENERATED(payouts->status)) { + K_WUNLOCK(payouts_free); + snprintf(reply, siz, + "status !generated (%s) for payout %"PRId64, + payouts->status, payoutid); + return strdup(reply); + } + p2_item = k_unlink_head(payouts_free); + K_WUNLOCK(payouts_free); + + /* There is a risk of the p_item changing while it's unlocked, + * but since this is a manual interface it's not really likely + * and there'll be an error if something goes wrong + * It reports the old and new status */ + DATA_PAYOUTS(payouts2, p2_item); + bzero(payouts2, sizeof(*payouts2)); + payouts2->payoutid = payouts->payoutid; + payouts2->height = payouts->height; + STRNCPY(payouts2->blockhash, payouts->blockhash); + payouts2->minerreward = payouts->minerreward; + payouts2->workinfoidstart = payouts->workinfoidstart; + payouts2->workinfoidend = payouts->workinfoidend; + payouts2->elapsed = payouts->elapsed; + STRNCPY(payouts2->status, PAYOUTS_ORPHAN_STR); + payouts2->diffwanted = payouts->diffwanted; + payouts2->diffused = payouts->diffused; + payouts2->shareacc = payouts->shareacc; + copy_tv(&(payouts2->lastshareacc), &(payouts->lastshareacc)); + payouts2->stats = strdup(payouts->stats); + ok = payouts_add(conn, true, p2_item, &old_p2_item, by, code, inet, now, NULL, false); if (!ok) { From c754f1b06ddf831c6eb87563941f1ba87e981a28 Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 11 Mar 2015 21:48:08 +1100 Subject: [PATCH 3/7] ckdb/php - add block B marks after the shift php shift names --- html/BTCSym.png | Bin 0 -> 387 bytes pool/page_shifts.php | 18 ++++++++++++++++-- src/ckdb.h | 2 +- src/ckdb_cmd.c | 22 +++++++++++++++++++++- 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 html/BTCSym.png diff --git a/html/BTCSym.png b/html/BTCSym.png new file mode 100644 index 0000000000000000000000000000000000000000..7e2114c294e1f25a97eb325214c216ae88ae1d48 GIT binary patch literal 387 zcmV-}0et?6P)6dx00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-yl2LuZq>p2QX0003ZNklRz4u$a zZehQ;qG(7@N)U8&)1@fqMu%{Baj+>z9sLj5ghuyhb8w4j$RD6f@+49*3whU`@7~*R zdD0orf%7ZUL*kyhDv@(--5yz^-y`!DoqOwx2TD1_U|8_eElpQOoGSGj?%8G@+t6{T zlq(%r@zgUJiC|Fh-4ji}E&JxB=ML>^xCl}~X~$>NPP`YJG;2gGkp{O_2om&}Ghx;r zpHwP0!*zGKZ$XM5+V!qj@t@rC%4_S!tVtw_SS~`L0)_ZO literal 0 HcmV?d00001 diff --git a/pool/page_shifts.php b/pool/page_shifts.php index 1092482f..1230d380 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -28,8 +28,22 @@ function doshifts($data, $user) $row = 'odd'; $pg .= ""; - $shif = preg_replace(array('/^.* to /','/^.*fin: /'), '', $ans['shift:'.$i]); - $pg .= "$shif"; + $shifname = $ans['shift:'.$i]; + $shif = preg_replace(array('/^.* to /','/^.*fin: /'), '', $shifname); + $ablock = false; + if (preg_match('/to.*Block.* fin/', $shifname) === true) + $ablock = true; + else + { + $shifex = $ans['endmarkextra:'.$i]; + if (preg_match('/Block .* fin/', $shifex) === true) + $ablock = true; + } + if ($ablock === true) + $btc = ' '; + else + $btc = ''; + $pg .= "$shif$btc"; $start = $ans['start:'.$i]; $pg .= ''.utcd($start).''; $nd = $ans['end:'.$i]; diff --git a/src/ckdb.h b/src/ckdb.h index 3e02c6e2..e59f475a 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.021" +#define CKDB_VERSION DB_VERSION"-1.022" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 43741df6..b61c0595 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -4543,12 +4543,13 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, __maybe_unused tv_t *notcd, __maybe_unused K_TREE *trf_root) { - K_ITEM *i_username, *u_item, ms_look, *wm_item, *ms_item, *wi_item; + K_ITEM *i_username, *u_item, *m_item, ms_look, *wm_item, *ms_item, *wi_item; K_TREE_CTX wm_ctx[1], ms_ctx[1]; WORKMARKERS *wm; WORKINFO *wi; MARKERSUMMARY markersummary, *ms, ms_add; USERS *users; + MARKS *marks = NULL; char reply[1024] = ""; char tmp[1024]; size_t siz = sizeof(reply); @@ -4584,6 +4585,19 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, if (CURRENT(&(wm->expirydate)) && WMPROCESSED(wm->status)) { K_RUNLOCK(workmarkers_free); + K_RLOCK(marks_free); + m_item = find_marks(wm->workinfoidend); + K_RUNLOCK(marks_free); + DATA_MARKS_NULL(marks, m_item); + if (m_item == NULL) { + // Log it but keep going + LOGERR("%s() missing mark for markerid " + "%"PRId64"/%s widend %"PRId64, + __func__, wm->markerid, + wm->description, + wm->workinfoidend); + } + bzero(&ms_add, sizeof(ms_add)); markersummary.markerid = wm->markerid; @@ -4652,6 +4666,12 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), "endmarkextra:%d=%s%c", + rows, + m_item ? marks->extra : EMPTY, + FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ftv_to_buf(&(wi->createdate), reply, sizeof(reply)); snprintf(tmp, sizeof(tmp), "start:%d=%s%c", rows, reply, FLDSEP); From 0e27bd2d47e7ae268b2fddfc3dc4e7fd4b8a3532 Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 11 Mar 2015 23:13:39 +1100 Subject: [PATCH 4/7] php - correct shift php --- pool/page_shifts.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pool/page_shifts.php b/pool/page_shifts.php index 1230d380..b83d3ec6 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -31,12 +31,12 @@ function doshifts($data, $user) $shifname = $ans['shift:'.$i]; $shif = preg_replace(array('/^.* to /','/^.*fin: /'), '', $shifname); $ablock = false; - if (preg_match('/to.*Block.* fin/', $shifname) === true) + if (preg_match('/to.*Block.* fin/', $shifname) == 1) $ablock = true; else { $shifex = $ans['endmarkextra:'.$i]; - if (preg_match('/Block .* fin/', $shifex) === true) + if (preg_match('/Block .* fin/', $shifex) == 1) $ablock = true; } if ($ablock === true) From 8e324f0ba534dcb94b4442a1cd5132d9b8132d8a Mon Sep 17 00:00:00 2001 From: kanoi Date: Wed, 11 Mar 2015 23:26:23 +1100 Subject: [PATCH 5/7] ckdb - add message spacing --- src/ckdb_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index b61c0595..8dbc872b 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -4281,7 +4281,7 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, DATA_PAYOUTS(payouts2, p2_item); DATA_PAYOUTS(old_payouts2, old_p2_item); snprintf(msg, sizeof(msg), - "payout %"PRId64" changed from '%s' to '%s' for" + "payout %"PRId64" changed from '%s' to '%s' for " "%"PRId32"/%s", payoutid, old_payouts2->status, payouts2->status, payouts2->height, payouts2->blockhash); @@ -4345,7 +4345,7 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, DATA_PAYOUTS(payouts2, p2_item); DATA_PAYOUTS(old_payouts2, old_p2_item); snprintf(msg, sizeof(msg), - "payout %"PRId64" changed from '%s' to '%s' for" + "payout %"PRId64" changed from '%s' to '%s' for " "%"PRId32"/%s", payoutid, old_payouts2->status, payouts2->status, payouts2->height, payouts2->blockhash); From 09a5de8e2cda85edbbe18f33b536a37f1b92409a Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 12 Mar 2015 16:24:07 +1100 Subject: [PATCH 6/7] ckdb - correct orphan diff redistribution --- src/ckdb.h | 6 +++++- src/ckdb_cmd.c | 10 ++++++---- src/ckdb_data.c | 29 +++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/ckdb.h b/src/ckdb.h index e59f475a..ecddeebc 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.022" +#define CKDB_VERSION DB_VERSION"-1.023" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -1113,6 +1113,10 @@ typedef struct blocks { double blockcdf; double blockluck; + /* diffacc for range calculations - includes orphans before it + * orphans have this set to 0 so they can't be double counted */ + double diffcalc; + /* From the last found block to this one * Orphans have these set to zero */ double diffratio; diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 8dbc872b..80b1f9d1 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -960,10 +960,12 @@ redo: desc = "Last 5"; } else if (seq == tot - 9) { desc = "Last 10"; - } else if (seq == tot - 19) { - desc = "Last 20"; - } else if (seq == tot - 41) { - desc = "Last 42"; + } else if (seq == tot - 24) { + desc = "Last 25"; + } else if (seq == tot - 49) { + desc = "Last 50"; + } else if (seq == tot - 99) { + desc = "Last 100"; } if (desc) { snprintf(tmp, sizeof(tmp), diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 5d9907f6..a4227e7e 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -2425,7 +2425,26 @@ bool check_update_blocks_stats(tv_t *stats) return false; if (blocks_stats_rebuild) { - ok = diffacc = netsumm = diffmean = pending = 0.0; + /* Have to first work out the diffcalc for each block + * Orphans count towards the next valid block after the orphan + * so this has to be done in the reverse order of the range + * calculations */ + pending = 0.0; + b_item = first_in_ktree(blocks_root, ctx); + while (b_item) { + DATA_BLOCKS(blocks, b_item); + if (CURRENT(&(blocks->expirydate))) { + pending += blocks->diffacc; + if (blocks->confirmed[0] == BLOCKS_ORPHAN) + blocks->diffcalc = 0.0; + else { + blocks->diffcalc = pending; + pending = 0.0; + } + } + b_item = next_in_ktree(ctx); + } + ok = diffacc = netsumm = diffmean = 0.0; b_item = last_in_ktree(blocks_root, ctx); while (b_item) { DATA_BLOCKS(blocks, b_item); @@ -2453,8 +2472,6 @@ bool check_update_blocks_stats(tv_t *stats) hex2bin(ndiffbin, workinfo->bits, 4); blocks->netdiff = diff_from_nbits(ndiffbin); } - pending += blocks->diffacc; - /* Stats for each blocks are independent of * if they are orphans or not */ if (blocks->netdiff == 0.0) @@ -2477,8 +2494,7 @@ bool check_update_blocks_stats(tv_t *stats) blocks->luck = 0.0; } else { ok++; - diffacc += pending; - pending = 0.0; + diffacc += blocks->diffcalc; netsumm += blocks->netdiff; if (netsumm == 0.0) @@ -2486,7 +2502,8 @@ bool check_update_blocks_stats(tv_t *stats) else blocks->diffratio = diffacc / netsumm; - diffmean = (diffmean * (ok - 1) + blocks->blockdiffratio) / ok; + diffmean = ((diffmean * (ok - 1)) + + (blocks->diffcalc / blocks->netdiff)) / ok; blocks->diffmean = diffmean; if (diffmean == 0.0) { From 7283af34e542beb15c09784eae489712059fc189 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 12 Mar 2015 18:47:27 +1100 Subject: [PATCH 7/7] php - add a login failure message --- pool/base.php | 22 +++++++++++++++++----- pool/page.php | 4 +++- pool/prime.php | 3 +++ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/pool/base.php b/pool/base.php index 5b24c4ab..a109a23c 100644 --- a/pool/base.php +++ b/pool/base.php @@ -334,7 +334,9 @@ function validUserPass($user, $pass) $key = 'ckp'.rand(1000000,9999999); $_SESSION['ckpkey'] = $key; $_SESSION[$key] = array('who' => $user, 'id' => $user); + return true; } + return false; } # function logout() @@ -364,6 +366,8 @@ function requestRegister() # function tryLogInOut() { + global $loginfailed; + // If already logged in, it will ignore User/Pass if (isset($_SESSION['ckpkey'])) { @@ -373,21 +377,29 @@ function tryLogInOut() } else { + $login = getparam('Login', false); + if (nuem($login)) + return; + $user = getparam('User', false); if ($user !== NULL) $user = loginStr($user); if (nuem($user)) + { + $loginfailed = true; return; + } $pass = getparam('Pass', false); if (nuem($pass)) + { + $loginfailed = true; return; + } - $login = getparam('Login', false); - if (nuem($login)) - return; - - validUserPass($user, $pass); + $valid = validUserPass($user, $pass); + if (!$valid) + $loginfailed = true; } } # diff --git a/pool/page.php b/pool/page.php index e4ec64dd..4ecccb6c 100644 --- a/pool/page.php +++ b/pool/page.php @@ -163,7 +163,7 @@ h1 {margin-top: 20px; float:middle; font-size: 20px;} # function pgtop($info, $dotop, $user, $douser) { - global $site_title; + global $site_title, $loginfailed; $phr = '?THs'; $plb = '?'; @@ -288,6 +288,8 @@ function pgtop($info, $dotop, $user, $douser) $top .= " You need to enable javascript to use"; $top .= " the $site_title web site."; + if ($loginfailed === true) + $top .= '
Login Failed
'; if (isset($info['u_nopayaddr'])) $top .= '
Please set a payout address on your account!
'; if (isset($info['u_noemail'])) diff --git a/pool/prime.php b/pool/prime.php index 539ef33b..6ee31cfb 100644 --- a/pool/prime.php +++ b/pool/prime.php @@ -3,6 +3,9 @@ global $stt; $stt = microtime(); # +global $loginfailed; +$loginfailed = false; +# include_once('param.php'); include_once('base.php'); #