From 13f50e33294155384caf59b33a15b4077f4580e3 Mon Sep 17 00:00:00 2001 From: kanoi Date: Tue, 9 Sep 2014 14:44:37 +1000 Subject: [PATCH] ckdb - fix block tree corruptions --- src/ckdb.c | 55 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/ckdb.c b/src/ckdb.c index b37f47f7..ac2784fa 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -47,7 +47,7 @@ #define DB_VLOCK "1" #define DB_VERSION "0.9" -#define CKDB_VERSION DB_VERSION"-0.260" +#define CKDB_VERSION DB_VERSION"-0.270" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -674,7 +674,8 @@ static const tv_t date_begin = { DATE_BEGIN, 0L }; #define PQPARAM14 PQPARAM8 ",$9,$10,$11,$12,$13,$14" #define PQPARAM15 PQPARAM8 ",$9,$10,$11,$12,$13,$14,$15" #define PQPARAM16 PQPARAM8 ",$9,$10,$11,$12,$13,$14,$15,$16" -#define PQPARAM27 PQPARAM16 ",$17,$18,$19,$20,$21,$22,$23,$24,$25,$26,$27" +#define PQPARAM22 PQPARAM16 ",$17,$18,$19,$20,$21,$22" +#define PQPARAM27 PQPARAM22 ",$23,$24,$25,$26,$27" #define PARCHK(_par, _params) do { \ if (_par != (int)(sizeof(_params)/sizeof(_params[0]))) { \ @@ -1302,7 +1303,9 @@ typedef struct blocks { #define BLOCKS_ORPHAN_STR "O" #define BLOCKS_STATSPENDING FALSE_CHR +#define BLOCKS_STATSPENDING_STR FALSE_STR #define BLOCKS_STATSCONFIRMED TRUE_CHR +#define BLOCKS_STATSCONFIRMED_STR TRUE_STR static const char *blocks_new = "New"; static const char *blocks_confirm = "1-Confirm"; @@ -5413,9 +5416,10 @@ static void dsp_blocks(K_ITEM *item, FILE *stream) dsp_hash(b->blockhash, hash_dsp, sizeof(hash_dsp)); tv_to_buf(&(b->createdate), createdate_buf, sizeof(createdate_buf)); tv_to_buf(&(b->expirydate), expirydate_buf, sizeof(expirydate_buf)); - fprintf(stream, " hi=%d hash='%.16s' uid=%"PRId64" w='%s' " - "cd=%s ed=%s\n", - b->height, hash_dsp, b->userid, b->workername, + fprintf(stream, " hi=%d hash='%.16s' conf=%s uid=%"PRId64 + " w='%s' sconf=%s cd=%s ed=%s\n", + b->height, hash_dsp, b->confirmed, b->userid, + b->workername, b->statsconfirmed, createdate_buf, expirydate_buf); } } @@ -5525,12 +5529,12 @@ static bool blocks_stats(PGconn *conn, int32_t height, char *blockhash, K_RUNLOCK(blocks_free); if (!old_b_item) { - LOGERR("%s(): Non-existent Block: %s/...%s", + LOGERR("%s(): Non-existent Block: %d/...%s", __func__, height, hash_dsp); return false; } - DATA_BLOCKS_NULL(oldblocks, old_b_item); + DATA_BLOCKS(oldblocks, old_b_item); K_WLOCK(blocks_free); b_item = k_unlink_head(blocks_free); @@ -5659,7 +5663,7 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, BLOCKS *row, *oldblocks; USERS *users; char *upd, *ins; - char *params[11 + HISTORYDATECOUNT]; + char *params[17 + HISTORYDATECOUNT]; bool ok = false, update_old = false; int par = 0; char want = '?'; @@ -5678,14 +5682,16 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, dsp_hash(blockhash, hash_dsp, sizeof(hash_dsp)); - K_WLOCK(blocks_free); + K_RLOCK(blocks_free); old_b_item = find_blocks(row->height, blockhash); + K_RUNLOCK(blocks_free); DATA_BLOCKS_NULL(oldblocks, old_b_item); switch (confirmed[0]) { case BLOCKS_NEW: // None should exist - so must be a duplicate if (old_b_item) { + K_WLOCK(blocks_free); k_add_head(blocks_free, b_item); K_WUNLOCK(blocks_free); if (!igndup) { @@ -5699,7 +5705,6 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, } return true; } - K_WUNLOCK(blocks_free); K_RLOCK(users_free); u_item = find_users(username); @@ -5719,6 +5724,13 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, STRNCPY(row->nonce2, nonce2); STRNCPY(row->nonce, nonce); TXT_TO_BIGINT("reward", reward, row->reward); + // Specify them + row->diffacc = 0; + row->diffinv = 0; + row->shareacc = 0; + row->shareinv = 0; + row->elapsed = 0; + STRNCPY(row->statsconfirmed, BLOCKS_STATSPENDING_STR); HISTORYDATEINIT(row, cd, by, code, inet); HISTORYDATETRANSFER(trf_root, row); @@ -5735,14 +5747,21 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, params[par++] = str_to_buf(row->nonce, NULL, 0); params[par++] = bigint_to_buf(row->reward, NULL, 0); params[par++] = str_to_buf(row->confirmed, NULL, 0); + params[par++] = double_to_buf(row->diffacc, NULL, 0); + params[par++] = double_to_buf(row->diffinv, NULL, 0); + params[par++] = double_to_buf(row->shareacc, NULL, 0); + params[par++] = double_to_buf(row->shareinv, NULL, 0); + params[par++] = bigint_to_buf(row->elapsed, NULL, 0); + params[par++] = str_to_buf(row->statsconfirmed, NULL, 0); HISTORYDATEPARAMS(params, par, row); PARCHK(par, params); - // db default stats values ins = "insert into blocks " "(height,blockhash,workinfoid,userid,workername," - "clientid,enonce1,nonce2,nonce,reward,confirmed" - HISTORYDATECONTROL ") values (" PQPARAM16 ")"; + "clientid,enonce1,nonce2,nonce,reward,confirmed," + "diffacc,diffinv,shareacc,shareinv,elapsed," + "statsconfirmed" + HISTORYDATECONTROL ") values (" PQPARAM22 ")"; if (conn == NULL) { conn = dbconnect(); @@ -5760,7 +5779,6 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, case BLOCKS_42: // These shouldn't be possible until startup completes if (!startup_complete) { - K_WUNLOCK(blocks_free); tv_to_buf(cd, cd_buf, sizeof(cd_buf)); LOGERR("%s(): Status: %s invalid during startup. " "Ignored: Block: %s/...%s/%s", @@ -5772,7 +5790,6 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, want = BLOCKS_CONFIRM; case BLOCKS_CONFIRM: if (!old_b_item) { - K_WUNLOCK(blocks_free); tv_to_buf(cd, cd_buf, sizeof(cd_buf)); LOGERR("%s(): Can't %s a non-existent Block: %s/...%s/%s", __func__, blocks_confirmed(confirmed), @@ -5782,8 +5799,6 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, if (confirmed[0] == BLOCKS_CONFIRM) want = BLOCKS_NEW; if (oldblocks->confirmed[0] != want) { - k_add_head(blocks_free, b_item); - K_WUNLOCK(blocks_free); // No mismatch messages during startup if (startup_complete) { tv_to_buf(cd, cd_buf, sizeof(cd_buf)); @@ -5796,7 +5811,6 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, } goto flail; } - K_WUNLOCK(blocks_free); upd = "update blocks set expirydate=$1 where blockhash=$2 and expirydate=$3"; par = 0; @@ -5899,7 +5913,6 @@ static bool blocks_add(PGconn *conn, char *height, char *blockhash, res = PQexec(conn, "Commit", CKPQ_WRITE); break; default: - K_WUNLOCK(blocks_free); LOGERR("%s(): %s.failed.invalid confirm='%s'", __func__, id, confirmed); goto flail; @@ -6027,7 +6040,6 @@ static bool blocks_fill(PGconn *conn) n = PQntuples(res); LOGDEBUG("%s(): tree build count %d", __func__, n); ok = true; - K_WLOCK(blocks_free); for (i = 0; i < n; i++) { item = k_unlink_head(blocks_free); DATA_BLOCKS(row, item); @@ -6133,7 +6145,6 @@ static bool blocks_fill(PGconn *conn) if (!ok) k_add_head(blocks_free, item); - K_WUNLOCK(blocks_free); PQclear(res); if (ok) { @@ -6148,10 +6159,8 @@ void blocks_reload() { PGconn *conn = dbconnect(); - K_WLOCK(blocks_free); blocks_root = free_ktree(blocks_root, NULL); k_list_transfer_to_head(blocks_store, blocks_free); - K_WUNLOCK(blocks_free); blocks_fill(conn);