Browse Source

ckdb - add cmd to accept blocks

master
kanoi 11 years ago
parent
commit
6ee763a5f8
  1. 481
      src/ckdb.c

481
src/ckdb.c

@ -53,6 +53,7 @@
#define coinbase1height(_cb1) _coinbase1height(_cb1, WHERE_FFL_HERE) #define coinbase1height(_cb1) _coinbase1height(_cb1, WHERE_FFL_HERE)
#define cmp_height(_cb1a, _cb1b) _cmp_height(_cb1a, _cb1b, WHERE_FFL_HERE) #define cmp_height(_cb1a, _cb1b) _cmp_height(_cb1a, _cb1b, WHERE_FFL_HERE)
static char *EMPTY = "";
static char *db_user; static char *db_user;
static char *db_pass; static char *db_pass;
@ -635,7 +636,7 @@ static K_STORE *optioncontrol_store;
*/ */
// TODO: aging/discarding workinfo,shares // TODO: aging/discarding workinfo,shares
// WORKINFO id.sharelog.json={...} // WORKINFO workinfo.id.json={...}
typedef struct workinfo { typedef struct workinfo {
int64_t workinfoid; int64_t workinfoid;
char poolinstance[TXT_BIG+1]; char poolinstance[TXT_BIG+1];
@ -667,7 +668,7 @@ static K_ITEM *workinfo_current;
// TODO: have it's own memory? // TODO: have it's own memory?
static tv_t *last_bc; static tv_t *last_bc;
// SHARES id.sharelog.json={...} // SHARES shares.id.json={...}
typedef struct shares { typedef struct shares {
int64_t workinfoid; int64_t workinfoid;
int64_t userid; int64_t userid;
@ -692,7 +693,7 @@ static K_TREE *shares_root;
static K_LIST *shares_list; static K_LIST *shares_list;
static K_STORE *shares_store; static K_STORE *shares_store;
// SHAREERRORS id.sharelog.json={...} // SHAREERRORS shareerrors.id.json={...}
typedef struct shareerrorss { typedef struct shareerrorss {
int64_t workinfoid; int64_t workinfoid;
int64_t userid; int64_t userid;
@ -771,8 +772,9 @@ typedef struct blocksummary {
static K_TREE *blocksummary_root; static K_TREE *blocksummary_root;
static K_LIST *blocksummary_list; static K_LIST *blocksummary_list;
static K_STORE *blocksummary_store; static K_STORE *blocksummary_store;
*/
// BLOCKS // BLOCKS block.id.json={...}
typedef struct blocks { typedef struct blocks {
int32_t height; int32_t height;
char blockhash[TXT_BIG+1]; char blockhash[TXT_BIG+1];
@ -788,14 +790,18 @@ typedef struct blocks {
HISTORYDATECONTROLFIELDS; HISTORYDATECONTROLFIELDS;
} BLOCKS; } BLOCKS;
#define ALLOC_BLOCKS 10000 #define ALLOC_BLOCKS 100
#define LIMIT_BLOCKS 0 #define LIMIT_BLOCKS 0
#define DATA_BLOCKS ((BLOCKS *)(_item->data)) #define DATA_BLOCKS(_item) ((BLOCKS *)(_item->data))
#define BLOCKS_NEW 'n'
#define BLOCKS_CONFIRM '1'
static K_TREE *blocks_root; static K_TREE *blocks_root;
static K_LIST *blocks_list; static K_LIST *blocks_list;
static K_STORE *blocks_store; static K_STORE *blocks_store;
/*
// MININGPAYOUTS // MININGPAYOUTS
typedef struct miningpayouts { typedef struct miningpayouts {
int64_t miningpayoutid; int64_t miningpayoutid;
@ -831,7 +837,7 @@ static K_LIST *eventlog_list;
static K_STORE *eventlog_store; static K_STORE *eventlog_store;
*/ */
// AUTHS // AUTHS authorise.id.json={...}
typedef struct auths { typedef struct auths {
int64_t authid; int64_t authid;
int64_t userid; int64_t userid;
@ -850,10 +856,7 @@ static K_TREE *auths_root;
static K_LIST *auths_list; static K_LIST *auths_list;
static K_STORE *auths_store; static K_STORE *auths_store;
// POOLSTATS // POOLSTATS poolstats.id.json={...}
// TODO: get every 1m: pool sending it
// so web page is kept up to date
// Store every > 9.5m? // Store every > 9.5m?
#define STATS_PER (9.5*60.0) #define STATS_PER (9.5*60.0)
@ -877,7 +880,7 @@ static K_TREE *poolstats_root;
static K_LIST *poolstats_list; static K_LIST *poolstats_list;
static K_STORE *poolstats_store; static K_STORE *poolstats_store;
// USERSTATS // USERSTATS userstats.id.json={...}
// Pool sends each user (staggered) once per 10m // Pool sends each user (staggered) once per 10m
// TODO: When to discard? // TODO: When to discard?
typedef struct userstats { typedef struct userstats {
@ -1884,7 +1887,6 @@ static bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault,
rescode = PQresultStatus(res); rescode = PQresultStatus(res);
if (!PGOK(rescode)) { if (!PGOK(rescode)) {
PGLOGERR("Begin", rescode, conn); PGLOGERR("Begin", rescode, conn);
PQclear(res);
goto unparam; goto unparam;
} }
PQclear(res); PQclear(res);
@ -1893,9 +1895,8 @@ static bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault,
rescode = PQresultStatus(res); rescode = PQresultStatus(res);
PQclear(res); PQclear(res);
if (!PGOK(rescode)) { if (!PGOK(rescode)) {
PGLOGERR("Insert", rescode, conn); PGLOGERR("Update", rescode, conn);
res = PQexec(conn, "Rollback"); res = PQexec(conn, "Rollback");
PQclear(res);
goto unparam; goto unparam;
} }
@ -1929,16 +1930,15 @@ static bool workers_update(PGconn *conn, K_ITEM *item, char *difficultydefault,
if (!PGOK(rescode)) { if (!PGOK(rescode)) {
PGLOGERR("Insert", rescode, conn); PGLOGERR("Insert", rescode, conn);
res = PQexec(conn, "Rollback"); res = PQexec(conn, "Rollback");
PQclear(res);
goto unparam; goto unparam;
} }
res = PQexec(conn, "Commit"); res = PQexec(conn, "Commit");
PQclear(res);
} }
ok = true; ok = true;
unparam: unparam:
PQclear(res);
for (n = 0; n < par; n++) for (n = 0; n < par; n++)
free(params[n]); free(params[n]);
@ -2260,8 +2260,8 @@ static double cmp_workinfo(K_ITEM *a, K_ITEM *b)
double c = (double)(DATA_WORKINFO(a)->workinfoid) - double c = (double)(DATA_WORKINFO(a)->workinfoid) -
(double)(DATA_WORKINFO(b)->workinfoid); (double)(DATA_WORKINFO(b)->workinfoid);
if (c == 0) { if (c == 0) {
c = tvdiff(&(DATA_WORKINFO(b)->expirydate), c = tvdiff(&(DATA_WORKINFO(a)->expirydate),
&(DATA_WORKINFO(a)->expirydate)); &(DATA_WORKINFO(b)->expirydate));
} }
return c; return c;
} }
@ -2305,8 +2305,8 @@ static double cmp_workinfo_height(K_ITEM *a, K_ITEM *b)
double c = cmp_height(DATA_WORKINFO(a)->coinbase1, double c = cmp_height(DATA_WORKINFO(a)->coinbase1,
DATA_WORKINFO(b)->coinbase1); DATA_WORKINFO(b)->coinbase1);
if (c == 0) { if (c == 0) {
c = tvdiff(&(DATA_WORKINFO(b)->createdate), c = tvdiff(&(DATA_WORKINFO(a)->createdate),
&(DATA_WORKINFO(a)->createdate)); &(DATA_WORKINFO(b)->createdate));
} }
return c; return c;
} }
@ -2745,6 +2745,317 @@ static bool shareerrors_fill()
return true; return true;
} }
// order by height asc,blockhash asc,expirydate desc
static double cmp_blocks(K_ITEM *a, K_ITEM *b)
{
double c = DATA_BLOCKS(a)->height - DATA_BLOCKS(b)->height;
if (c == 0) {
c = strcmp(DATA_BLOCKS(a)->blockhash,
DATA_BLOCKS(b)->blockhash);
if (c == 0) {
c = tvdiff(&(DATA_BLOCKS(a)->expirydate),
&(DATA_BLOCKS(b)->expirydate));
}
}
return c;
}
/* unused
static K_ITEM *find_blocks(int32_t height, char *blockhash)
{
BLOCKS blocks;
K_TREE_CTX ctx[1];
K_ITEM look;
blocks.height = height;
STRNCPY(blocks.blockhash, blockhash);
blocks.expirydate.tv_sec = default_expiry.tv_sec;
blocks.expirydate.tv_usec = default_expiry.tv_usec;
look.data = (void *)(&blocks);
return find_in_ktree(blocks_root, &look, cmp_blocks, ctx);
}
*/
static bool blocks_add(PGconn *conn, char *height, char *blockhash,
char *workinfoid, char *username, char *workername,
char *clientid, char *enonce1, char *nonce2,
char *nonce, char *reward, char *confirmed,
tv_t *now, char *by, char *code, char *inet)
{
ExecStatusType rescode;
PGresult *res;
K_ITEM *item, *u_item;
BLOCKS *row;
char *upd, *ins;
char *params[11 + HISTORYDATECOUNT];
bool ok = false;
int par;
int n;
LOGDEBUG("%s(): add", __func__);
K_WLOCK(blocks_list);
item = k_unlink_head(blocks_list);
K_WUNLOCK(blocks_list);
row = DATA_BLOCKS(item);
TXT_TO_INT("height", height, row->height);
STRNCPY(row->blockhash, blockhash);
STRNCPY(row->confirmed, confirmed);
HISTORYDATEINIT(row, now, by, code, inet);
switch (confirmed[0]) {
case BLOCKS_NEW:
u_item = find_users(username);
if (!u_item)
goto unparam;
TXT_TO_BIGINT("workinfoid", workinfoid, row->workinfoid);
STRNCPY(row->workername, workername);
TXT_TO_INT("clientid", clientid, row->clientid);
STRNCPY(row->enonce1, enonce1);
STRNCPY(row->nonce2, nonce2);
STRNCPY(row->nonce, nonce);
TXT_TO_BIGINT("reward", reward, row->reward);
HISTORYDATETRANSFER(row);
par = 0;
params[par++] = int_to_buf(row->height, NULL, 0);
params[par++] = str_to_buf(row->blockhash, NULL, 0);
params[par++] = bigint_to_buf(row->workinfoid, NULL, 0);
params[par++] = bigint_to_buf(row->userid, NULL, 0);
params[par++] = str_to_buf(row->workername, 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->nonce2, NULL, 0);
params[par++] = str_to_buf(row->nonce, NULL, 0);
params[par++] = bigint_to_buf(row->reward, NULL, 0);
params[par++] = str_to_buf(row->confirmed, NULL, 0);
HISTORYDATEPARAMS(params, par, row);
PARCHK(par, params);
ins = "insert into blocks "
"(height,blockhash,workinfoid,userid,workername,"
"clientid,enonce1,nonce2,nonce,reward,confirmed"
HISTORYDATECONTROL ") values (" PQPARAM16 ")";
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0);
rescode = PQresultStatus(res);
if (!PGOK(rescode)) {
PGLOGERR("Insert", rescode, conn);
goto unparam;
}
break;
case BLOCKS_CONFIRM:
upd = "update blocks set expirydate=$1 where blockhash=$2 and expirydate=$3";
par = 0;
params[par++] = tv_to_buf(now, NULL, 0);
params[par++] = str_to_buf(row->blockhash, NULL, 0);
params[par++] = tv_to_buf((tv_t *)&default_expiry, NULL, 0);
// Not the full size of params[] so no PARCHK()
res = PQexec(conn, "Begin");
rescode = PQresultStatus(res);
if (!PGOK(rescode)) {
PGLOGERR("Begin", rescode, conn);
goto unparam;
}
PQclear(res);
res = PQexecParams(conn, upd, par, NULL, (const char **)params, NULL, NULL, 0);
rescode = PQresultStatus(res);
PQclear(res);
if (!PGOK(rescode)) {
PGLOGERR("Update", rescode, conn);
res = PQexec(conn, "Rollback");
goto unparam;
}
for (n = 0; n < par; n++)
free(params[n]);
par = 0;
params[par++] = int_to_buf(row->height, NULL, 0);
params[par++] = str_to_buf(row->blockhash, NULL, 0);
params[par++] = str_to_buf(row->confirmed, NULL, 0);
HISTORYDATEPARAMS(params, par, row);
ins = "insert into blocks "
"(height,blockhash,workinfoid,userid,workername,"
"clientid,enonce1,nonce2,nonce,reward,confirmed"
HISTORYDATECONTROL ") values (" PQPARAM16 ")";
res = PQexecParams(conn, ins, par, NULL, (const char **)params, NULL, NULL, 0);
rescode = PQresultStatus(res);
PQclear(res);
if (!PGOK(rescode)) {
PGLOGERR("Insert", rescode, conn);
res = PQexec(conn, "Rollback");
goto unparam;
}
res = PQexec(conn, "Commit");
break;
}
ok = true;
unparam:
PQclear(res);
for (n = 0; n < par; n++)
free(params[n]);
K_WLOCK(blocks_list);
if (!ok)
k_add_head(blocks_list, item);
else {
blocks_root = add_to_ktree(blocks_root, item, cmp_blocks);
k_add_head(blocks_store, item);
}
K_WUNLOCK(blocks_list);
return ok;
}
static bool blocks_fill(PGconn *conn)
{
ExecStatusType rescode;
PGresult *res;
K_ITEM *item;
int n, i;
BLOCKS *row;
char *params[1];
int par;
char *field;
char *sel;
int fields = 11;
bool ok;
LOGDEBUG("%s(): select", __func__);
sel = "select "
"height,blockhash,workinfoid,userid,workername,"
"clientid,enonce1,nonce2,nonce,reward,confirmed"
HISTORYDATECONTROL
" from blocks where expirydate=$1";
par = 0;
params[par++] = tv_to_buf((tv_t *)(&default_expiry), NULL, 0);
PARCHK(par, params);
res = PQexecParams(conn, sel, par, NULL, (const char **)params, NULL, NULL, 0);
rescode = PQresultStatus(res);
if (!PGOK(rescode)) {
PGLOGERR("Select", rescode, conn);
PQclear(res);
return false;
}
n = PQnfields(res);
if (n != (fields + HISTORYDATECOUNT)) {
LOGERR("%s(): Invalid field count - should be %d, but is %d",
__func__, fields + HISTORYDATECOUNT, n);
PQclear(res);
return false;
}
n = PQntuples(res);
LOGDEBUG("%s(): tree build count %d", __func__, n);
ok = true;
K_WLOCK(blocks_list);
for (i = 0; i < n; i++) {
item = k_unlink_head(blocks_list);
row = DATA_BLOCKS(item);
PQ_GET_FLD(res, i, "height", field, ok);
if (!ok)
break;
TXT_TO_INT("height", field, row->height);
PQ_GET_FLD(res, i, "blockhash", field, ok);
if (!ok)
break;
TXT_TO_STR("blockhash", field, row->blockhash);
PQ_GET_FLD(res, i, "workinfoid", field, ok);
if (!ok)
break;
TXT_TO_BIGINT("workinfoid", field, row->workinfoid);
PQ_GET_FLD(res, i, "userid", field, ok);
if (!ok)
break;
TXT_TO_BIGINT("userid", field, row->userid);
PQ_GET_FLD(res, i, "workername", field, ok);
if (!ok)
break;
TXT_TO_BLOB("workername", field, row->workername);
PQ_GET_FLD(res, i, "clientid", field, ok);
if (!ok)
break;
TXT_TO_INT("clientid", field, row->clientid);
PQ_GET_FLD(res, i, "enonce1", field, ok);
if (!ok)
break;
TXT_TO_STR("enonce1", field, row->enonce1);
PQ_GET_FLD(res, i, "nonce2", field, ok);
if (!ok)
break;
TXT_TO_STR("nonce2", field, row->nonce2);
PQ_GET_FLD(res, i, "nonce", field, ok);
if (!ok)
break;
TXT_TO_STR("nonce", field, row->nonce);
PQ_GET_FLD(res, i, "reward", field, ok);
if (!ok)
break;
TXT_TO_BIGINT("reward", field, row->reward);
PQ_GET_FLD(res, i, "confirmed", field, ok);
if (!ok)
break;
TXT_TO_STR("confirmed", field, row->confirmed);
HISTORYDATEFLDS(res, i, row, ok);
if (!ok)
break;
blocks_root = add_to_ktree(blocks_root, item, cmp_blocks);
k_add_head(blocks_store, item);
}
if (!ok)
k_add_head(blocks_list, item);
K_WUNLOCK(blocks_list);
PQclear(res);
if (ok)
LOGDEBUG("%s(): built", __func__);
return true;
}
void blocks_reload()
{
PGconn *conn = dbconnect();
K_WLOCK(blocks_list);
blocks_root = free_ktree(blocks_root, NULL);
k_list_transfer_to_head(blocks_store, blocks_list);
K_WUNLOCK(blocks_list);
blocks_fill(conn);
PQfinish(conn);
}
// order by userid asc,createdate asc,authid asc,expirydate desc // order by userid asc,createdate asc,authid asc,expirydate desc
static double cmp_auths(K_ITEM *a, K_ITEM *b) static double cmp_auths(K_ITEM *a, K_ITEM *b)
{ {
@ -3452,6 +3763,10 @@ static void setup_data()
shareerrors_store = k_new_store(shareerrors_list); shareerrors_store = k_new_store(shareerrors_list);
shareerrors_root = new_ktree(); shareerrors_root = new_ktree();
blocks_list = k_new_list("Blocks", sizeof(BLOCKS), ALLOC_BLOCKS, LIMIT_BLOCKS, true);
blocks_store = k_new_store(blocks_list);
blocks_root = new_ktree();
auths_list = k_new_list("Auths", sizeof(AUTHS), ALLOC_AUTHS, LIMIT_AUTHS, true); auths_list = k_new_list("Auths", sizeof(AUTHS), ALLOC_AUTHS, LIMIT_AUTHS, true);
auths_store = k_new_store(auths_list); auths_store = k_new_store(auths_list);
auths_root = new_ktree(); auths_root = new_ktree();
@ -3514,7 +3829,7 @@ static char *cmd_adduser(char *cmd, char *id, tv_t *now, char *by, char *code, c
PQfinish(conn); PQfinish(conn);
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.DBE", id); LOGERR("%s.failed.DBE", id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} }
LOGDEBUG("%s.ok.added %s", id, DATA_TRANSFER(i_username)->data); LOGDEBUG("%s.ok.added %s", id, DATA_TRANSFER(i_username)->data);
@ -3552,7 +3867,7 @@ static char *cmd_chkpass(char *cmd, char *id, __maybe_unused tv_t *now, __maybe_
} }
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.%s", id, DATA_TRANSFER(i_username)->data); LOGERR("%s.failed.%s", id, DATA_TRANSFER(i_username)->data);
return strdup("failed."); return strdup("failed.");
} }
LOGDEBUG("%s.ok.%s", id, DATA_TRANSFER(i_username)->data); LOGDEBUG("%s.ok.%s", id, DATA_TRANSFER(i_username)->data);
@ -3641,7 +3956,7 @@ static char *cmd_poolstats(char *cmd, __maybe_unused char *id, tv_t *now, char *
PQfinish(conn); PQfinish(conn);
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.DBE", id); LOGERR("%s.failed.DBE", id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} }
LOGDEBUG("%s.ok.", id); LOGDEBUG("%s.ok.", id);
@ -3712,7 +4027,7 @@ static char *cmd_userstats(char *cmd, __maybe_unused char *id, tv_t *now, char *
eos, now, by, code, inet); eos, now, by, code, inet);
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.DATA", id); LOGERR("%s.failed.DATA", id);
return strdup("failed.DATA"); return strdup("failed.DATA");
} }
LOGDEBUG("%s.ok.", id); LOGDEBUG("%s.ok.", id);
@ -3785,7 +4100,7 @@ foil:
K_WUNLOCK(idcontrol_list); K_WUNLOCK(idcontrol_list);
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.DBE", id); LOGERR("%s.failed.DBE", id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} }
LOGDEBUG("%s.ok.added %s %"PRId64, id, DATA_TRANSFER(i_idname)->data, row->lastid); LOGDEBUG("%s.ok.added %s %"PRId64, id, DATA_TRANSFER(i_idname)->data, row->lastid);
@ -3935,7 +4250,7 @@ static char *cmd_sharelog(char *cmd, char *id, tv_t *now, char *by, char *code,
PQfinish(conn); PQfinish(conn);
if (workinfoid == -1) { if (workinfoid == -1) {
LOGDEBUG("%s.failed.DBE", id); LOGERR("%s.failed.DBE", id);
return strdup("failed.DBE"); return strdup("failed.DBE");
} }
LOGDEBUG("%s.ok.added %"PRId64, id, workinfoid); LOGDEBUG("%s.ok.added %"PRId64, id, workinfoid);
@ -3999,7 +4314,7 @@ static char *cmd_sharelog(char *cmd, char *id, tv_t *now, char *by, char *code,
now, by, code, inet); now, by, code, inet);
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.DATA", id); LOGERR("%s.failed.DATA", id);
return strdup("failed.DATA"); return strdup("failed.DATA");
} }
LOGDEBUG("%s.ok.added %s", id, DATA_TRANSFER(i_nonce)->data); LOGDEBUG("%s.ok.added %s", id, DATA_TRANSFER(i_nonce)->data);
@ -4047,17 +4362,119 @@ static char *cmd_sharelog(char *cmd, char *id, tv_t *now, char *by, char *code,
DATA_TRANSFER(i_secondaryuserid)->data, DATA_TRANSFER(i_secondaryuserid)->data,
now, by, code, inet); now, by, code, inet);
if (!ok) { if (!ok) {
LOGDEBUG("%s.failed.DATA", id); LOGERR("%s.failed.DATA", id);
return strdup("failed.DATA"); return strdup("failed.DATA");
} }
LOGDEBUG("%s.ok.added %s", id, DATA_TRANSFER(i_username)->data); LOGDEBUG("%s.ok.added %s", id, DATA_TRANSFER(i_username)->data);
snprintf(reply, siz, "ok.added %s", DATA_TRANSFER(i_username)->data); snprintf(reply, siz, "ok.added %s", DATA_TRANSFER(i_username)->data);
} }
LOGDEBUG("%s.bad.cmd %s", cmd); LOGERR("%s.bad.cmd %s", cmd);
return strdup("bad.cmd"); return strdup("bad.cmd");
} }
static char *cmd_blocks(char *cmd, char *id, tv_t *now, char *by, char *code, char *inet)
{
char reply[1024] = "";
size_t siz = sizeof(reply);
PGconn *conn;
K_ITEM *i_height, *i_blockhash, *i_confirmed, *i_workinfoid, *i_username;
K_ITEM *i_workername, *i_clientid, *i_enonce1, *i_nonce2, *i_nonce, *i_reward;
char *msg;
bool ok;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
i_height = require_name("height", 1, NULL, reply, siz);
if (!i_height)
return strdup(reply);
i_blockhash = require_name("blockhash", 1, NULL, reply, siz);
if (!i_blockhash)
return strdup(reply);
i_confirmed = require_name("confirmed", 1, NULL, reply, siz);
if (!i_confirmed)
return strdup(reply);
DATA_TRANSFER(i_confirmed)->data[0] = tolower(DATA_TRANSFER(i_confirmed)->data[0]);
switch(DATA_TRANSFER(i_confirmed)->data[0]) {
case BLOCKS_NEW:
i_workinfoid = require_name("workinfoid", 1, NULL, reply, siz);
if (!i_workinfoid)
return strdup(reply);
i_username = require_name("username", 1, NULL, reply, siz);
if (!i_username)
return strdup(reply);
i_workername = require_name("workername", 1, NULL, reply, siz);
if (!i_workername)
return strdup(reply);
i_clientid = require_name("clientid", 1, NULL, reply, siz);
if (!i_clientid)
return strdup(reply);
i_enonce1 = require_name("enonce1", 1, NULL, reply, siz);
if (!i_enonce1)
return strdup(reply);
i_nonce2 = require_name("nonce2", 1, NULL, reply, siz);
if (!i_nonce2)
return strdup(reply);
i_nonce = require_name("nonce", 1, NULL, reply, siz);
if (!i_nonce)
return strdup(reply);
i_reward = require_name("reward", 1, NULL, reply, siz);
if (!i_reward)
return strdup(reply);
msg = "added";
conn = dbconnect();
ok = blocks_add(conn, DATA_TRANSFER(i_height)->data,
DATA_TRANSFER(i_blockhash)->data,
DATA_TRANSFER(i_confirmed)->data,
DATA_TRANSFER(i_workinfoid)->data,
DATA_TRANSFER(i_username)->data,
DATA_TRANSFER(i_workername)->data,
DATA_TRANSFER(i_clientid)->data,
DATA_TRANSFER(i_enonce1)->data,
DATA_TRANSFER(i_nonce2)->data,
DATA_TRANSFER(i_nonce)->data,
DATA_TRANSFER(i_reward)->data,
now, by, code, inet);
break;
case BLOCKS_CONFIRM:
msg = "confirmed";
conn = dbconnect();
ok = blocks_add(conn, DATA_TRANSFER(i_height)->data,
DATA_TRANSFER(i_blockhash)->data,
DATA_TRANSFER(i_confirmed)->data,
EMPTY, EMPTY, EMPTY, EMPTY,
EMPTY, EMPTY, EMPTY, EMPTY,
now, by, code, inet);
break;
default:
LOGERR("%s.failed.invalid conf='%s'",
id, DATA_TRANSFER(i_confirmed)->data);
return strdup("failed.DATA");
}
PQfinish(conn);
if (!ok) {
LOGERR("%s.failed.DBE", id);
return strdup("failed.DBE");
}
LOGDEBUG("%s.ok.blocks %s", id, msg);
snprintf(reply, siz, "ok.%s", msg);
return strdup(reply);
}
static char *cmd_auth(char *cmd, char *id, tv_t *now, char *by, char *code, char *inet) static char *cmd_auth(char *cmd, char *id, tv_t *now, char *by, char *code, char *inet)
{ {
char reply[1024] = ""; char reply[1024] = "";
@ -4281,7 +4698,7 @@ enum cmd_values {
CMD_CHKPASS, CMD_CHKPASS,
CMD_POOLSTAT, CMD_POOLSTAT,
CMD_USERSTAT, CMD_USERSTAT,
// CMD_BLOCK, CMD_BLOCK,
CMD_NEWID, CMD_NEWID,
CMD_PAYMENTS, CMD_PAYMENTS,
CMD_HOMEPAGE, CMD_HOMEPAGE,
@ -4311,7 +4728,7 @@ static struct CMDS {
{ CMD_CHKPASS, "chkpass", cmd_chkpass, ACCESS_WEB }, { CMD_CHKPASS, "chkpass", cmd_chkpass, ACCESS_WEB },
{ CMD_POOLSTAT, "poolstats", cmd_poolstats, ACCESS_POOL }, { CMD_POOLSTAT, "poolstats", cmd_poolstats, ACCESS_POOL },
{ CMD_USERSTAT, "userstats", cmd_userstats, ACCESS_POOL }, { CMD_USERSTAT, "userstats", cmd_userstats, ACCESS_POOL },
// TODO { CMD_BLOCK, "block", cmd_block, ACCESS_POOL }, { CMD_BLOCK, "block", cmd_blocks, ACCESS_POOL },
{ CMD_NEWID, "newid", cmd_newid, ACCESS_SYSTEM }, { CMD_NEWID, "newid", cmd_newid, ACCESS_SYSTEM },
{ CMD_PAYMENTS, "payments", cmd_payments, ACCESS_WEB }, { CMD_PAYMENTS, "payments", cmd_payments, ACCESS_WEB },
{ CMD_HOMEPAGE, "homepage", cmd_homepage, ACCESS_WEB }, { CMD_HOMEPAGE, "homepage", cmd_homepage, ACCESS_WEB },

Loading…
Cancel
Save