Merge branch 'master' of bitbucket.org:ckolivas/ckpool
This commit is contained in:
commit
6836f6fb7f
@ -110,6 +110,9 @@ h1 {margin-top: 20px; float:middle; font-size: 20px;}
|
||||
.dl {text-align: left; padding: 2px 8px;}
|
||||
.dr {text-align: right; padding: 2px 8px;}
|
||||
.dc {text-align: center; padding: 2px 8px;}
|
||||
.dls {text-align: left; padding: 2px 8px; text-decoration:line-through; font-weight:lighter; }
|
||||
.drs {text-align: right; padding: 2px 8px; text-decoration:line-through; font-weight:lighter; }
|
||||
.dcs {text-align: center; padding: 2px 8px; text-decoration:line-through; font-weight:lighter; }
|
||||
</style>\n";
|
||||
|
||||
$head .= '<meta name="robots" content="noindex">';
|
||||
|
||||
@ -12,7 +12,8 @@ function doblocks($data, $user)
|
||||
$pg .= "<td class=dl>Height</td>";
|
||||
$pg .= "<td class=dl>Who</td>";
|
||||
$pg .= "<td class=dr>Reward</td>";
|
||||
$pg .= "<td class=dr>When</td>";
|
||||
$pg .= "<td class=dc>When</td>";
|
||||
$pg .= "<td class=dr>Status</td>";
|
||||
$pg .= "</tr>\n";
|
||||
if ($ans['STATUS'] == 'ok')
|
||||
{
|
||||
@ -24,11 +25,19 @@ function doblocks($data, $user)
|
||||
else
|
||||
$row = 'odd';
|
||||
|
||||
$ex = '';
|
||||
$stat = $ans['status'.$i];
|
||||
if ($stat == 'Orphan')
|
||||
$ex = 's';
|
||||
if ($stat == '1-Confirm')
|
||||
$stat = 'Conf';
|
||||
|
||||
$pg .= "<tr class=$row>";
|
||||
$pg .= '<td class=dl>'.$ans['height'.$i].'</td>';
|
||||
$pg .= '<td class=dl>'.$ans['workername'.$i].'</td>';
|
||||
$pg .= '<td class=dr>'.btcfmt($ans['reward'.$i]).'</td>';
|
||||
$pg .= '<td class=dl>'.gmdate('Y-m-d H:i:s+00', $ans['createdate'.$i]).'</td>';
|
||||
$pg .= "<td class=dl$ex>".$ans['height'.$i].'</td>';
|
||||
$pg .= "<td class=dl$ex>".$ans['workername'.$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=dr$ex>".$stat.'</td>';
|
||||
$pg .= "</tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,7 +59,7 @@ function safepass($pass)
|
||||
return false;
|
||||
|
||||
# Invalid characters
|
||||
$p2 = preg_replace('/[^ -~]/', '', $pass);
|
||||
$p2 = preg_replace('/[\011]/', '', $pass);
|
||||
if ($p2 != $pass)
|
||||
return false;
|
||||
|
||||
@ -109,7 +109,7 @@ function show_reg($menu, $name, $u)
|
||||
{
|
||||
$ok = false;
|
||||
$data['error'] = "Password is unsafe - requires 6 or more characters, including<br>" .
|
||||
"at least one of each uppercase, lowercase and digits";
|
||||
"at least one of each uppercase, lowercase and digits, but not Tab";
|
||||
}
|
||||
elseif ($pass2 != $pass)
|
||||
{
|
||||
@ -118,11 +118,11 @@ function show_reg($menu, $name, $u)
|
||||
}
|
||||
|
||||
$orig = $user;
|
||||
$user = preg_replace('/[_\\.]/', '', $orig);
|
||||
$user = preg_replace('/[\._\/\011]/', '', $orig);
|
||||
if ($user != $orig)
|
||||
{
|
||||
$ok = false;
|
||||
$data['error'] = "Username cannot include '.' or '_'";
|
||||
$data['error'] = "Username cannot include '.', '_', '/' or Tab";
|
||||
$data['user'] = $user;
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ function doworker($data, $user)
|
||||
$pg .= "</tr>\n";
|
||||
if ($ans['STATUS'] == 'ok')
|
||||
{
|
||||
$thr = 0;
|
||||
$count = $ans['rows'];
|
||||
for ($i = 0; $i < $count; $i++)
|
||||
{
|
||||
@ -89,6 +90,7 @@ function doworker($data, $user)
|
||||
$uhr = '?GHs';
|
||||
else
|
||||
{
|
||||
$thr += $uhr;
|
||||
$uhr /= 10000000;
|
||||
if ($uhr < 0.01)
|
||||
$uhr = '0GHs';
|
||||
@ -104,6 +106,21 @@ function doworker($data, $user)
|
||||
$pg .= "</tr>\n";
|
||||
}
|
||||
}
|
||||
$thr /= 10000000;
|
||||
if ($thr < 0.01)
|
||||
$thr = '0GHs';
|
||||
else
|
||||
{
|
||||
if ($thr < 100000)
|
||||
$thr = number_format(round($thr)/100,2).'GHs';
|
||||
else
|
||||
$thr = number_format(round($thr/1000)/100,2).'THs';
|
||||
}
|
||||
if (($i % 2) == 0)
|
||||
$row = 'even';
|
||||
else
|
||||
$row = 'odd';
|
||||
$pg .= "<tr class=$row><td colspan=3 class=dl></td><td class=dr>$thr</td></tr>\n";
|
||||
$pg .= "</table>\n";
|
||||
|
||||
return $pg;
|
||||
|
||||
298
src/ckdb.c
298
src/ckdb.c
@ -47,7 +47,7 @@
|
||||
|
||||
#define DB_VLOCK "1"
|
||||
#define DB_VERSION "0.7"
|
||||
#define CKDB_VERSION DB_VERSION"-0.102"
|
||||
#define CKDB_VERSION DB_VERSION"-0.106"
|
||||
|
||||
#define WHERE_FFL " - from %s %s() line %d"
|
||||
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__
|
||||
@ -774,6 +774,7 @@ enum cmd_values {
|
||||
CMD_USERSTAT,
|
||||
CMD_BLOCK,
|
||||
CMD_BLOCKLIST,
|
||||
CMD_BLOCKSTATUS,
|
||||
CMD_NEWID,
|
||||
CMD_PAYMENTS,
|
||||
CMD_WORKERS,
|
||||
@ -1187,10 +1188,18 @@ typedef struct blocks {
|
||||
#define DATA_BLOCKS(_item) ((BLOCKS *)(_item->data))
|
||||
|
||||
#define BLOCKS_NEW 'n'
|
||||
#define BLOCKS_NEW_STR "n"
|
||||
#define BLOCKS_CONFIRM '1'
|
||||
#define BLOCKS_CONFIRM_STR "1"
|
||||
#define BLOCKS_42 'F'
|
||||
#define BLOCKS_42_STR "F"
|
||||
#define BLOCKS_ORPHAN 'O'
|
||||
#define BLOCKS_ORPHAN_STR "O"
|
||||
|
||||
static const char *blocks_new = "New";
|
||||
static const char *blocks_confirm = "1-Confirm";
|
||||
static const char *blocks_42 = "42-Confirm";
|
||||
static const char *blocks_orphan = "Orphan";
|
||||
static const char *blocks_unknown = "?Unknown?";
|
||||
|
||||
#define KANO -27972
|
||||
@ -3640,6 +3649,7 @@ static void auto_age_older(PGconn *conn, int64_t workinfoid, char *poolinstance,
|
||||
char *by, char *code, char *inet, tv_t *cd)
|
||||
{
|
||||
static int64_t last_attempted_id = -1;
|
||||
static int64_t prev_found = 0;
|
||||
static int repeat;
|
||||
|
||||
char min_buf[DATE_BUFSIZ], max_buf[DATE_BUFSIZ];
|
||||
@ -3648,37 +3658,51 @@ static void auto_age_older(PGconn *conn, int64_t workinfoid, char *poolinstance,
|
||||
tv_t ss_first_min, ss_last_max;
|
||||
tv_t ss_first, ss_last;
|
||||
int32_t wid_count;
|
||||
SHARESUMMARY sharesummary;
|
||||
K_TREE_CTX ctx[1];
|
||||
K_ITEM *ss_item;
|
||||
K_ITEM look, *ss_item;
|
||||
int64_t age_id, do_id, to_id;
|
||||
bool ok;
|
||||
bool ok, found;
|
||||
|
||||
LOGDEBUG("%s(): %"PRId64, __func__, workinfoid);
|
||||
LOGDEBUG("%s(): workinfoid=%"PRId64" prev=%"PRId64, __func__, workinfoid, prev_found);
|
||||
|
||||
age_id = prev_found;
|
||||
|
||||
// Find the oldest 'unaged' sharesummary < workinfoid and >= prev_found
|
||||
sharesummary.workinfoid = prev_found;
|
||||
sharesummary.userid = -1;
|
||||
sharesummary.workername[0] = '\0';
|
||||
look.data = (void *)(&sharesummary);
|
||||
ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &look,
|
||||
cmp_sharesummary_workinfoid, ctx);
|
||||
|
||||
ss_first_min.tv_sec = ss_first_min.tv_usec =
|
||||
ss_last_max.tv_sec = ss_last_max.tv_usec = 0;
|
||||
ss_count_tot = s_count_tot = s_diff_tot = 0;
|
||||
|
||||
age_id = 0;
|
||||
// Find the oldest 'unaged' sharesummary < workinfoid
|
||||
ss_item = first_in_ktree(sharesummary_workinfoid_root, ctx);
|
||||
found = false;
|
||||
while (ss_item && DATA_SHARESUMMARY(ss_item)->workinfoid < workinfoid) {
|
||||
if (DATA_SHARESUMMARY(ss_item)->complete[0] == SUMMARY_NEW) {
|
||||
age_id = DATA_SHARESUMMARY(ss_item)->workinfoid;
|
||||
prev_found = age_id;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
ss_item = next_in_ktree(ctx);
|
||||
}
|
||||
|
||||
LOGDEBUG("%s(): age_id=%"PRId64, __func__, age_id);
|
||||
/* Process all the consecutive sharesummaries that's aren't aged
|
||||
* This way we find each oldest 'batch' of sharesummaries that have
|
||||
* been missed and can report the range of data that was aged,
|
||||
* which would normally just be an approx 10min set of workinfoids
|
||||
* from the last time ckpool stopped
|
||||
* Each next group of unaged sharesummaries following this, will be
|
||||
* picked up by each next aging */
|
||||
if (age_id) {
|
||||
LOGDEBUG("%s(): age_id=%"PRId64" found=%d", __func__, age_id, found);
|
||||
// Don't repeat searching old items to avoid accessing their ram
|
||||
if (!found)
|
||||
prev_found = workinfoid;
|
||||
else {
|
||||
/* Process all the consecutive sharesummaries that's aren't aged
|
||||
* This way we find each oldest 'batch' of sharesummaries that have
|
||||
* been missed and can report the range of data that was aged,
|
||||
* which would normally just be an approx 10min set of workinfoids
|
||||
* from the last time ckpool stopped
|
||||
* Each next group of unaged sharesummaries following this, will be
|
||||
* picked up by each next aging */
|
||||
wid_count = 0;
|
||||
do_id = age_id;
|
||||
to_id = 0;
|
||||
@ -4851,11 +4875,14 @@ static const char *blocks_confirmed(char *confirmed)
|
||||
return blocks_new;
|
||||
case BLOCKS_CONFIRM:
|
||||
return blocks_confirm;
|
||||
case BLOCKS_42:
|
||||
return blocks_42;
|
||||
case BLOCKS_ORPHAN:
|
||||
return blocks_orphan;
|
||||
}
|
||||
return blocks_unknown;
|
||||
}
|
||||
|
||||
// TODO: determine how to handle orphan blocks after 1 confirm
|
||||
static bool blocks_add(PGconn *conn, char *height, char *blockhash,
|
||||
char *confirmed, char *workinfoid, char *username,
|
||||
char *workername, char *clientid, char *enonce1,
|
||||
@ -4875,6 +4902,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
|
||||
char *params[11 + HISTORYDATECOUNT];
|
||||
bool ok = false, update_old = false;
|
||||
int par = 0;
|
||||
char want = '?';
|
||||
int n;
|
||||
|
||||
LOGDEBUG("%s(): add", __func__);
|
||||
@ -4969,32 +4997,46 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash,
|
||||
goto unparam;
|
||||
}
|
||||
break;
|
||||
case BLOCKS_CONFIRM:
|
||||
if (!old_b_item) {
|
||||
k_add_head(blocks_free, b_item);
|
||||
case BLOCKS_ORPHAN:
|
||||
case BLOCKS_42:
|
||||
// These shouldn't be possible until startup completes
|
||||
if (!startup_complete) {
|
||||
K_WUNLOCK(blocks_free);
|
||||
tv_to_buf(cd, cd_buf, sizeof(cd_buf));
|
||||
LOGERR("%s(): Can't confirm a non-existent block, Status: "
|
||||
"%s, Block: %s/...%s/%s",
|
||||
LOGERR("%s(): Status: %s invalid during startup. "
|
||||
"Ignored: Block: %s/...%s/%s",
|
||||
__func__,
|
||||
blocks_confirmed(confirmed),
|
||||
height, blk_dsp, cd_buf);
|
||||
goto flail;
|
||||
}
|
||||
want = BLOCKS_CONFIRM;
|
||||
case BLOCKS_CONFIRM:
|
||||
if (!old_b_item) {
|
||||
K_WUNLOCK(blocks_free);
|
||||
tv_to_buf(cd, cd_buf, sizeof(cd_buf));
|
||||
LOGERR("%s(): Can't %s a non-existent Block: %s/...%s/%s",
|
||||
__func__, blocks_confirmed(confirmed),
|
||||
height, blk_dsp, cd_buf);
|
||||
return false;
|
||||
goto flail;
|
||||
}
|
||||
/* This will also treat an unrecognised 'confirmed' as a
|
||||
* duplicate since they shouldn't exist anyway */
|
||||
if (DATA_BLOCKS(old_b_item)->confirmed[0] != BLOCKS_NEW) {
|
||||
if (confirmed[0] == BLOCKS_CONFIRM)
|
||||
want = BLOCKS_NEW;
|
||||
if (DATA_BLOCKS(old_b_item)->confirmed[0] != want) {
|
||||
k_add_head(blocks_free, b_item);
|
||||
K_WUNLOCK(blocks_free);
|
||||
if (!igndup || DATA_BLOCKS(old_b_item)->confirmed[0] != BLOCKS_CONFIRM) {
|
||||
// No mismatch messages during startup
|
||||
if (!startup_complete) {
|
||||
tv_to_buf(cd, cd_buf, sizeof(cd_buf));
|
||||
LOGERR("%s(): Duplicate (%s) blocks ignored, Status: "
|
||||
"%s, Block: %s/...%s/%s",
|
||||
LOGERR("%s(): Request Status: %s requires Status: %s. "
|
||||
"Ignored: Status: %s, Block: %s/...%s/%s",
|
||||
__func__,
|
||||
blocks_confirmed(DATA_BLOCKS(old_b_item)->confirmed),
|
||||
blocks_confirmed(confirmed),
|
||||
blocks_confirmed(BLOCKS_CONFIRM_STR),
|
||||
blocks_confirmed(DATA_BLOCKS(old_b_item)->confirmed),
|
||||
height, blk_dsp, cd_buf);
|
||||
}
|
||||
return true;
|
||||
goto flail;
|
||||
}
|
||||
K_WUNLOCK(blocks_free);
|
||||
|
||||
@ -5102,44 +5144,55 @@ flail:
|
||||
K_WUNLOCK(blocks_free);
|
||||
|
||||
if (ok) {
|
||||
char pct[16] = "?";
|
||||
char est[16] = "";
|
||||
K_ITEM *w_item;
|
||||
char tmp[256];
|
||||
bool blk;
|
||||
|
||||
if (confirmed[0] != BLOCKS_NEW)
|
||||
tmp[0] = '\0';
|
||||
else {
|
||||
char pct[16] = "?";
|
||||
char est[16] = "";
|
||||
K_ITEM *w_item;
|
||||
|
||||
w_item = find_workinfo(DATA_BLOCKS(b_item)->workinfoid);
|
||||
if (w_item) {
|
||||
char wdiffbin[TXT_SML+1];
|
||||
double wdiff;
|
||||
hex2bin(wdiffbin, DATA_WORKINFO(w_item)->bits, 4);
|
||||
wdiff = diff_from_nbits(wdiffbin);
|
||||
if (wdiff > 0.0) {
|
||||
snprintf(pct, sizeof(pct), "%.2f",
|
||||
100.0 * pool.diffacc / wdiff);
|
||||
switch (confirmed[0]) {
|
||||
case BLOCKS_NEW:
|
||||
blk = true;
|
||||
tmp[0] = '\0';
|
||||
break;
|
||||
case BLOCKS_CONFIRM:
|
||||
blk = true;
|
||||
w_item = find_workinfo(DATA_BLOCKS(b_item)->workinfoid);
|
||||
if (w_item) {
|
||||
char wdiffbin[TXT_SML+1];
|
||||
double wdiff;
|
||||
hex2bin(wdiffbin, DATA_WORKINFO(w_item)->bits, 4);
|
||||
wdiff = diff_from_nbits(wdiffbin);
|
||||
if (wdiff > 0.0) {
|
||||
snprintf(pct, sizeof(pct), "%.2f",
|
||||
100.0 * pool.diffacc / wdiff);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pool.diffacc >= 1000000.0) {
|
||||
suffix_string(pool.diffacc, est, sizeof(est)-1, 1);
|
||||
strcat(est, " ");
|
||||
}
|
||||
tv_to_buf(&(DATA_BLOCKS(b_item)->createdate), cd_buf, sizeof(cd_buf));
|
||||
snprintf(tmp, sizeof(tmp),
|
||||
" Reward: %f, User: %s, Worker: %s, ShareEst: %.1f %s%s%% UTC:%s",
|
||||
BTC_TO_D(DATA_BLOCKS(b_item)->reward),
|
||||
username, workername, pool.diffacc, est, pct, cd_buf);
|
||||
if (pool.workinfoid < DATA_BLOCKS(b_item)->workinfoid) {
|
||||
pool.workinfoid = DATA_BLOCKS(b_item)->workinfoid;
|
||||
pool.diffacc = pool.differr =
|
||||
pool.best_sdiff = 0.0;
|
||||
}
|
||||
if (pool.diffacc >= 1000000.0) {
|
||||
suffix_string(pool.diffacc, est, sizeof(est)-1, 1);
|
||||
strcat(est, " ");
|
||||
}
|
||||
tv_to_buf(&(DATA_BLOCKS(b_item)->createdate), cd_buf, sizeof(cd_buf));
|
||||
snprintf(tmp, sizeof(tmp),
|
||||
" Reward: %f, User: %s, Worker: %s, ShareEst: %.1f %s%s%% UTC:%s",
|
||||
BTC_TO_D(DATA_BLOCKS(b_item)->reward),
|
||||
username, workername, pool.diffacc, est, pct, cd_buf);
|
||||
if (pool.workinfoid < DATA_BLOCKS(b_item)->workinfoid) {
|
||||
pool.workinfoid = DATA_BLOCKS(b_item)->workinfoid;
|
||||
pool.diffacc = pool.differr =
|
||||
pool.best_sdiff = 0.0;
|
||||
}
|
||||
break;
|
||||
case BLOCKS_ORPHAN:
|
||||
case BLOCKS_42:
|
||||
default:
|
||||
blk = false;
|
||||
tmp[0] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
LOGWARNING("%s(): BLOCK! Status: %s, Block: %s/...%s%s",
|
||||
__func__,
|
||||
LOGWARNING("%s(): %sStatus: %s, Block: %s/...%s%s",
|
||||
__func__, blk ? "BLOCK! " : "",
|
||||
blocks_confirmed(confirmed),
|
||||
height, blk_dsp, tmp);
|
||||
}
|
||||
@ -7220,20 +7273,18 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
char *buf;
|
||||
size_t len, off;
|
||||
int rows;
|
||||
int32_t height;
|
||||
|
||||
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
|
||||
|
||||
b_item = last_in_ktree(blocks_root, ctx);
|
||||
APPEND_REALLOC_INIT(buf, off, len);
|
||||
APPEND_REALLOC(buf, off, len, "ok.");
|
||||
rows = 0;
|
||||
height = -1;
|
||||
K_RLOCK(blocks_free);
|
||||
b_item = last_in_ktree(blocks_root, ctx);
|
||||
while (b_item && rows < 42) {
|
||||
if (height != DATA_BLOCKS(b_item)->height) {
|
||||
height = DATA_BLOCKS(b_item)->height;
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "height%d=%d%c", rows, height, FLDSEP);
|
||||
if (CURRENT(&(DATA_BLOCKS(b_item)->expirydate))) {
|
||||
int_to_buf(DATA_BLOCKS(b_item)->height, reply, sizeof(reply));
|
||||
snprintf(tmp, sizeof(tmp), "height%d=%s%c", rows, reply, FLDSEP);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
str_to_buf(DATA_BLOCKS(b_item)->blockhash, reply, sizeof(reply));
|
||||
@ -7266,6 +7317,7 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
}
|
||||
b_item = prev_in_ktree(ctx);
|
||||
}
|
||||
K_RUNLOCK(blocks_free);
|
||||
snprintf(tmp, sizeof(tmp), "rows=%d", rows);
|
||||
APPEND_REALLOC(buf, off, len, tmp);
|
||||
|
||||
@ -7273,6 +7325,90 @@ static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
return buf;
|
||||
}
|
||||
|
||||
static char *cmd_blockstatus(__maybe_unused PGconn *conn, char *cmd, char *id,
|
||||
tv_t *now, char *by, char *code, char *inet,
|
||||
__maybe_unused tv_t *cd, K_TREE *trf_root)
|
||||
{
|
||||
K_ITEM *i_height, *i_blockhash, *i_action;
|
||||
char reply[1024] = "";
|
||||
size_t siz = sizeof(reply);
|
||||
K_ITEM *b_item;
|
||||
BLOCKS *blocks;
|
||||
int32_t height;
|
||||
char *action;
|
||||
bool ok = false;
|
||||
|
||||
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
|
||||
|
||||
i_height = require_name(trf_root, "height", 1, NULL, reply, siz);
|
||||
if (!i_height)
|
||||
return strdup(reply);
|
||||
|
||||
TXT_TO_INT("height", DATA_TRANSFER(i_height)->data, height);
|
||||
|
||||
i_blockhash = require_name(trf_root, "blockhash", 1, NULL, reply, siz);
|
||||
if (!i_blockhash)
|
||||
return strdup(reply);
|
||||
|
||||
i_action = require_name(trf_root, "action", 1, NULL, reply, siz);
|
||||
if (!i_action)
|
||||
return strdup(reply);
|
||||
|
||||
action = DATA_TRANSFER(i_action)->data;
|
||||
|
||||
K_RLOCK(blocks_free);
|
||||
b_item = find_blocks(height, DATA_TRANSFER(i_blockhash)->data);
|
||||
K_RUNLOCK(blocks_free);
|
||||
|
||||
if (!b_item) {
|
||||
snprintf(reply, siz, "ERR.unknown block");
|
||||
LOGERR("%s.%s", id, reply);
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
blocks = DATA_BLOCKS(b_item);
|
||||
|
||||
if (strcasecmp(action, "orphan") == 0) {
|
||||
switch (blocks->confirmed[0]) {
|
||||
case BLOCKS_NEW:
|
||||
case BLOCKS_CONFIRM:
|
||||
ok = blocks_add(conn, DATA_TRANSFER(i_height)->data,
|
||||
blocks->blockhash,
|
||||
BLOCKS_ORPHAN_STR,
|
||||
EMPTY, EMPTY, EMPTY, EMPTY,
|
||||
EMPTY, EMPTY, EMPTY, EMPTY,
|
||||
by, code, inet, now, false, id,
|
||||
trf_root);
|
||||
if (!ok) {
|
||||
snprintf(reply, siz,
|
||||
"DBE.action '%s'",
|
||||
action);
|
||||
LOGERR("%s.%s", id, reply);
|
||||
return strdup(reply);
|
||||
}
|
||||
// TODO: reset the share counter?
|
||||
break;
|
||||
default:
|
||||
snprintf(reply, siz,
|
||||
"ERR.invalid action '%.*s%s' for block state '%s'",
|
||||
CMD_SIZ, action,
|
||||
(strlen(action) > CMD_SIZ) ? "..." : "",
|
||||
blocks_confirmed(blocks->confirmed));
|
||||
LOGERR("%s.%s", id, reply);
|
||||
return strdup(reply);
|
||||
}
|
||||
} else {
|
||||
snprintf(reply, siz, "ERR.unknown action '%s'",
|
||||
DATA_TRANSFER(i_action)->data);
|
||||
LOGERR("%s.%s", id, reply);
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
snprintf(reply, siz, "ok.%s %d", DATA_TRANSFER(i_action)->data, height);
|
||||
LOGDEBUG("%s.%s", id, reply);
|
||||
return strdup(reply);
|
||||
}
|
||||
|
||||
static char *cmd_newid(PGconn *conn, char *cmd, char *id, tv_t *now, char *by,
|
||||
char *code, char *inet, __maybe_unused tv_t *cd,
|
||||
K_TREE *trf_root)
|
||||
@ -8835,6 +8971,7 @@ static struct CMDS {
|
||||
{ CMD_USERSTAT, "userstats", false, true, cmd_userstats, ACCESS_POOL },
|
||||
{ CMD_BLOCK, "block", false, true, cmd_blocks, ACCESS_POOL },
|
||||
{ CMD_BLOCKLIST,"blocklist", false, false, cmd_blocklist, ACCESS_WEB },
|
||||
{ CMD_BLOCKSTATUS,"blockstatus",false, false, cmd_blockstatus,ACCESS_WEB },
|
||||
{ CMD_NEWID, "newid", false, false, cmd_newid, ACCESS_SYSTEM },
|
||||
{ CMD_PAYMENTS, "payments", false, false, cmd_payments, ACCESS_WEB },
|
||||
{ CMD_WORKERS, "workers", false, false, cmd_workers, ACCESS_WEB },
|
||||
@ -9581,6 +9718,7 @@ static void *socketer(__maybe_unused void *arg)
|
||||
case CMD_PAYMENTS:
|
||||
case CMD_PPLNS:
|
||||
case CMD_DSP:
|
||||
case CMD_BLOCKSTATUS:
|
||||
if (!startup_complete) {
|
||||
snprintf(reply, sizeof(reply),
|
||||
"%s.%ld.loading.%s",
|
||||
@ -9685,8 +9823,11 @@ static void *socketer(__maybe_unused void *arg)
|
||||
}
|
||||
K_WLOCK(transfer_free);
|
||||
k_list_transfer_to_head(trf_store, transfer_free);
|
||||
K_WUNLOCK(transfer_free);
|
||||
trf_store = k_free_store(trf_store);
|
||||
if (transfer_free->count == transfer_free->total &&
|
||||
transfer_free->total > ALLOC_TRANSFER * 64)
|
||||
k_cull_list(transfer_free);
|
||||
K_WUNLOCK(transfer_free);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9750,6 +9891,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
|
||||
case CMD_NEWPASS:
|
||||
case CMD_CHKPASS:
|
||||
case CMD_BLOCKLIST:
|
||||
case CMD_BLOCKSTATUS:
|
||||
case CMD_NEWID:
|
||||
case CMD_PAYMENTS:
|
||||
case CMD_WORKERS:
|
||||
@ -10035,7 +10177,8 @@ static void *listener(void *arg)
|
||||
startup_complete = true;
|
||||
}
|
||||
|
||||
conn = dbconnect();
|
||||
if (!everyone_die)
|
||||
conn = dbconnect();
|
||||
|
||||
// Process queued work
|
||||
while (!everyone_die) {
|
||||
@ -10060,7 +10203,8 @@ static void *listener(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
PQfinish(conn);
|
||||
if (conn)
|
||||
PQfinish(conn);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@ -10601,6 +10745,7 @@ static struct option long_options[] = {
|
||||
{ "name", required_argument, 0, 'n' },
|
||||
{ "dbpass", required_argument, 0, 'p' },
|
||||
{ "ckpool-logdir", required_argument, 0, 'r' },
|
||||
{ "logdir", required_argument, 0, 'R' },
|
||||
{ "sockdir", required_argument, 0, 's' },
|
||||
{ "dbuser", required_argument, 0, 'u' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
@ -10634,7 +10779,7 @@ int main(int argc, char **argv)
|
||||
memset(&ckp, 0, sizeof(ckp));
|
||||
ckp.loglevel = LOG_NOTICE;
|
||||
|
||||
while ((c = getopt_long(argc, argv, "c:d:hkl:n:p:r:s:u:vyY:", long_options, &i)) != -1) {
|
||||
while ((c = getopt_long(argc, argv, "c:d:hkl:n:p:r:R:s:u:vyY:", long_options, &i)) != -1) {
|
||||
switch(c) {
|
||||
case 'c':
|
||||
ckp.config = strdup(optarg);
|
||||
@ -10686,6 +10831,9 @@ int main(int argc, char **argv)
|
||||
case 'r':
|
||||
restorefrom = strdup(optarg);
|
||||
break;
|
||||
case 'R':
|
||||
ckp.logdir = strdup(optarg);
|
||||
break;
|
||||
case 's':
|
||||
ckp.socket_dir = strdup(optarg);
|
||||
break;
|
||||
|
||||
33
src/klist.c
33
src/klist.c
@ -378,3 +378,36 @@ K_STORE *_k_free_store(K_STORE *store, KLIST_FFL_ARGS)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Must be locked and none in use and/or unlinked
|
||||
void _k_cull_list(K_LIST *list, KLIST_FFL_ARGS)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (list->is_store) {
|
||||
quithere(1, "List %s can't %s() a store" KLIST_FFL,
|
||||
list->name, __func__, KLIST_FFL_PASS);
|
||||
}
|
||||
|
||||
if (list->count != list->total) {
|
||||
quithere(1, "List %s can't %s() a list in use" KLIST_FFL,
|
||||
list->name, __func__, KLIST_FFL_PASS);
|
||||
}
|
||||
|
||||
for (i = 0; i < list->item_mem_count; i++)
|
||||
free(list->item_memory[i]);
|
||||
free(list->item_memory);
|
||||
list->item_memory = NULL;
|
||||
list->item_mem_count = 0;
|
||||
|
||||
for (i = 0; i < list->data_mem_count; i++)
|
||||
free(list->data_memory[i]);
|
||||
free(list->data_memory);
|
||||
list->data_memory = NULL;
|
||||
list->data_mem_count = 0;
|
||||
|
||||
list->total = list->count = list->count_up = 0;
|
||||
list->head = list->tail = NULL;
|
||||
|
||||
k_alloc_items(list, KLIST_FFL_PASS);
|
||||
}
|
||||
|
||||
@ -94,5 +94,7 @@ extern K_LIST *_k_free_list(K_LIST *list, KLIST_FFL_ARGS);
|
||||
#define k_free_list(_list) _k_free_list(_list, KLIST_FFL_HERE)
|
||||
extern K_STORE *_k_free_store(K_STORE *store, KLIST_FFL_ARGS);
|
||||
#define k_free_store(_store) _k_free_store(_store, KLIST_FFL_HERE)
|
||||
extern void _k_cull_list(K_LIST *list, KLIST_FFL_ARGS);
|
||||
#define k_cull_list(_list) _k_cull_list(_list, KLIST_FFL_HERE)
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user