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);