diff --git a/pool/page_shifts.php b/pool/page_shifts.php index e8efac11..40cc94ff 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -14,6 +14,7 @@ function doshifts($data, $user) $pg .= "Avg Hs"; $pg .= "Shares"; $pg .= "Avg Share"; + $pg .= "Rewards"; $pg .= "\n"; if (($ans['STATUS'] != 'ok') || !isset($ans['prefix_all'])) @@ -66,6 +67,7 @@ function doshifts($data, $user) else $avgsh = 0; $pg .= ''.number_format($avgsh, 2).''; + $pg .= ''.$ans['rewards:'.$i].''; $pg .= "\n"; } } diff --git a/src/ckdb.c b/src/ckdb.c index 50eaac49..97b473b7 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -776,8 +776,6 @@ static bool getdata3() goto sukamudai; if (!(ok = miningpayouts_fill(conn)) || everyone_die) goto sukamudai; - if (!(ok = payouts_fill(conn)) || everyone_die) - goto sukamudai; } if (!(ok = workinfo_fill(conn)) || everyone_die) goto sukamudai; @@ -786,6 +784,11 @@ static bool getdata3() /* must be after workinfo */ if (!(ok = workmarkers_fill(conn)) || everyone_die) goto sukamudai; + if (!confirm_sharesummary) { + /* must be after workmarkers */ + if (!(ok = payouts_fill(conn)) || everyone_die) + goto sukamudai; + } if (!(ok = markersummary_fill(conn)) || everyone_die) goto sukamudai; if (!confirm_sharesummary && !everyone_die) diff --git a/src/ckdb.h b/src/ckdb.h index 7db37e9b..8acdd7b1 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -1901,6 +1901,9 @@ typedef struct workmarkers { int64_t workinfoidstart; char *description; char status[TXT_FLAG+1]; + int rewards; // non-DB field + double pps_value; // non-DB field + double rewarded; // non-DB field HISTORYDATECONTROLFIELDS; } WORKMARKERS; @@ -2343,11 +2346,12 @@ extern bool make_markersummaries(bool msg, char *by, char *code, char *inet, extern void dsp_workmarkers(K_ITEM *item, FILE *stream); extern cmp_t cmp_workmarkers(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_workmarkers_workinfoid(K_ITEM *a, K_ITEM *b); -extern K_ITEM *find_workmarkers(int64_t workinfoid, bool anystatus, char status); +extern K_ITEM *find_workmarkers(int64_t workinfoid, bool anystatus, char status, K_TREE_CTX *ctx); extern K_ITEM *find_workmarkerid(int64_t markerid, bool anystatus, char status); extern bool workmarkers_generate(PGconn *conn, char *err, size_t siz, char *by, char *code, char *inet, tv_t *cd, K_TREE *trf_root, bool none_error); +extern bool reward_shifts(PAYOUTS *payouts, bool lock, int delta); extern cmp_t cmp_marks(K_ITEM *a, K_ITEM *b); extern K_ITEM *find_marks(int64_t workinfoid); extern const char *marks_marktype(char *marktype); diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 5f749d3f..1e41f13a 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -4789,6 +4789,8 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, snprintf(reply, siz, "failed payout %"PRId64, payoutid); return strdup(reply); } + // Original wasn't generated, so reward it + reward_shifts(payouts2, true, 1); DATA_PAYOUTS(payouts2, p2_item); DATA_PAYOUTS(old_payouts2, old_p2_item); snprintf(msg, sizeof(msg), @@ -4858,6 +4860,8 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, snprintf(reply, siz, "failed payout %"PRId64, payoutid); return strdup(reply); } + // Original was generated, so undo the reward + reward_shifts(payouts2, true, -1); DATA_PAYOUTS(payouts2, p2_item); DATA_PAYOUTS(old_payouts2, old_p2_item); snprintf(msg, sizeof(msg), @@ -4875,6 +4879,7 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, return strdup(reply); TXT_TO_BIGINT("payoutid", transfer_data(i_payoutid), payoutid); + // payouts_full_expire updates the shift rewards p_item = payouts_full_expire(conn, payoutid, now, true); if (!p_item) { snprintf(reply, siz, "failed payout %"PRId64, payoutid); @@ -4911,6 +4916,7 @@ static char *cmd_payouts(PGconn *conn, char *cmd, char *id, tv_t *now, return strdup(reply); TXT_TO_CTV("addrdate", transfer_data(i_addrdate), addrdate); + // process_pplns updates the shift rewards if (addrdate.tv_sec == 0) ok = process_pplns(height, blockhash, NULL); else @@ -5355,6 +5361,10 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), "rewards:%d=%d%c", + rows, wm->rewards, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + rows++; // Setup for next shift @@ -5394,7 +5404,7 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, * other workers start >= 0 and finish <= rows-1 */ snprintf(tmp, sizeof(tmp), "rows=%d%cflds=%s%c", rows, FLDSEP, - "markerid,shift,start,end", FLDSEP); + "markerid,shift,start,end,rewards", FLDSEP); APPEND_REALLOC(buf, off, len, tmp); snprintf(tmp, sizeof(tmp), "arn=%s", "Shifts"); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 6b145163..71754783 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -2070,7 +2070,7 @@ bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, char *code, } K_RLOCK(workmarkers_free); - wm_item = find_workmarkers(workinfoid, false, MARKER_PROCESSED); + wm_item = find_workmarkers(workinfoid, false, MARKER_PROCESSED, NULL); K_RUNLOCK(workmarkers_free); // Should never happen? if (wm_item && !reloading) { @@ -3589,7 +3589,7 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) * block - so abort * The fix is to create the marks and summaries needed via * cmd_marks() then manually trigger the payout generation - * TODO: via cmd_payouts() ... which isn't available yet */ + * via cmd_payouts() */ LOGEMERG("%s(): payout had < 1 (%"PRId64") workmarkers for " "block %"PRId32"/%"PRId64"/%s/%s/%"PRId64 " beginwi=%"PRId64" ss=%"PRId64" diff=%.1f", @@ -3810,20 +3810,8 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) pa_item = pa_item->next; } } else { - /* Address user or normal user without a paymentaddress - * TODO: user table needs a flag to say which it is ... - * for now use a simple test */ - bool gotaddr = false; - size_t len; - - switch (users->username[0]) { - case '1': - case '3': - len = strlen(users->username); - if (len >= ADDR_MIN_LEN && len <= ADDR_MAX_LEN) - gotaddr = true; - } - if (gotaddr) { + /* Address user or normal user without a paymentaddress */ + if (users->userbits & USER_ADDRESS) { K_WLOCK(payments_free); pay_item = k_unlink_head(payments_free); K_WUNLOCK(payments_free); @@ -3906,6 +3894,9 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) ss_count, wm_count, ms_count, usercount, diff_times, diff_add, cd_buf); + /* At this point the payout is complete, but it just hasn't been + * flagged complete yet in the DB */ + K_WLOCK(payouts_free); p2_item = k_unlink_head(payouts_free); K_WUNLOCK(payouts_free); @@ -3931,13 +3922,20 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) ok = payouts_add(conn, true, p2_item, &old_p2_item, (char *)by_default, (char *)__func__, (char *)inet_default, &now, NULL, false); + if (!ok) { + /* All that's required is to mark the payout GENERATED + * since it already exists in the DB and in RAM, thus a manual + * cmd_payouts 'generated' is all that's needed to fix it */ LOGEMERG("%s(): payout %"PRId64" for block %"PRId32"/%s " "NOT set generated - it needs to be set manually", __func__, payouts->payoutid, blocks->height, blocks->blockhash); } + // Flag each shift as rewarded + reward_shifts(payouts2, true, 1); + CKPQDisco(&conn, conned); goto oku; @@ -4146,7 +4144,7 @@ K_ITEM *_find_markersummary(int64_t markerid, int64_t workinfoid, K_TREE_CTX ctx[1]; if (markerid == 0) { - wm_item = find_workmarkers(workinfoid, false, MARKER_PROCESSED); + wm_item = find_workmarkers(workinfoid, false, MARKER_PROCESSED, NULL); if (wm_item) { DATA_WORKMARKERS(wm, wm_item); markerid = wm->markerid; @@ -4277,12 +4275,15 @@ cmp_t cmp_workmarkers_workinfoid(K_ITEM *a, K_ITEM *b) return c; } -K_ITEM *find_workmarkers(int64_t workinfoid, bool anystatus, char status) +K_ITEM *find_workmarkers(int64_t workinfoid, bool anystatus, char status, K_TREE_CTX *ctx) { WORKMARKERS workmarkers, *wm; - K_TREE_CTX ctx[1]; + K_TREE_CTX ctx0[1]; K_ITEM look, *wm_item; + if (ctx == NULL) + ctx = ctx0; + workmarkers.expirydate.tv_sec = default_expiry.tv_sec; workmarkers.expirydate.tv_usec = default_expiry.tv_usec; workmarkers.workinfoidend = workinfoid-1; @@ -4401,7 +4402,8 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin, * sort order and matching errors */ if (wi_fin->workinfoid >= wi_stt->workinfoid) { K_RLOCK(workmarkers_free); - old_wm_item = find_workmarkers(wi_fin->workinfoid, true, '\0'); + old_wm_item = find_workmarkers(wi_fin->workinfoid, true, '\0', + NULL); K_RUNLOCK(workmarkers_free); DATA_WORKMARKERS_NULL(old_wm, old_wm_item); if (old_wm_item && (WMREADY(old_wm->status) || @@ -4580,6 +4582,39 @@ bool workmarkers_generate(PGconn *conn, char *err, size_t siz, char *by, return true; } +// delta = 1 or -1 i.e. reward or undo reward +bool reward_shifts(PAYOUTS *payouts, bool lock, int delta) +{ + // TODO: PPS calculations + K_TREE_CTX ctx[1]; + K_ITEM *wm_item; + WORKMARKERS *wm; + bool did_one = false; + + if (lock) + K_WLOCK(workmarkers_free); + + wm_item = find_workmarkers(payouts->workinfoidstart, false, + MARKER_PROCESSED, ctx); + while (wm_item) { + DATA_WORKMARKERS(wm, wm_item); + if (wm->workinfoidstart > payouts->workinfoidend) + break; + /* The status doesn't matter since we want the rewards passed + * onto the PROCESSED status if it isn't already processed */ + if (CURRENT(&(wm->expirydate))) { + wm->rewards += delta; + did_one = true; + } + wm_item = next_in_ktree(ctx); + } + + if (lock) + K_WUNLOCK(workmarkers_free); + + return did_one; +} + // order by expirydate asc,workinfoid asc // TODO: add poolinstance cmp_t cmp_marks(K_ITEM *a, K_ITEM *b) diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index f2927d9e..d355be78 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -2959,7 +2959,7 @@ static bool shares_process(PGconn *conn, SHARES *shares, K_TREE *trf_root) if (reloading && !confirm_sharesummary) { // We only need to know if the workmarker is processed wm_item = find_workmarkers(shares->workinfoid, false, - MARKER_PROCESSED); + MARKER_PROCESSED, NULL); if (wm_item) { LOGDEBUG("%s(): workmarker exists for wid %"PRId64 " %"PRId64"/%s/%ld,%ld", @@ -3260,7 +3260,7 @@ static bool shareerrors_process(PGconn *conn, SHAREERRORS *shareerrors, if (reloading && !confirm_sharesummary) { // We only need to know if the workmarker is processed wm_item = find_workmarkers(shareerrors->workinfoid, false, - MARKER_PROCESSED); + MARKER_PROCESSED, NULL); if (wm_item) { LOGDEBUG("%s(): workmarker exists for wid %"PRId64 " %"PRId64"/%s/%ld,%ld", @@ -4024,7 +4024,8 @@ bool _sharesummary_update(SHARES *s_row, SHAREERRORS *e_row, K_ITEM *ss_item, } K_RLOCK(workmarkers_free); - wm_item = find_workmarkers(workinfoid, false, MARKER_PROCESSED); + wm_item = find_workmarkers(workinfoid, false, MARKER_PROCESSED, + NULL); K_RUNLOCK(workmarkers_free); if (wm_item) { DATA_WORKMARKERS(wm, wm_item); @@ -5465,6 +5466,12 @@ K_ITEM *payouts_full_expire(PGconn *conn, int64_t payoutid, tv_t *now, bool lock DATA_PAYMENTS_NULL(payments, pm_item); } + if (PAYGENERATED(payouts->status)) { + // Original was generated, so undo the reward + reward_shifts(payouts, true, -1); + + } + ok = true; matane: if (begun) @@ -5613,6 +5620,9 @@ bool payouts_fill(PGconn *conn) payouts_id_root = add_to_ktree(payouts_id_root, item, cmp_payouts_id); k_add_head(payouts_store, item); + if (CURRENT(&(row->expirydate)) && PAYGENERATED(row->status)) + reward_shifts(row, false, 1); + tick(); } if (!ok) { @@ -6517,7 +6527,7 @@ bool _workmarkers_process(PGconn *conn, bool already, bool add, if (markerid == 0) { K_RLOCK(workmarkers_free); - old_wm_item = find_workmarkers(workinfoidend, true, '\0'); + old_wm_item = find_workmarkers(workinfoidend, true, '\0', NULL); K_RUNLOCK(workmarkers_free); } else { K_RLOCK(workmarkers_free);