diff --git a/src/ckdb.c b/src/ckdb.c index 30141ca4..b47578ac 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -1204,8 +1204,8 @@ static void alloc_storage() shares_root = new_ktree(NULL, cmp_shares, shares_free); shares_early_root = new_ktree("SharesEarly", cmp_shares, shares_free); shares_hi_store = k_new_store(shares_free); - shares_hi_root = new_ktree("SharesHi", cmp_shares, shares_free); - shares_db_root = new_ktree("SharesDB", cmp_shares, shares_free); + shares_hi_root = new_ktree("SharesHi", cmp_shares_db, shares_free); + shares_db_root = new_ktree("SharesDB", cmp_shares_db, shares_free); shareerrors_free = k_new_list("ShareErrors", sizeof(SHAREERRORS), ALLOC_SHAREERRORS, LIMIT_SHAREERRORS, diff --git a/src/ckdb.h b/src/ckdb.h index f19b174a..031f79d5 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -51,7 +51,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.5" -#define CKDB_VERSION DB_VERSION"-1.984" +#define CKDB_VERSION DB_VERSION"-1.985" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -2814,6 +2814,7 @@ extern bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, extern double coinbase_reward(int32_t height); extern double workinfo_pps(K_ITEM *w_item, int64_t workinfoid); extern cmp_t cmp_shares(K_ITEM *a, K_ITEM *b); +extern cmp_t cmp_shares_db(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b); extern void dsp_sharesummary(K_ITEM *item, FILE *stream); extern cmp_t cmp_sharesummary(K_ITEM *a, K_ITEM *b); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index c8e8b3c9..77cdca55 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -2333,6 +2333,38 @@ cmp_t cmp_shares(K_ITEM *a, K_ITEM *b) return c; } +/* order by workinfoid asc,userid asc,workername asc,enonce1 asc,nonce2 asc, + * nonce asc,expirydate desc + * i.e. match the DB table index so duplicates are ignored and all new shares_db + * can always go in the DB */ +cmp_t cmp_shares_db(K_ITEM *a, K_ITEM *b) +{ + SHARES *sa, *sb; + DATA_SHARES(sa, a); + DATA_SHARES(sb, b); + cmp_t c = CMP_BIGINT(sa->workinfoid, sb->workinfoid); + if (c == 0) { + c = CMP_BIGINT(sa->userid, sb->userid); + if (c == 0) { + c = CMP_STR(sa->workername, sb->workername); + if (c == 0) { + c = CMP_STR(sa->enonce1, sb->enonce1); + if (c == 0) { + c = CMP_STR(sa->nonce2, sb->nonce2); + if (c == 0) { + c = CMP_STR(sa->nonce, sb->nonce); + if (c == 0) { + c = CMP_TV(sb->expirydate, + sa->expirydate); + } + } + } + } + } + } + return c; +} + // order by workinfoid asc,userid asc,createdate asc,nonce asc,expirydate desc cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b) { diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index 8d707403..c7747561 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -3625,7 +3625,7 @@ discard: static void shareerrors_process_early(PGconn *conn, int64_t good_wid, tv_t *good_cd, K_TREE *trf_root); -// DB Shares are stored by by the summariser to ensure the reload is correct +// DB Shares are stored by the summariser to ensure the reload is correct bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername, char *clientid, char *errn, char *enonce1, char *nonce2, char *nonce, char *diff, char *sdiff, char *secondaryuserid, @@ -3640,7 +3640,6 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername USERS *users; bool ok = false; char *st = NULL; - int errn_int; LOGDEBUG("%s(): %s/%s/%s/%s/%ld,%ld", __func__, @@ -3649,13 +3648,10 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername FREENULL(st); TXT_TO_DOUBLE("sdiff", sdiff, sdiff_amt); - TXT_TO_INT("errn", errn, errn_int); K_WLOCK(shares_free); s_item = k_unlink_head(shares_free); - // Don't store duplicates since they will already exist - if (errn_int != SE_DUPE && share_min_sdiff > 0 && - sdiff_amt >= share_min_sdiff) + if (share_min_sdiff > 0 && sdiff_amt >= share_min_sdiff) s2_item = k_unlink_head(shares_free); K_WUNLOCK(shares_free); @@ -3731,7 +3727,9 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername add_to_ktree(shares_early_root, s_item); k_add_head(shares_early_store, s_item); if (s2_item) { - // Just ignore duplicates + /* Just ignore duplicates - this matches the DB index + N.B. a duplicate share doesn't have to be SE_DUPE, + two shares can be SE_NONE and SE_STALE */ tmp_item = find_in_ktree(shares_db_root, s2_item, ctx); if (tmp_item == NULL) { // Store them in advance - always