Browse Source

ckdb - cmd_payouts for setting up old payouts

master
kanoi 10 years ago
parent
commit
1380acddfb
  1. 2
      src/ckdb.c
  2. 7
      src/ckdb.h
  3. 161
      src/ckdb_cmd.c
  4. 25
      src/ckdb_data.c

2
src/ckdb.c

@ -2662,6 +2662,7 @@ static void *socketer(__maybe_unused void *arg)
case CMD_PAYMENTS: case CMD_PAYMENTS:
case CMD_PPLNS: case CMD_PPLNS:
case CMD_PPLNS2: case CMD_PPLNS2:
case CMD_PAYOUTS:
case CMD_DSP: case CMD_DSP:
case CMD_BLOCKSTATUS: case CMD_BLOCKSTATUS:
if (!startup_complete) { if (!startup_complete) {
@ -2880,6 +2881,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
case CMD_STATS: case CMD_STATS:
case CMD_PPLNS: case CMD_PPLNS:
case CMD_PPLNS2: case CMD_PPLNS2:
case CMD_PAYOUTS:
case CMD_USERSTATUS: case CMD_USERSTATUS:
case CMD_MARKS: case CMD_MARKS:
LOGERR("%s() Message line %"PRIu64" '%s' - invalid - ignored", LOGERR("%s() Message line %"PRIu64" '%s' - invalid - ignored",

7
src/ckdb.h

@ -52,7 +52,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "1.0.0" #define DB_VERSION "1.0.0"
#define CKDB_VERSION DB_VERSION"-1.000" #define CKDB_VERSION DB_VERSION"-1.001"
#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__
@ -340,7 +340,7 @@ enum cmd_values {
CMD_STATS, CMD_STATS,
CMD_PPLNS, CMD_PPLNS,
CMD_PPLNS2, CMD_PPLNS2,
CMD_PAYOUT, CMD_PAYOUTS,
CMD_USERSTATUS, CMD_USERSTATUS,
CMD_MARKS, CMD_MARKS,
CMD_END CMD_END
@ -1182,6 +1182,7 @@ extern K_LIST *payouts_free;
extern K_STORE *payouts_store; extern K_STORE *payouts_store;
extern cklock_t process_pplns_lock; extern cklock_t process_pplns_lock;
// N.B. status should be checked under r/w lock
#define PAYOUTS_GENERATED 'G' #define PAYOUTS_GENERATED 'G'
#define PAYOUTS_GENERATED_STR "G" #define PAYOUTS_GENERATED_STR "G"
#define PAYGENERATED(_status) ((_status)[0] == PAYOUTS_GENERATED) #define PAYGENERATED(_status) ((_status)[0] == PAYOUTS_GENERATED)
@ -1754,7 +1755,7 @@ extern cmp_t cmp_payouts_id(K_ITEM *a, K_ITEM *b);
extern K_ITEM *find_payouts(int32_t height, char *blockhash); extern K_ITEM *find_payouts(int32_t height, char *blockhash);
extern K_ITEM *find_last_payouts(); extern K_ITEM *find_last_payouts();
extern K_ITEM *find_payoutid(int64_t payoutid); extern K_ITEM *find_payoutid(int64_t payoutid);
extern void process_pplns(int32_t height, char *blockhash, tv_t *now); extern bool process_pplns(int32_t height, char *blockhash, tv_t *now);
extern cmp_t cmp_auths(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_auths(K_ITEM *a, K_ITEM *b);
extern cmp_t cmp_poolstats(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_poolstats(K_ITEM *a, K_ITEM *b);
extern void dsp_userstats(K_ITEM *item, FILE *stream); extern void dsp_userstats(K_ITEM *item, FILE *stream);

161
src/ckdb_cmd.c

@ -4030,6 +4030,165 @@ shazbot:
return strdup(reply); return strdup(reply);
} }
static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now,
char *by, char *code, char *inet,
__maybe_unused tv_t *cd, K_TREE *trf_root)
{
char reply[1024] = "";
size_t siz = sizeof(reply);
char msg[1024] = "";
K_ITEM *i_action, *i_payoutid, *i_height, *i_blockhash, *i_addrdate;
K_ITEM *p_item, *p2_item, *old_p2_item;
PAYOUTS *payouts, *payouts2, *old_payouts2;
char *action;
int64_t payoutid = -1;
int32_t height = 0;
char blockhash[TXT_BIG+1];
tv_t addrdate;
bool ok = true;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
i_action = require_name(trf_root, "action", 1, NULL, reply, siz);
if (!i_action)
return strdup(reply);
action = transfer_data(i_action);
if (strcasecmp(action, "generated") == 0) {
/* Change the status of a processing payout to generated
* Require payoutid
* Use this if the payout process completed but the end txn,
* that only updates the payout to generated, failed */
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 (!PAYPROCESSING(payouts->status)) {
K_WUNLOCK(payouts_free);
snprintf(reply, siz,
"status !processing (%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_GENERATED_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) {
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, payouts2->status, old_payouts2->status,
payouts2->height, payouts2->blockhash);
/*
} else if (strcasecmp(action, "expire") == 0) {
/ TODO: Expire the payout - effectively deletes it
* Require payoutid
* If any payments are paid then don't allow it /
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);
}
p2_item = k_unlink_head(payouts_free);
K_WUNLOCK(payouts_free);
DATA_PAYOUTS(payouts2, p2_item);
bzero(payouts2, sizeof(*payouts2));
payouts2->payoutid = payouts->payoutid;
...
*/
} else if (strcasecmp(action, "process") == 0) {
/* Generate a payout
* Require height, blockhash and addrdate
* addrdate is an epoch integer
* and 0 means uses the default = block NEW createdate
* this is the date to use for payoutaddresses
* Check the console for processing messages */
i_height = require_name(trf_root, "height", 6,
(char *)intpatt, reply, siz);
if (!i_height)
return strdup(reply);
TXT_TO_INT("height", transfer_data(i_height), height);
i_blockhash = require_name(trf_root, "blockhash", 64,
(char *)hashpatt, reply, siz);
if (!i_blockhash)
return strdup(reply);
TXT_TO_STR("blockhash", transfer_data(i_blockhash), blockhash);
i_addrdate = require_name(trf_root, "addrdate", 1,
(char *)intpatt, reply, siz);
if (!i_addrdate)
return strdup(reply);
TXT_TO_CTV("addrdate", transfer_data(i_addrdate), addrdate);
if (addrdate.tv_sec == 0)
ok = process_pplns(height, blockhash, NULL);
else
ok = process_pplns(height, blockhash, &addrdate);
} else {
snprintf(reply, siz, "unknown action '%s'", action);
LOGERR("%s.%s", id, reply);
return strdup(reply);
}
snprintf(reply, siz, "%s.%s%s%s",
ok ? "ok" : "ERR",
action,
msg[0] ? " " : EMPTY,
msg[0] ? msg : EMPTY);
LOGWARNING("%s.%s", id, reply);
return strdup(reply);
}
static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd, static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,
char *id, __maybe_unused tv_t *now, char *id, __maybe_unused tv_t *now,
__maybe_unused char *by, __maybe_unused char *code, __maybe_unused char *by, __maybe_unused char *code,
@ -4690,7 +4849,7 @@ struct CMDS ckdb_cmds[] = {
{ CMD_STATS, "stats", true, false, cmd_stats, ACCESS_SYSTEM ACCESS_WEB }, { CMD_STATS, "stats", true, false, cmd_stats, ACCESS_SYSTEM ACCESS_WEB },
{ CMD_PPLNS, "pplns", false, false, cmd_pplns, ACCESS_SYSTEM ACCESS_WEB }, { CMD_PPLNS, "pplns", false, false, cmd_pplns, ACCESS_SYSTEM ACCESS_WEB },
{ CMD_PPLNS2, "pplns2", false, false, cmd_pplns2, ACCESS_SYSTEM ACCESS_WEB }, { CMD_PPLNS2, "pplns2", false, false, cmd_pplns2, ACCESS_SYSTEM ACCESS_WEB },
// { CMD_PAYOUT, "payout", false, false, cmd_payout, ACCESS_SYSTEM }, { CMD_PAYOUTS, "payouts", false, false, cmd_payouts, ACCESS_SYSTEM },
{ CMD_USERSTATUS,"userstatus", false, false, cmd_userstatus, ACCESS_SYSTEM ACCESS_WEB }, { CMD_USERSTATUS,"userstatus", false, false, cmd_userstatus, ACCESS_SYSTEM ACCESS_WEB },
{ CMD_MARKS, "marks", false, false, cmd_marks, ACCESS_SYSTEM }, { CMD_MARKS, "marks", false, false, cmd_marks, ACCESS_SYSTEM },
{ CMD_END, NULL, false, false, NULL, NULL } { CMD_END, NULL, false, false, NULL, NULL }

25
src/ckdb_data.c

@ -2557,11 +2557,11 @@ K_ITEM *find_payoutid(int64_t payoutid)
N.B. process_pplns() is only automatically triggered once after the block N.B. process_pplns() is only automatically triggered once after the block
summarisation is verified, so it can always report all errors summarisation is verified, so it can always report all errors
*/ */
void process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd)
{ {
K_TREE_CTX b_ctx[1], ss_ctx[1], wm_ctx[1], ms_ctx[1], pay_ctx[1], mu_ctx[1]; K_TREE_CTX b_ctx[1], ss_ctx[1], wm_ctx[1], ms_ctx[1], pay_ctx[1], mu_ctx[1];
bool allow_aged = true, conned = false, begun = false; bool allow_aged = true, conned = false, begun = false;
bool countbacklimit, ok; bool countbacklimit, ok = false;
PGconn *conn = NULL; PGconn *conn = NULL;
MININGPAYOUTS *miningpayouts; MININGPAYOUTS *miningpayouts;
OPTIONCONTROL *optioncontrol; OPTIONCONTROL *optioncontrol;
@ -2586,7 +2586,8 @@ void process_pplns(int32_t height, char *blockhash, tv_t *addr_cd)
char ndiffbin[TXT_SML+1]; char ndiffbin[TXT_SML+1];
double diff_times, diff_add; double diff_times, diff_add;
char cd_buf[CDATE_BUFSIZ]; char cd_buf[CDATE_BUFSIZ];
tv_t begin_tv, end_tv, now; tv_t end_tv = { 0L, 0L };
tv_t begin_tv, now;
char buf[1024]; char buf[1024];
/* /*
@ -2624,30 +2625,30 @@ void process_pplns(int32_t height, char *blockhash, tv_t *addr_cd)
goto oku; goto oku;
} }
DATA_BLOCKS(blocks, b_item); DATA_BLOCKS(blocks, b_item);
// If addr_cd is null, use the block NEW createdate
if (!addr_cd) {
b2_item = b_item; b2_item = b_item;
DATA_BLOCKS(blocks2, b2_item); DATA_BLOCKS(blocks2, b2_item);
while (b2_item && blocks2->height == height && while (b2_item && blocks2->height == height &&
strcmp(blocks2->blockhash, blockhash) == 0) { strcmp(blocks2->blockhash, blockhash) == 0) {
if (blocks2->confirmed[0] == BLOCKS_NEW) { if (blocks2->confirmed[0] == BLOCKS_NEW) {
copy_tv(&end_tv, &(blocks->createdate));
if (!addr_cd)
addr_cd = &(blocks2->createdate); addr_cd = &(blocks2->createdate);
break; break;
} }
b2_item = next_in_ktree(b_ctx); b2_item = next_in_ktree(b_ctx);
DATA_BLOCKS_NULL(blocks2, b2_item); DATA_BLOCKS_NULL(blocks2, b2_item);
} }
if (!addr_cd) {
K_RUNLOCK(blocks_free); K_RUNLOCK(blocks_free);
LOGEMERG("%s(): missing NEW record for block %"PRId32 // If addr_cd was null it should've been set to the block NEW createdate
if (!addr_cd || end_tv.tv_sec == 0) {
LOGEMERG("%s(): missing %s record for block %"PRId32
"/%"PRId64"/%s/%s/%"PRId64, "/%"PRId64"/%s/%s/%"PRId64,
__func__, blocks->height, blocks->workinfoid, __func__, blocks_confirmed(BLOCKS_NEW_STR),
blocks->height, blocks->workinfoid,
blocks->workername, blocks->confirmed, blocks->workername, blocks->confirmed,
blocks->reward); blocks->reward);
goto oku; goto oku;
} }
}
K_RUNLOCK(blocks_free);
LOGDEBUG("%s(): block %"PRId32"/%"PRId64"/%s/%s/%"PRId64, LOGDEBUG("%s(): block %"PRId32"/%"PRId64"/%s/%s/%"PRId64,
__func__, blocks->height, blocks->workinfoid, __func__, blocks->height, blocks->workinfoid,
@ -3211,6 +3212,8 @@ void process_pplns(int32_t height, char *blockhash, tv_t *addr_cd)
goto oku; goto oku;
shazbot: shazbot:
ok = false;
if (begun) if (begun)
CKPQEnd(conn, false); CKPQEnd(conn, false);
CKPQDisco(&conn, conned); CKPQDisco(&conn, conned);
@ -3250,7 +3253,7 @@ oku:
} }
addr_store = k_free_store(addr_store); addr_store = k_free_store(addr_store);
} }
return; return ok;
} }
// order by userid asc,createdate asc,authid asc,expirydate desc // order by userid asc,createdate asc,authid asc,expirydate desc

Loading…
Cancel
Save