Browse Source

Merge branch 'master' of bitbucket.org:ckolivas/ckpool

master
Con Kolivas 10 years ago
parent
commit
071566e3d5
  1. 10
      pool/db.php
  2. 2
      pool/page_blocks.php
  3. 7
      pool/socket.php
  4. 10
      sql/ckdb.sql
  5. 32
      sql/v0.7-v0.8.sql
  6. 342
      src/ckdb.c

10
pool/db.php

@ -3,6 +3,16 @@
include_once('socket.php'); include_once('socket.php');
include_once('base.php'); include_once('base.php');
# #
# List of db functions to call and get the results back from ckdb
# From homeInfo() and the rest after that
# The result is an array of all ckdb result field names and their values
# Also included:
# ['ID'] the id sent
# ['STAMP'] the ckdb reply timestamp
# ['STATUS'] the ckdb reply status (!'ok' = error)
# ['ERROR'] if status not 'ok' the error message reply
# The reply is false if the ckdb return data was corrupt
#
global $send_sep, $fld_sep, $val_sep; global $send_sep, $fld_sep, $val_sep;
$send_sep = '.'; $send_sep = '.';
$fld_sep = Chr(0x9); $fld_sep = Chr(0x9);

2
pool/page_blocks.php

@ -36,7 +36,7 @@ function doblocks($data, $user)
$pg .= "<td class=dl$ex>".$ans['height'.$i].'</td>'; $pg .= "<td class=dl$ex>".$ans['height'.$i].'</td>';
$pg .= "<td class=dl$ex>".$ans['workername'.$i].'</td>'; $pg .= "<td class=dl$ex>".$ans['workername'.$i].'</td>';
$pg .= "<td class=dr$ex>".btcfmt($ans['reward'.$i]).'</td>'; $pg .= "<td class=dr$ex>".btcfmt($ans['reward'.$i]).'</td>';
$pg .= "<td class=dl$ex>".gmdate('Y-m-d H:i:s+00', $ans['createdate'.$i]).'</td>'; $pg .= "<td class=dl$ex>".gmdate('Y-m-d H:i:s+00', $ans['firstcreatedate'.$i]).'</td>';
$pg .= "<td class=dr$ex>".$stat.'</td>'; $pg .= "<td class=dr$ex>".$stat.'</td>';
$pg .= "</tr>\n"; $pg .= "</tr>\n";
} }

7
pool/socket.php

@ -1,5 +1,7 @@
<?php <?php
# #
# See function sendsockreply($fun, $msg) at the end
#
# Note that $port in AF_UNIX should be the socket filename # Note that $port in AF_UNIX should be the socket filename
function _getsock($fun, $port, $unix=true) function _getsock($fun, $port, $unix=true)
{ {
@ -145,6 +147,11 @@ function sendsock($fun, $msg)
return $ret; return $ret;
} }
# #
# This is the only function in here you call
# You pass it a string $fun for debugging
# and the data $msg to send to ckdb
# and it returns $ret = false on error or $ret = the string reply
#
function sendsockreply($fun, $msg) function sendsockreply($fun, $msg)
{ {
$ret = false; $ret = false;

10
sql/ckdb.sql

@ -289,7 +289,12 @@ CREATE TABLE blocks (
nonce2 character varying(256) NOT NULL, nonce2 character varying(256) NOT NULL,
nonce character varying(64) NOT NULL, nonce character varying(64) NOT NULL,
reward bigint NOT NULL, -- satoshis reward bigint NOT NULL, -- satoshis
confirmed char DEFAULT '' NOT NULL, -- blank, 'c'onfirmed or 'o'rphan confirmed char DEFAULT '' NOT NULL,
diffacc float DEFAULT 0 NOT NULL,
differr float DEFAULT 0 NOT NULL,
sharecount bigint DEFAULT 0 NOT NULL,
errorcount bigint DEFAULT 0 NOT NULL,
elapsed bigint DEFAULT 0 NOT NULL,
createdate timestamp with time zone NOT NULL, createdate timestamp with time zone NOT NULL,
createby character varying(64) DEFAULT ''::character varying NOT NULL, createby character varying(64) DEFAULT ''::character varying NOT NULL,
createcode character varying(128) DEFAULT ''::character varying NOT NULL, createcode character varying(128) DEFAULT ''::character varying NOT NULL,
@ -340,6 +345,7 @@ CREATE TABLE auths (
clientid integer NOT NULL, clientid integer NOT NULL,
enonce1 character varying(64) NOT NULL, enonce1 character varying(64) NOT NULL,
useragent character varying(256) NOT NULL, useragent character varying(256) NOT NULL,
preauth char DEFAULT 'N' NOT NULL,
createdate timestamp with time zone NOT NULL, createdate timestamp with time zone NOT NULL,
createby character varying(64) DEFAULT ''::character varying NOT NULL, createby character varying(64) DEFAULT ''::character varying NOT NULL,
createcode character varying(128) DEFAULT ''::character varying NOT NULL, createcode character varying(128) DEFAULT ''::character varying NOT NULL,
@ -391,4 +397,4 @@ CREATE TABLE version (
PRIMARY KEY (vlock) PRIMARY KEY (vlock)
); );
insert into version (vlock,version) values (1,'0.7'); insert into version (vlock,version) values (1,'0.8');

32
sql/v0.7-v0.8.sql

@ -0,0 +1,32 @@
SET SESSION AUTHORIZATION 'postgres';
BEGIN transaction;
DO $$
DECLARE ver TEXT;
BEGIN
UPDATE version set version='0.8' where vlock=1 and version='0.7';
IF found THEN
RETURN;
END IF;
SELECT version into ver from version
WHERE vlock=1;
RAISE EXCEPTION 'Wrong DB version - expect "0.7" - found "%"', ver;
END $$;
ALTER TABLE ONLY auths
ADD COLUMN preauth char DEFAULT 'N' NOT NULL;
ALTER TABLE ONLY blocks
ADD COLUMN diffacc float DEFAULT 0 NOT NULL,
ADD COLUMN differr float DEFAULT 0 NOT NULL,
ADD COLUMN sharecount bigint DEFAULT 0 NOT NULL,
ADD COLUMN errorcount bigint DEFAULT 0 NOT NULL,
ADD COLUMN elapsed bigint DEFAULT 0 NOT NULL;
END transaction;

342
src/ckdb.c

@ -46,8 +46,8 @@
*/ */
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "0.7" #define DB_VERSION "0.8"
#define CKDB_VERSION DB_VERSION"-0.106" #define CKDB_VERSION DB_VERSION"-0.202"
#define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -128,8 +128,6 @@ static char *restorefrom;
* ckdb aborting and needing a complete restart resolves it * ckdb aborting and needing a complete restart resolves it
* The users table, required for the authorise messages, is always updated * The users table, required for the authorise messages, is always updated
* immediately and is not affected by ckpool messages until we * immediately and is not affected by ckpool messages until we
* TODO: allow bitcoin addresses - this will also need to be handled
* while filling the queue during reload, once we allow BTC addresses
* During the reload, when checking the timeframe for summarisation, we * During the reload, when checking the timeframe for summarisation, we
* use the current last userstats createdate as 'now' to avoid touching a * use the current last userstats createdate as 'now' to avoid touching a
* timeframe where data could still be waiting to be loaded * timeframe where data could still be waiting to be loaded
@ -767,6 +765,7 @@ enum cmd_values {
CMD_LOGLEVEL, CMD_LOGLEVEL,
CMD_SHARELOG, CMD_SHARELOG,
CMD_AUTH, CMD_AUTH,
CMD_ADDRAUTH,
CMD_ADDUSER, CMD_ADDUSER,
CMD_NEWPASS, CMD_NEWPASS,
CMD_CHKPASS, CMD_CHKPASS,
@ -841,6 +840,8 @@ static K_LIST *transfer_free;
// older version missing field defaults // older version missing field defaults
static TRANSFER auth_1 = { "poolinstance", "", auth_1.value }; static TRANSFER auth_1 = { "poolinstance", "", auth_1.value };
static K_ITEM auth_poolinstance = { "tmp", NULL, NULL, (void *)(&auth_1) }; static K_ITEM auth_poolinstance = { "tmp", NULL, NULL, (void *)(&auth_1) };
static TRANSFER auth_2 = { "preauth", FALSE_STR, auth_2.value };
static K_ITEM auth_preauth = { "tmp", NULL, NULL, (void *)(&auth_2) };
static TRANSFER poolstats_1 = { "elapsed", "0", poolstats_1.value }; static TRANSFER poolstats_1 = { "elapsed", "0", poolstats_1.value };
static K_ITEM poolstats_elapsed = { "tmp", NULL, NULL, (void *)(&poolstats_1) }; static K_ITEM poolstats_elapsed = { "tmp", NULL, NULL, (void *)(&poolstats_1) };
static TRANSFER userstats_1 = { "elapsed", "0", userstats_1.value }; static TRANSFER userstats_1 = { "elapsed", "0", userstats_1.value };
@ -1043,7 +1044,7 @@ static K_LIST *optioncontrol_free;
static K_STORE *optioncontrol_store; static K_STORE *optioncontrol_store;
*/ */
// TODO: aging/discarding workinfo,shares // TODO: discarding workinfo,shares
// WORKINFO workinfo.id.json={...} // WORKINFO workinfo.id.json={...}
typedef struct workinfo { typedef struct workinfo {
int64_t workinfoid; int64_t workinfoid;
@ -1254,6 +1255,7 @@ typedef struct auths {
int32_t clientid; int32_t clientid;
char enonce1[TXT_SML+1]; char enonce1[TXT_SML+1];
char useragent[TXT_BIG+1]; char useragent[TXT_BIG+1];
char preauth[TXT_FLAG+1];
HISTORYDATECONTROLFIELDS; HISTORYDATECONTROLFIELDS;
} AUTHS; } AUTHS;
@ -2475,7 +2477,7 @@ unparam:
return ok; return ok;
} }
static bool users_add(PGconn *conn, char *username, char *emailaddress, static K_ITEM *users_add(PGconn *conn, char *username, char *emailaddress,
char *passwordhash, char *by, char *code, char *inet, char *passwordhash, char *by, char *code, char *inet,
tv_t *cd, K_TREE *trf_root) tv_t *cd, K_TREE *trf_root)
{ {
@ -2568,7 +2570,10 @@ unitem:
} }
K_WUNLOCK(users_free); K_WUNLOCK(users_free);
return ok; if (ok)
return item;
else
return NULL;
} }
static bool users_fill(PGconn *conn) static bool users_fill(PGconn *conn)
@ -3158,7 +3163,7 @@ static bool payments_fill(PGconn *conn)
LOGDEBUG("%s(): select", __func__); LOGDEBUG("%s(): select", __func__);
// TODO: handle selecting a subset, eg 20 per web page // TODO: handle selecting a subset, eg 20 per web page (in blocklist also)
sel = "select " sel = "select "
"userid,paydate,payaddress,originaltxn,amount,committxn,commitblockhash" "userid,paydate,payaddress,originaltxn,amount,committxn,commitblockhash"
HISTORYDATECONTROL HISTORYDATECONTROL
@ -3481,20 +3486,6 @@ static bool _sharesummary_update(PGconn *conn, SHARES *s_row, SHAREERRORS *e_row
static cmp_t cmp_sharesummary_workinfoid(K_ITEM *a, K_ITEM *b); static cmp_t cmp_sharesummary_workinfoid(K_ITEM *a, K_ITEM *b);
static cmp_t cmp_shares(K_ITEM *a, K_ITEM *b); static cmp_t cmp_shares(K_ITEM *a, K_ITEM *b);
/* N.B. a DB check can be done to find sharesummaries that have missed being
* aged (and a possible problem with the aging process):
* e.g. for a date D in the past of at least a few hours
* select count(*) from sharesummary where createdate<'D' and complete='n';
* and can be easily corrected:
* update sharesummary set complete='a' where createdate<'D' and complete='n';
* It's important to make sure the D value is far enough in the past such that
* all the matching sharesummary records in ckdb have certainly completed
* ckdb would need to restart to get the updated DB information though it would
* not affect current ckdb code
* TODO: This will happen until auto aging is added here - since ckpool can not reliably
* age all workinfo that was active when it exits (e.g. a crash) so best to not
* try, but get ckdb to auto age old unaged data
*/
static bool workinfo_age(PGconn *conn, int64_t workinfoid, char *poolinstance, static bool workinfo_age(PGconn *conn, int64_t workinfoid, char *poolinstance,
char *by, char *code, char *inet, tv_t *cd, char *by, char *code, char *inet, tv_t *cd,
tv_t *ss_first, tv_t *ss_last, int64_t *ss_count, tv_t *ss_first, tv_t *ss_last, int64_t *ss_count,
@ -4000,7 +3991,6 @@ static bool shares_add(PGconn *conn, char *workinfoid, char *username, char *wor
shares = DATA_SHARES(s_item); shares = DATA_SHARES(s_item);
// TODO: allow BTC address later?
K_RLOCK(users_free); K_RLOCK(users_free);
u_item = find_users(username); u_item = find_users(username);
K_RUNLOCK(users_free); K_RUNLOCK(users_free);
@ -4097,9 +4087,6 @@ unitem:
static bool shares_fill() static bool shares_fill()
{ {
// TODO: reload shares from workinfo from log file
// and verify workinfo while doing that
return true; return true;
} }
@ -4143,7 +4130,6 @@ static bool shareerrors_add(PGconn *conn, char *workinfoid, char *username,
shareerrors = DATA_SHAREERRORS(s_item); shareerrors = DATA_SHAREERRORS(s_item);
// TODO: allow BTC address later?
K_RLOCK(users_free); K_RLOCK(users_free);
u_item = find_users(username); u_item = find_users(username);
K_RUNLOCK(users_free); K_RUNLOCK(users_free);
@ -4234,9 +4220,6 @@ unitem:
static bool shareerrors_fill() static bool shareerrors_fill()
{ {
// TODO: reload shareerrors from workinfo from log file
// and verify workinfo while doing that
return true; return true;
} }
@ -4836,6 +4819,38 @@ void sharesummary_reload()
PQfinish(conn); PQfinish(conn);
} }
// TODO: do this better ... :)
static void dsp_hash(char *hash, char *buf, size_t siz)
{
char *ptr;
ptr = hash + strlen(hash) - (siz - 1) - 8;
if (ptr < hash)
ptr = hash;
STRNCPYSIZ(buf, ptr, siz);
}
static void dsp_blocks(K_ITEM *item, FILE *stream)
{
char createdate_buf[DATE_BUFSIZ], expirydate_buf[DATE_BUFSIZ];
BLOCKS *b = NULL;
char hash_dsp[16+1];
if (!item)
fprintf(stream, "%s() called with (null) item\n", __func__);
else {
b = DATA_BLOCKS(item);
dsp_hash(b->blockhash, hash_dsp, sizeof(hash_dsp));
tv_to_buf(&(b->createdate), createdate_buf, sizeof(createdate_buf));
tv_to_buf(&(b->expirydate), expirydate_buf, sizeof(expirydate_buf));
fprintf(stream, " hi=%d hash='%.16s' uid=%"PRId64" w='%s' "
"cd=%s ed=%s\n",
b->height, hash_dsp, b->userid, b->workername,
createdate_buf, expirydate_buf);
}
}
// order by height asc,blockhash asc,expirydate desc // order by height asc,blockhash asc,expirydate desc
static cmp_t cmp_blocks(K_ITEM *a, K_ITEM *b) static cmp_t cmp_blocks(K_ITEM *a, K_ITEM *b)
{ {
@ -4896,7 +4911,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
K_ITEM *b_item, *u_item, *old_b_item; K_ITEM *b_item, *u_item, *old_b_item;
char cd_buf[DATE_BUFSIZ]; char cd_buf[DATE_BUFSIZ];
char blk_dsp[16+1], *ptr; char hash_dsp[16+1];
BLOCKS *row; BLOCKS *row;
char *upd, *ins; char *upd, *ins;
char *params[11 + HISTORYDATECOUNT]; char *params[11 + HISTORYDATECOUNT];
@ -4918,11 +4933,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATEINIT(row, cd, by, code, inet);
// TODO: do this better ... :) dsp_hash(blockhash, hash_dsp, sizeof(hash_dsp));
ptr = blockhash + strlen(blockhash) - (sizeof(blk_dsp)-1) - 8;
if (ptr < blockhash)
ptr = blockhash;
STRNCPY(blk_dsp, ptr);
K_WLOCK(blocks_free); K_WLOCK(blocks_free);
old_b_item = find_blocks(row->height, blockhash); old_b_item = find_blocks(row->height, blockhash);
@ -4940,7 +4951,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
__func__, __func__,
blocks_confirmed(DATA_BLOCKS(old_b_item)->confirmed), blocks_confirmed(DATA_BLOCKS(old_b_item)->confirmed),
blocks_confirmed(confirmed), blocks_confirmed(confirmed),
height, blk_dsp, cd_buf); height, hash_dsp, cd_buf);
} }
return true; return true;
} }
@ -5007,7 +5018,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
"Ignored: Block: %s/...%s/%s", "Ignored: Block: %s/...%s/%s",
__func__, __func__,
blocks_confirmed(confirmed), blocks_confirmed(confirmed),
height, blk_dsp, cd_buf); height, hash_dsp, cd_buf);
goto flail; goto flail;
} }
want = BLOCKS_CONFIRM; want = BLOCKS_CONFIRM;
@ -5017,7 +5028,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
tv_to_buf(cd, cd_buf, sizeof(cd_buf)); tv_to_buf(cd, cd_buf, sizeof(cd_buf));
LOGERR("%s(): Can't %s a non-existent Block: %s/...%s/%s", LOGERR("%s(): Can't %s a non-existent Block: %s/...%s/%s",
__func__, blocks_confirmed(confirmed), __func__, blocks_confirmed(confirmed),
height, blk_dsp, cd_buf); height, hash_dsp, cd_buf);
goto flail; goto flail;
} }
if (confirmed[0] == BLOCKS_CONFIRM) if (confirmed[0] == BLOCKS_CONFIRM)
@ -5026,15 +5037,14 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
k_add_head(blocks_free, b_item); k_add_head(blocks_free, b_item);
K_WUNLOCK(blocks_free); K_WUNLOCK(blocks_free);
// No mismatch messages during startup // No mismatch messages during startup
if (!startup_complete) { if (startup_complete) {
tv_to_buf(cd, cd_buf, sizeof(cd_buf)); tv_to_buf(cd, cd_buf, sizeof(cd_buf));
LOGERR("%s(): Request Status: %s requires Status: %s. " LOGERR("%s(): New Status: %s requires Status: %c. "
"Ignored: Status: %s, Block: %s/...%s/%s", "Ignored: Status: %s, Block: %s/...%s/%s",
__func__, __func__,
blocks_confirmed(confirmed), blocks_confirmed(confirmed), want,
blocks_confirmed(BLOCKS_CONFIRM_STR),
blocks_confirmed(DATA_BLOCKS(old_b_item)->confirmed), blocks_confirmed(DATA_BLOCKS(old_b_item)->confirmed),
height, blk_dsp, cd_buf); height, hash_dsp, cd_buf);
} }
goto flail; goto flail;
} }
@ -5174,9 +5184,10 @@ flail:
} }
tv_to_buf(&(DATA_BLOCKS(b_item)->createdate), cd_buf, sizeof(cd_buf)); tv_to_buf(&(DATA_BLOCKS(b_item)->createdate), cd_buf, sizeof(cd_buf));
snprintf(tmp, sizeof(tmp), snprintf(tmp, sizeof(tmp),
" Reward: %f, User: %s, Worker: %s, ShareEst: %.1f %s%s%% UTC:%s", " Reward: %f, Worker: %s, ShareEst: %.1f %s%s%% UTC:%s",
BTC_TO_D(DATA_BLOCKS(b_item)->reward), BTC_TO_D(DATA_BLOCKS(b_item)->reward),
username, workername, pool.diffacc, est, pct, cd_buf); DATA_BLOCKS(b_item)->workername,
pool.diffacc, est, pct, cd_buf);
if (pool.workinfoid < DATA_BLOCKS(b_item)->workinfoid) { if (pool.workinfoid < DATA_BLOCKS(b_item)->workinfoid) {
pool.workinfoid = DATA_BLOCKS(b_item)->workinfoid; pool.workinfoid = DATA_BLOCKS(b_item)->workinfoid;
pool.diffacc = pool.differr = pool.diffacc = pool.differr =
@ -5194,7 +5205,7 @@ flail:
LOGWARNING("%s(): %sStatus: %s, Block: %s/...%s%s", LOGWARNING("%s(): %sStatus: %s, Block: %s/...%s%s",
__func__, blk ? "BLOCK! " : "", __func__, blk ? "BLOCK! " : "",
blocks_confirmed(confirmed), blocks_confirmed(confirmed),
height, blk_dsp, tmp); height, hash_dsp, tmp);
} }
return ok; return ok;
@ -5574,8 +5585,9 @@ static cmp_t cmp_auths(K_ITEM *a, K_ITEM *b)
static char *auths_add(PGconn *conn, char *poolinstance, char *username, static char *auths_add(PGconn *conn, char *poolinstance, char *username,
char *workername, char *clientid, char *enonce1, char *workername, char *clientid, char *enonce1,
char *useragent, char *by, char *code, char *inet, char *useragent, char *preauth, char *by, char *code,
tv_t *cd, bool igndup, K_TREE *trf_root) char *inet, tv_t *cd, bool igndup, K_TREE *trf_root,
bool addressuser)
{ {
ExecStatusType rescode; ExecStatusType rescode;
bool conned = false; bool conned = false;
@ -5587,7 +5599,7 @@ static char *auths_add(PGconn *conn, char *poolinstance, char *username,
AUTHS *row; AUTHS *row;
char *ins; char *ins;
char *secuserid = NULL; char *secuserid = NULL;
char *params[7 + HISTORYDATECOUNT]; char *params[8 + HISTORYDATECOUNT];
int par; int par;
LOGDEBUG("%s(): add", __func__); LOGDEBUG("%s(): add", __func__);
@ -5601,8 +5613,18 @@ static char *auths_add(PGconn *conn, char *poolinstance, char *username,
K_RLOCK(users_free); K_RLOCK(users_free);
u_item = find_users(username); u_item = find_users(username);
K_RUNLOCK(users_free); K_RUNLOCK(users_free);
if (!u_item) if (!u_item) {
goto unitem; if (addressuser) {
if (conn == NULL) {
conn = dbconnect();
conned = true;
}
u_item = users_add(conn, username, EMPTY, EMPTY,
by, code, inet, cd, trf_root);
}
if (!u_item)
goto unitem;
}
STRNCPY(row->poolinstance, poolinstance); STRNCPY(row->poolinstance, poolinstance);
row->userid = DATA_USERS(u_item)->userid; row->userid = DATA_USERS(u_item)->userid;
@ -5614,6 +5636,7 @@ static char *auths_add(PGconn *conn, char *poolinstance, char *username,
TXT_TO_INT("clientid", clientid, row->clientid); TXT_TO_INT("clientid", clientid, row->clientid);
STRNCPY(row->enonce1, enonce1); STRNCPY(row->enonce1, enonce1);
STRNCPY(row->useragent, useragent); STRNCPY(row->useragent, useragent);
STRNCPY(row->preauth, preauth);
HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATEINIT(row, cd, by, code, inet);
HISTORYDATETRANSFER(trf_root, row); HISTORYDATETRANSFER(trf_root, row);
@ -5623,6 +5646,9 @@ static char *auths_add(PGconn *conn, char *poolinstance, char *username,
k_add_head(auths_free, a_item); k_add_head(auths_free, a_item);
K_WUNLOCK(auths_free); K_WUNLOCK(auths_free);
if (conned)
PQfinish(conn);
if (!igndup) { if (!igndup) {
tv_to_buf(cd, cd_buf, sizeof(cd_buf)); tv_to_buf(cd, cd_buf, sizeof(cd_buf));
LOGERR("%s(): Duplicate auths ignored %s/%s/%s", LOGERR("%s(): Duplicate auths ignored %s/%s/%s",
@ -5653,12 +5679,13 @@ static char *auths_add(PGconn *conn, char *poolinstance, char *username,
params[par++] = int_to_buf(row->clientid, NULL, 0); params[par++] = int_to_buf(row->clientid, NULL, 0);
params[par++] = str_to_buf(row->enonce1, NULL, 0); params[par++] = str_to_buf(row->enonce1, NULL, 0);
params[par++] = str_to_buf(row->useragent, NULL, 0); params[par++] = str_to_buf(row->useragent, NULL, 0);
params[par++] = str_to_buf(row->preauth, NULL, 0);
HISTORYDATEPARAMS(params, par, row); HISTORYDATEPARAMS(params, par, row);
PARCHK(par, params); PARCHK(par, params);
ins = "insert into auths " ins = "insert into auths "
"(authid,poolinstance,userid,workername,clientid,enonce1,useragent" "(authid,poolinstance,userid,workername,clientid,enonce1,useragent,preauth"
HISTORYDATECONTROL ") values (" PQPARAM12 ")"; HISTORYDATECONTROL ") values (" PQPARAM13 ")";
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE); res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0, CKPQ_WRITE);
rescode = PQresultStatus(res); rescode = PQresultStatus(res);
@ -5704,7 +5731,7 @@ static bool auths_fill(PGconn *conn)
LOGDEBUG("%s(): select", __func__); LOGDEBUG("%s(): select", __func__);
// TODO: keep last x - since a user may login and mine for 100 days // TODO: add/update a (single) fake auth every ~10min or 10min after the last one?
sel = "select " sel = "select "
"authid,userid,workername,clientid,enonce1,useragent" "authid,userid,workername,clientid,enonce1,useragent"
HISTORYDATECONTROL HISTORYDATECONTROL
@ -6810,7 +6837,6 @@ static void clean_up(ckpool_t *ckp)
fclose(ckp->logfp); fclose(ckp->logfp);
} }
// TODO: skip ones not needed for confirm_summaries()
static void alloc_storage() static void alloc_storage()
{ {
workqueue_free = k_new_list("WorkQueue", sizeof(WORKQUEUE), workqueue_free = k_new_list("WorkQueue", sizeof(WORKQUEUE),
@ -6869,6 +6895,7 @@ static void alloc_storage()
ALLOC_BLOCKS, LIMIT_BLOCKS, true); ALLOC_BLOCKS, LIMIT_BLOCKS, true);
blocks_store = k_new_store(blocks_free); blocks_store = k_new_store(blocks_free);
blocks_root = new_ktree(); blocks_root = new_ktree();
blocks_free->dsp_func = dsp_blocks;
miningpayouts_free = k_new_list("MiningPayouts", sizeof(MININGPAYOUTS), miningpayouts_free = k_new_list("MiningPayouts", sizeof(MININGPAYOUTS),
ALLOC_MININGPAYOUTS, LIMIT_MININGPAYOUTS, true); ALLOC_MININGPAYOUTS, LIMIT_MININGPAYOUTS, true);
@ -6955,9 +6982,7 @@ static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
{ {
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
K_ITEM *i_username, *i_emailaddress, *i_passwordhash, *u_item;
K_ITEM *i_username, *i_emailaddress, *i_passwordhash;
bool ok;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd); LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@ -6973,12 +6998,12 @@ static char *cmd_adduser(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
if (!i_passwordhash) if (!i_passwordhash)
return strdup(reply); return strdup(reply);
ok = users_add(conn, DATA_TRANSFER(i_username)->data, u_item = users_add(conn, DATA_TRANSFER(i_username)->data,
DATA_TRANSFER(i_emailaddress)->data, DATA_TRANSFER(i_emailaddress)->data,
DATA_TRANSFER(i_passwordhash)->data, DATA_TRANSFER(i_passwordhash)->data,
by, code, inet, now, trf_root); by, code, inet, now, trf_root);
if (!ok) { if (!u_item) {
LOGERR("%s() %s.failed.DBE", __func__, id); LOGERR("%s() %s.failed.DBE", __func__, id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} }
@ -7272,6 +7297,8 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
char tmp[1024]; char tmp[1024];
char *buf; char *buf;
size_t len, off; size_t len, off;
int32_t height = -1;
tv_t first_cd = {0,0};
int rows; int rows;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd); LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@ -7282,6 +7309,10 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
K_RLOCK(blocks_free); K_RLOCK(blocks_free);
b_item = last_in_ktree(blocks_root, ctx); b_item = last_in_ktree(blocks_root, ctx);
while (b_item && rows < 42) { while (b_item && rows < 42) {
if (height != DATA_BLOCKS(b_item)->height) {
height = DATA_BLOCKS(b_item)->height;
copy_tv(&first_cd, &(DATA_BLOCKS(b_item)->createdate));
}
if (CURRENT(&(DATA_BLOCKS(b_item)->expirydate))) { if (CURRENT(&(DATA_BLOCKS(b_item)->expirydate))) {
int_to_buf(DATA_BLOCKS(b_item)->height, reply, sizeof(reply)); int_to_buf(DATA_BLOCKS(b_item)->height, reply, sizeof(reply));
snprintf(tmp, sizeof(tmp), "height%d=%s%c", rows, reply, FLDSEP); snprintf(tmp, sizeof(tmp), "height%d=%s%c", rows, reply, FLDSEP);
@ -7303,6 +7334,11 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
snprintf(tmp, sizeof(tmp), "workername%d=%s%c", rows, reply, FLDSEP); snprintf(tmp, sizeof(tmp), "workername%d=%s%c", rows, reply, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp); APPEND_REALLOC(buf, off, len, tmp);
snprintf(tmp, sizeof(tmp),
"firstcreatedate%d=%ld%c", rows,
first_cd.tv_sec, FLDSEP);
APPEND_REALLOC(buf, off, len, tmp);
snprintf(tmp, sizeof(tmp), snprintf(tmp, sizeof(tmp),
"createdate%d=%ld%c", rows, "createdate%d=%ld%c", rows,
DATA_BLOCKS(b_item)->createdate.tv_sec, FLDSEP); DATA_BLOCKS(b_item)->createdate.tv_sec, FLDSEP);
@ -8210,7 +8246,10 @@ static char *cmd_blocks_do(PGconn *conn, char *cmd, char *id, char *by,
} }
if (!ok) { if (!ok) {
LOGERR("%s() %s.failed.DBE", __func__, id); /* Ignore during startup,
* another error should have shown if it matters */
if (startup_complete)
LOGERR("%s() %s.failed.DBE", __func__, id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} }
@ -8244,7 +8283,7 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
char reply[1024] = ""; char reply[1024] = "";
size_t siz = sizeof(reply); size_t siz = sizeof(reply);
K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid; K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid;
K_ITEM *i_enonce1, *i_useragent; K_ITEM *i_enonce1, *i_useragent, *i_preauth;
char *secuserid; char *secuserid;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd); LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
@ -8273,13 +8312,18 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by,
if (!i_useragent) if (!i_useragent)
return strdup(reply); return strdup(reply);
i_preauth = optional_name(trf_root, "preauth", 1, NULL);
if (!i_preauth)
i_preauth = &auth_preauth;
secuserid = auths_add(conn, DATA_TRANSFER(i_poolinstance)->data, secuserid = auths_add(conn, DATA_TRANSFER(i_poolinstance)->data,
DATA_TRANSFER(i_username)->data, DATA_TRANSFER(i_username)->data,
DATA_TRANSFER(i_workername)->data, DATA_TRANSFER(i_workername)->data,
DATA_TRANSFER(i_clientid)->data, DATA_TRANSFER(i_clientid)->data,
DATA_TRANSFER(i_enonce1)->data, DATA_TRANSFER(i_enonce1)->data,
DATA_TRANSFER(i_useragent)->data, DATA_TRANSFER(i_useragent)->data,
by, code, inet, cd, igndup, trf_root); DATA_TRANSFER(i_preauth)->data,
by, code, inet, cd, igndup, trf_root, false);
if (!secuserid) { if (!secuserid) {
LOGDEBUG("%s() %s.failed.DBE", __func__, id); LOGDEBUG("%s() %s.failed.DBE", __func__, id);
@ -8309,6 +8353,83 @@ static char *cmd_auth(PGconn *conn, char *cmd, char *id,
return cmd_auth_do(conn, cmd, id, by, code, inet, cd, igndup, trf_root); return cmd_auth_do(conn, cmd, id, by, code, inet, cd, igndup, trf_root);
} }
static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by,
char *code, char *inet, tv_t *cd, bool igndup,
K_TREE *trf_root)
{
char reply[1024] = "";
size_t siz = sizeof(reply);
K_ITEM *i_poolinstance, *i_username, *i_workername, *i_clientid;
K_ITEM *i_enonce1, *i_useragent, *i_preauth;
char *secuserid;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
i_poolinstance = optional_name(trf_root, "poolinstance", 1, NULL);
if (!i_poolinstance)
i_poolinstance = &auth_poolinstance;
i_username = require_name(trf_root, "username", 1, NULL, reply, siz);
if (!i_username)
return strdup(reply);
i_workername = require_name(trf_root, "workername", 1, NULL, reply, siz);
if (!i_workername)
return strdup(reply);
i_clientid = require_name(trf_root, "clientid", 1, NULL, reply, siz);
if (!i_clientid)
return strdup(reply);
i_enonce1 = require_name(trf_root, "enonce1", 1, NULL, reply, siz);
if (!i_enonce1)
return strdup(reply);
i_useragent = require_name(trf_root, "useragent", 0, NULL, reply, siz);
if (!i_useragent)
return strdup(reply);
i_preauth = require_name(trf_root, "preauth", 1, NULL, reply, siz);
if (!i_preauth)
return strdup(reply);
secuserid = auths_add(conn, DATA_TRANSFER(i_poolinstance)->data,
DATA_TRANSFER(i_username)->data,
DATA_TRANSFER(i_workername)->data,
DATA_TRANSFER(i_clientid)->data,
DATA_TRANSFER(i_enonce1)->data,
DATA_TRANSFER(i_useragent)->data,
DATA_TRANSFER(i_preauth)->data,
by, code, inet, cd, igndup, trf_root, true);
if (!secuserid) {
LOGDEBUG("%s() %s.failed.DBE", __func__, id);
return strdup("failed.DBE");
}
LOGDEBUG("%s.ok.auth added for %s", id, secuserid);
snprintf(reply, siz, "ok.%s", secuserid);
return strdup(reply);
}
static char *cmd_addrauth(PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, char *by,
char *code, char *inet, tv_t *cd,
K_TREE *trf_root)
{
bool igndup = false;
// confirm_summaries() doesn't call this
if (reloading) {
if (tv_equal(cd, &(dbstatus.newest_createdate_auths)))
igndup = true;
else if (tv_newer(cd, &(dbstatus.newest_createdate_auths)))
return NULL;
}
return cmd_addrauth_do(conn, cmd, id, by, code, inet, cd, igndup, trf_root);
}
static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
@ -8347,7 +8468,9 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id,
} }
// TODO: handle orphans // TODO: handle orphans
K_RLOCK(blocks_free);
b_item = last_in_ktree(blocks_root, ctx); b_item = last_in_ktree(blocks_root, ctx);
K_RUNLOCK(blocks_free);
if (b_item) { if (b_item) {
tvs_to_buf(&(DATA_BLOCKS(b_item)->createdate), reply, sizeof(reply)); tvs_to_buf(&(DATA_BLOCKS(b_item)->createdate), reply, sizeof(reply));
snprintf(tmp, sizeof(tmp), "lastblock=%s%cconfirmed=%s%c", snprintf(tmp, sizeof(tmp), "lastblock=%s%cconfirmed=%s%c",
@ -8509,6 +8632,7 @@ static K_TREE *upd_add_mu(K_TREE *mu_root, K_STORE *mu_store, int64_t userid, in
The value of diff_want defaults to the block's network difficulty The value of diff_want defaults to the block's network difficulty
(block_ndiff) but can be changed with diff_times and diff_add to: (block_ndiff) but can be changed with diff_times and diff_add to:
block_ndiff * diff_times + diff_add block_ndiff * diff_times + diff_add
N.B. diff_times and diff_add can be zero, positive or negative
The pplns_elapsed time of the shares is from the createdate of the The pplns_elapsed time of the shares is from the createdate of the
begin_workinfoid that has shares accounted to the total, begin_workinfoid that has shares accounted to the total,
up to the createdate of the last share up to the createdate of the last share
@ -8573,8 +8697,10 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
blocks.height = height + 1; blocks.height = height + 1;
blocks.blockhash[0] = '\0'; blocks.blockhash[0] = '\0';
look.data = (void *)(&blocks); look.data = (void *)(&blocks);
K_RLOCK(blocks_free);
b_item = find_before_in_ktree(blocks_root, &look, cmp_blocks, ctx); b_item = find_before_in_ktree(blocks_root, &look, cmp_blocks, ctx);
if (!b_item) { if (!b_item) {
K_RUNLOCK(blocks_free);
snprintf(reply, siz, "ERR.no block height %d", height); snprintf(reply, siz, "ERR.no block height %d", height);
return strdup(reply); return strdup(reply);
} }
@ -8583,6 +8709,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
break; break;
b_item = prev_in_ktree(ctx); b_item = prev_in_ktree(ctx);
} }
K_RUNLOCK(blocks_free);
if (!b_item || DATA_BLOCKS(b_item)->height != height) { if (!b_item || DATA_BLOCKS(b_item)->height != height) {
snprintf(reply, siz, "ERR.unconfirmed block %d", height); snprintf(reply, siz, "ERR.unconfirmed block %d", height);
return strdup(reply); return strdup(reply);
@ -8600,6 +8727,13 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
hex2bin(ndiffbin, DATA_WORKINFO(w_item)->bits, 4); hex2bin(ndiffbin, DATA_WORKINFO(w_item)->bits, 4);
ndiff = diff_from_nbits(ndiffbin); ndiff = diff_from_nbits(ndiffbin);
diff_want = ndiff * diff_times + diff_add; diff_want = ndiff * diff_times + diff_add;
if (diff_want < 1.0) {
snprintf(reply, siz,
"ERR.invalid diff_want result %f",
diff_want);
return strdup(reply);
}
begin_workinfoid = 0; begin_workinfoid = 0;
share_count = 0; share_count = 0;
total = 0; total = 0;
@ -8634,7 +8768,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
break; break;
default: default:
snprintf(reply, siz, snprintf(reply, siz,
"ERR.sharesummary not ready in workinfo %"PRId64, "ERR.sharesummary1 not ready in workinfo %"PRId64,
DATA_SHARESUMMARY(ss_item)->workinfoid); DATA_SHARESUMMARY(ss_item)->workinfoid);
goto shazbot; goto shazbot;
} }
@ -8659,7 +8793,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
break; break;
default: default:
snprintf(reply, siz, snprintf(reply, siz,
"ERR.sharesummary not ready in workinfo %"PRId64, "ERR.sharesummary2 not ready in workinfo %"PRId64,
DATA_SHARESUMMARY(ss_item)->workinfoid); DATA_SHARESUMMARY(ss_item)->workinfoid);
goto shazbot; goto shazbot;
} }
@ -8818,6 +8952,8 @@ static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,
if (!i_file) if (!i_file)
return strdup(reply); return strdup(reply);
dsp_ktree(blocks_free, blocks_root, DATA_BLOCKS(i_file)->data, NULL);
dsp_ktree(transfer_free, trf_root, DATA_TRANSFER(i_file)->data, NULL); dsp_ktree(transfer_free, trf_root, DATA_TRANSFER(i_file)->data, NULL);
dsp_ktree(sharesummary_free, sharesummary_root, DATA_TRANSFER(i_file)->data, NULL); dsp_ktree(sharesummary_free, sharesummary_root, DATA_TRANSFER(i_file)->data, NULL);
@ -8964,6 +9100,7 @@ static struct CMDS {
{ CMD_SHARELOG, STR_SHAREERRORS, false, true, cmd_sharelog, ACCESS_POOL }, { CMD_SHARELOG, STR_SHAREERRORS, false, true, cmd_sharelog, ACCESS_POOL },
{ CMD_SHARELOG, STR_AGEWORKINFO, false, true, cmd_sharelog, ACCESS_POOL }, { CMD_SHARELOG, STR_AGEWORKINFO, false, true, cmd_sharelog, ACCESS_POOL },
{ CMD_AUTH, "authorise", false, true, cmd_auth, ACCESS_POOL }, { CMD_AUTH, "authorise", false, true, cmd_auth, ACCESS_POOL },
{ CMD_ADDRAUTH, "addrauth", false, true, cmd_addrauth, ACCESS_POOL },
{ CMD_ADDUSER, "adduser", false, false, cmd_adduser, ACCESS_WEB }, { CMD_ADDUSER, "adduser", false, false, cmd_adduser, ACCESS_WEB },
{ CMD_NEWPASS, "newpass", false, false, cmd_newpass, ACCESS_WEB }, { CMD_NEWPASS, "newpass", false, false, cmd_newpass, ACCESS_WEB },
{ CMD_CHKPASS, "chkpass", false, false, cmd_chkpass, ACCESS_WEB }, { CMD_CHKPASS, "chkpass", false, false, cmd_chkpass, ACCESS_WEB },
@ -9470,6 +9607,16 @@ static void *logger(__maybe_unused void *arg)
return NULL; return NULL;
} }
#define STORELASTREPLY(_cmd) do { \
if (last_ ## _cmd) \
free(last_ ## _cmd); \
last_ ## _cmd = buf; \
buf = NULL; \
if (reply_ ## _cmd) \
free(reply_ ## _cmd); \
reply_ ## _cmd = rep; \
} while (0)
static void *socketer(__maybe_unused void *arg) static void *socketer(__maybe_unused void *arg)
{ {
proc_instance_t *pi = (proc_instance_t *)arg; proc_instance_t *pi = (proc_instance_t *)arg;
@ -9477,6 +9624,7 @@ static void *socketer(__maybe_unused void *arg)
char *end, *ans = NULL, *rep = NULL, *buf = NULL, *dot; char *end, *ans = NULL, *rep = NULL, *buf = NULL, *dot;
char cmd[CMD_SIZ+1], id[ID_SIZ+1], reply[1024+1]; char cmd[CMD_SIZ+1], id[ID_SIZ+1], reply[1024+1];
char *last_auth = NULL, *reply_auth = NULL; char *last_auth = NULL, *reply_auth = NULL;
char *last_addrauth = NULL, *reply_addrauth = NULL;
char *last_chkpass = NULL, *reply_chkpass = NULL; char *last_chkpass = NULL, *reply_chkpass = NULL;
char *last_adduser = NULL, *reply_adduser = NULL; char *last_adduser = NULL, *reply_adduser = NULL;
char *last_newpass = NULL, *reply_newpass = NULL; char *last_newpass = NULL, *reply_newpass = NULL;
@ -9547,6 +9695,7 @@ static void *socketer(__maybe_unused void *arg)
* the reply without reprocessing the message * the reply without reprocessing the message
*/ */
dup = false; dup = false;
// These are ordered approximately most likely first
if (last_auth && strcmp(last_auth, buf) == 0) { if (last_auth && strcmp(last_auth, buf) == 0) {
reply_last = reply_auth; reply_last = reply_auth;
dup = true; dup = true;
@ -9562,6 +9711,9 @@ static void *socketer(__maybe_unused void *arg)
} else if (last_newid && strcmp(last_newid, buf) == 0) { } else if (last_newid && strcmp(last_newid, buf) == 0) {
reply_last = reply_newid; reply_last = reply_newid;
dup = true; dup = true;
} else if (last_addrauth && strcmp(last_addrauth, buf) == 0) {
reply_last = reply_auth;
dup = true;
} else if (last_web && strcmp(last_web, buf) == 0) { } else if (last_web && strcmp(last_web, buf) == 0) {
reply_last = reply_web; reply_last = reply_web;
dup = true; dup = true;
@ -9636,6 +9788,7 @@ static void *socketer(__maybe_unused void *arg)
break; break;
// Always process immediately: // Always process immediately:
case CMD_AUTH: case CMD_AUTH:
case CMD_ADDRAUTH:
// First message from the pool // First message from the pool
if (want_first) { if (want_first) {
ck_wlock(&fpm_lock); ck_wlock(&fpm_lock);
@ -9662,49 +9815,22 @@ static void *socketer(__maybe_unused void *arg)
ans = NULL; ans = NULL;
switch (cmdnum) { switch (cmdnum) {
case CMD_AUTH: case CMD_AUTH:
if (last_auth) STORELASTREPLY(auth);
free(last_auth); break;
last_auth = buf; case CMD_ADDRAUTH:
buf = NULL; STORELASTREPLY(addrauth);
if (reply_auth)
free(reply_auth);
reply_auth = rep;
break; break;
case CMD_CHKPASS: case CMD_CHKPASS:
if (last_chkpass) STORELASTREPLY(chkpass);
free(last_chkpass);
last_chkpass = buf;
buf = NULL;
if (reply_chkpass)
free(reply_chkpass);
reply_chkpass = rep;
break; break;
case CMD_ADDUSER: case CMD_ADDUSER:
if (last_adduser) STORELASTREPLY(adduser);
free(last_adduser);
last_adduser = buf;
buf = NULL;
if (reply_adduser)
free(reply_adduser);
reply_adduser = rep;
break; break;
case CMD_NEWPASS: case CMD_NEWPASS:
if (last_newpass) STORELASTREPLY(newpass);
free(last_newpass);
last_newpass = buf;
buf = NULL;
if (reply_newpass)
free(reply_newpass);
reply_newpass = rep;
break; break;
case CMD_NEWID: case CMD_NEWID:
if (last_newid) STORELASTREPLY(newid);
free(last_newid);
last_newid = buf;
buf = NULL;
if (reply_newid)
free(reply_newid);
reply_newid = rep;
break; break;
default: default:
free(rep); free(rep);
@ -9904,6 +10030,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
__func__, count, cmd); __func__, count, cmd);
break; break;
case CMD_AUTH: case CMD_AUTH:
case CMD_ADDRAUTH:
case CMD_POOLSTAT: case CMD_POOLSTAT:
case CMD_USERSTAT: case CMD_USERSTAT:
case CMD_BLOCK: case CMD_BLOCK:
@ -10411,11 +10538,8 @@ static void confirm_reload()
/* The last workinfo we should process /* The last workinfo we should process
* The reason for going past the last 'a' up to before * The reason for going past the last 'a' up to before
* the first 'n' is in case there were shares missed between them - * the first 'n' is in case there were shares missed between them -
* but that should only be the case with a code bug - so it checks that * but that should only be the case with a code bug -
* TODO: auto aging will clear 'n' sections inside the 'a's that * so it checks that */
* will always occur when ckpool restarts, since ckpool will never
* send workinfo age records for workinfo that's active at shutdown -
* Aging these can (for now) easily be done manually in psql */
if (dbstatus.newest_workinfoid_a > 0) { if (dbstatus.newest_workinfoid_a > 0) {
confirm_last_workinfoid = dbstatus.newest_workinfoid_a; confirm_last_workinfoid = dbstatus.newest_workinfoid_a;
last_reason = "newest aged"; last_reason = "newest aged";

Loading…
Cancel
Save