Browse Source

ckdb - calc 'rewards' for a new shift in case the payout has already been done

master
kanoi 9 years ago
parent
commit
369274b521
  1. 3
      src/ckdb.c
  2. 6
      src/ckdb.h
  3. 2
      src/ckdb_cmd.c
  4. 64
      src/ckdb_data.c
  5. 8
      src/ckdb_dbio.c

3
src/ckdb.c

@ -420,6 +420,7 @@ K_STORE *miningpayouts_store;
// PAYOUTS
K_TREE *payouts_root;
K_TREE *payouts_id_root;
K_TREE *payouts_wid_root;
K_LIST *payouts_free;
K_STORE *payouts_store;
cklock_t process_pplns_lock;
@ -1086,6 +1087,7 @@ static void alloc_storage()
payouts_store = k_new_store(payouts_free);
payouts_root = new_ktree();
payouts_id_root = new_ktree();
payouts_wid_root = new_ktree();
auths_free = k_new_list("Auths", sizeof(AUTHS),
ALLOC_AUTHS, LIMIT_AUTHS, true);
@ -1304,6 +1306,7 @@ static void dealloc_storage()
FREE_ALL(poolstats);
FREE_ALL(auths);
FREE_TREE(payouts_wid);
FREE_TREE(payouts_id);
FREE_TREE(payouts);
FREE_STORE_DATA(payouts);

6
src/ckdb.h

@ -55,7 +55,7 @@
#define DB_VLOCK "1"
#define DB_VERSION "1.0.2"
#define CKDB_VERSION DB_VERSION"-1.229"
#define CKDB_VERSION DB_VERSION"-1.230"
#define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -1600,6 +1600,7 @@ typedef struct payouts {
extern K_TREE *payouts_root;
extern K_TREE *payouts_id_root;
extern K_TREE *payouts_wid_root;
extern K_LIST *payouts_free;
extern K_STORE *payouts_store;
extern cklock_t process_pplns_lock;
@ -2318,9 +2319,11 @@ extern K_TREE *upd_add_mu(K_TREE *mu_root, K_STORE *mu_store, int64_t userid,
double diffacc);
extern cmp_t cmp_payouts(K_ITEM *a, K_ITEM *b);
extern cmp_t cmp_payouts_id(K_ITEM *a, K_ITEM *b);
extern cmp_t cmp_payouts_wid(K_ITEM *a, K_ITEM *b);
extern K_ITEM *find_payouts(int32_t height, char *blockhash);
extern K_ITEM *find_last_payouts();
extern K_ITEM *find_payoutid(int64_t payoutid);
extern K_ITEM *find_payouts_wid(int64_t workinfoidend, K_TREE_CTX *ctx);
extern double payout_stats(PAYOUTS *payouts, char *statname);
extern bool process_pplns(int32_t height, char *blockhash, tv_t *now);
extern cmp_t cmp_auths(K_ITEM *a, K_ITEM *b);
@ -2354,6 +2357,7 @@ 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 bool shift_rewards(K_ITEM *wm_item);
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);

2
src/ckdb_cmd.c

@ -5541,7 +5541,7 @@ static char *cmd_stats(__maybe_unused PGconn *conn, char *cmd, char *id,
USEINFO(marks, 1, 1);
USEINFO(blocks, 1, 1);
USEINFO(miningpayouts, 1, 1);
USEINFO(payouts, 1, 2);
USEINFO(payouts, 1, 3);
USEINFO(auths, 1, 1);
USEINFO(poolstats, 1, 1);
USEINFO(userstats, 2, 1);

64
src/ckdb_data.c

@ -3141,6 +3141,22 @@ cmp_t cmp_payouts_id(K_ITEM *a, K_ITEM *b)
return c;
}
/* order by workinfoidend asc,expirydate asc
* This must use workinfoidend, not workinfoidstart, since a change
* in the payout PPLNS N could have 2 payouts with the same start,
* but currently there is only one payout per block
* i.e. workinfoidend can only have one payout */
cmp_t cmp_payouts_wid(K_ITEM *a, K_ITEM *b)
{
PAYOUTS *pa, *pb;
DATA_PAYOUTS(pa, a);
DATA_PAYOUTS(pb, b);
cmp_t c = CMP_BIGINT(pa->workinfoidend, pb->workinfoidend);
if (c == 0)
c = CMP_TV(pa->expirydate, pb->expirydate);
return c;
}
K_ITEM *find_payouts(int32_t height, char *blockhash)
{
PAYOUTS payouts;
@ -3189,6 +3205,25 @@ K_ITEM *find_payoutid(int64_t payoutid)
return find_in_ktree(payouts_id_root, &look, cmp_payouts_id, ctx);
}
// First payouts workinfoidend equal or before workinfoidend
K_ITEM *find_payouts_wid(int64_t workinfoidend, K_TREE_CTX *ctx)
{
PAYOUTS payouts;
K_TREE_CTX ctx0[1];
K_ITEM look;
if (ctx == NULL)
ctx = ctx0;
payouts.workinfoidend = workinfoidend+1;
payouts.expirydate.tv_sec = 0;
payouts.expirydate.tv_usec = 0;
INIT_PAYOUTS(&look);
look.data = (void *)(&payouts);
return find_before_in_ktree(payouts_wid_root, &look, cmp_payouts_wid, ctx);
}
/* Values from payout stats, returns -1 if statname isn't found
* If code needs a value then it probably really should be a new payouts field
* rather than stored in the stats passed to the pplns2 web page
@ -4635,6 +4670,35 @@ bool reward_shifts(PAYOUTS *payouts, bool lock, int delta)
return did_one;
}
// (re)calculate rewards for a shift
bool shift_rewards(K_ITEM *wm_item)
{
PAYOUTS *payouts = NULL;
K_TREE_CTX ctx[1];
WORKMARKERS *wm;
K_ITEM *p_item;
int rewards = 0;
DATA_WORKMARKERS(wm, wm_item);
// Deadlock risk since calling code should have workmarkers locked
K_WLOCK(payouts_free);
p_item = find_payouts_wid(wm->workinfoidend, ctx);
DATA_PAYOUTS_NULL(payouts, p_item);
// a workmarker should not cross a payout boundary
while (p_item && payouts->workinfoidstart <= wm->workinfoidstart &&
wm->workinfoidend <= payouts->workinfoidend) {
if (CURRENT(&(payouts->expirydate)))
rewards++;
p_item = prev_in_ktree(ctx);
DATA_PAYOUTS_NULL(payouts, p_item);
}
K_WUNLOCK(payouts_free);
wm->rewards = rewards;
return (rewards > 0);
}
// order by expirydate asc,workinfoid asc
// TODO: add poolinstance
cmp_t cmp_marks(K_ITEM *a, K_ITEM *b)

8
src/ckdb_dbio.c

@ -5119,12 +5119,15 @@ void payouts_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item, tv_t *cd)
DATA_PAYOUTS(oldp, old_p_item);
payouts_root = remove_from_ktree(payouts_root, old_p_item, cmp_payouts);
payouts_id_root = remove_from_ktree(payouts_id_root, old_p_item, cmp_payouts_id);
payouts_wid_root = remove_from_ktree(payouts_wid_root, old_p_item, cmp_payouts_wid);
copy_tv(&(oldp->expirydate), cd);
payouts_root = add_to_ktree(payouts_root, old_p_item, cmp_payouts);
payouts_id_root = add_to_ktree(payouts_id_root, old_p_item, cmp_payouts_id);
payouts_wid_root = add_to_ktree(payouts_wid_root, old_p_item, cmp_payouts_wid);
}
payouts_root = add_to_ktree(payouts_root, p_item, cmp_payouts);
payouts_id_root = add_to_ktree(payouts_id_root, p_item, cmp_payouts_id);
payouts_wid_root = add_to_ktree(payouts_wid_root, p_item, cmp_payouts_wid);
k_add_head(payouts_store, p_item);
}
K_WUNLOCK(payouts_free);
@ -5431,9 +5434,11 @@ K_ITEM *payouts_full_expire(PGconn *conn, int64_t payoutid, tv_t *now, bool lock
DATA_PAYOUTS(payouts, po_item);
payouts_root = remove_from_ktree(payouts_root, po_item, cmp_payouts);
payouts_id_root = remove_from_ktree(payouts_id_root, po_item, cmp_payouts_id);
payouts_wid_root = remove_from_ktree(payouts_wid_root, po_item, cmp_payouts_wid);
copy_tv(&(payouts->expirydate), now);
payouts_root = add_to_ktree(payouts_root, po_item, cmp_payouts);
payouts_id_root = add_to_ktree(payouts_id_root, po_item, cmp_payouts_id);
payouts_wid_root = add_to_ktree(payouts_wid_root, po_item, cmp_payouts_wid);
mp_item = first_miningpayouts(payoutid, mp_ctx);
DATA_MININGPAYOUTS_NULL(mp, mp_item);
@ -5643,6 +5648,7 @@ bool payouts_fill(PGconn *conn)
payouts_root = add_to_ktree(payouts_root, item, cmp_payouts);
payouts_id_root = add_to_ktree(payouts_id_root, item, cmp_payouts_id);
payouts_wid_root = add_to_ktree(payouts_wid_root, item, cmp_payouts_wid);
k_add_head(payouts_store, item);
if (CURRENT(&(row->expirydate)) && PAYGENERATED(row->status))
@ -6726,6 +6732,8 @@ unparam:
cmp_workmarkers_workinfoid);
}
if (wm_item) {
shift_rewards(wm_item);
workmarkers_root = add_to_ktree(workmarkers_root,
wm_item,
cmp_workmarkers);

Loading…
Cancel
Save