From ac7e41c57093f4f4df70c7de110d4c7874b896e1 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 5 May 2016 18:12:08 +1000 Subject: [PATCH] ckdb - separate out the block orphan check and call it more often --- src/ckdb.c | 57 ++++++++++++++++++++++++++++++++- src/ckdb.h | 3 +- src/ckdb_btc.c | 83 ++++++++++++++++++++++++++++++++++++++---------- src/ckdb_crypt.c | 2 +- src/klist.h | 2 +- src/ktree.h | 2 +- 6 files changed, 128 insertions(+), 21 deletions(-) diff --git a/src/ckdb.c b/src/ckdb.c index 12d57b79..4e1e8893 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -3774,6 +3774,46 @@ static void *breaker(void *arg) return NULL; } +static void check_orphans() +{ + K_TREE_CTX ctx[1]; + K_ITEM *b_item; + BLOCKS *blocks = NULL; + uint32_t currhi = 0; + + K_RLOCK(blocks_free); + // Find the most recent block BLOCKS_NEW or BLOCKS_CONFIRM + b_item = last_in_ktree(blocks_root, ctx); + while (b_item) { + DATA_BLOCKS(blocks, b_item); + if (!blocks->ignore && + CURRENT(&(blocks->expirydate)) && + (blocks->confirmed[0] == BLOCKS_NEW || + blocks->confirmed[0] == BLOCKS_CONFIRM)) + break; + b_item = prev_in_ktree(ctx); + } + K_RUNLOCK(blocks_free); + + // None + if (!b_item) + return; + + K_RLOCK(workinfo_free); + if (workinfo_current) { + WORKINFO *wic; + DATA_WORKINFO(wic, workinfo_current); + currhi = wic->height - 1; + } + K_RUNLOCK(workinfo_free); + + LOGDEBUG("%s() currhi=%"PRIu32" block=%"PRIu32, + __func__, currhi, blocks->height); + // Keep checking for 6 blocks + if (currhi && (currhi - blocks->height) < 6) + btc_orphancheck(blocks); +} + static void check_blocks() { K_TREE_CTX ctx[1]; @@ -3800,7 +3840,8 @@ static void check_blocks() if (!b_item) return; - btc_blockstatus(blocks); + if (btc_orphancheck(blocks)) + btc_blockstatus(blocks); } static void pplns_block(BLOCKS *blocks) @@ -4043,6 +4084,7 @@ static void summarise_blocks() static void *summariser(__maybe_unused void *arg) { + bool orphan_check = false; int i; pthread_detach(pthread_self()); @@ -4073,6 +4115,19 @@ static void *summariser(__maybe_unused void *arg) if (!everyone_die) sleep(1); } + + if (everyone_die) + break; + else { + orphan_check = !orphan_check; + // Check every 2nd time + if (orphan_check) + check_orphans(); + } + + if (!everyone_die) + sleep(1); + if (everyone_die) break; else diff --git a/src/ckdb.h b/src/ckdb.h index 6702e33e..e37b3d2f 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -52,7 +52,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.5" -#define CKDB_VERSION DB_VERSION"-2.105" +#define CKDB_VERSION DB_VERSION"-2.106" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -3377,6 +3377,7 @@ extern struct CMDS ckdb_cmds[]; // *** extern bool btc_valid_address(char *addr); +extern bool btc_orphancheck(BLOCKS *blocks); extern void btc_blockstatus(BLOCKS *blocks); // *** diff --git a/src/ckdb_btc.c b/src/ckdb_btc.c index 1e258800..caea9e78 100644 --- a/src/ckdb_btc.c +++ b/src/ckdb_btc.c @@ -1,5 +1,5 @@ /* - * Copyright 2014 Andrew Smith + * Copyright 2014-2016 Andrew Smith * Copyright 2014 Con Kolivas * * This program is free software; you can redistribute it and/or modify it @@ -304,28 +304,20 @@ bool btc_valid_address(char *addr) return valid; } -// Check for orphan or update confirm count -void btc_blockstatus(BLOCKS *blocks) +// Check orphan, returns true only if all OK and not an orphan +bool btc_orphancheck(BLOCKS *blocks) { char hash[TXT_BIG+1]; char *blockhash; - int32_t confirms; size_t len; tv_t now; bool ok; - setnow(&now); - LOGDEBUG("%s() checking %d %s", - __func__, - blocks->height, blocks->blockhash); + __func__, blocks->height, blocks->blockhash); - // Caller must check this to avoid resending it every time - if (blocks->ignore) { - LOGERR("%s() ignored block %d passed", - __func__, blocks->height); - return; - } + if (blocks->ignore) + return false; len = strlen(blocks->blockhash); if (len != SHA256SIZHEX) { @@ -336,7 +328,7 @@ void btc_blockstatus(BLOCKS *blocks) * This should never happen */ blocks->ignore = true; - return; + return false; } dbhash2btchash(blocks->blockhash, hash, sizeof(hash)); @@ -344,7 +336,12 @@ void btc_blockstatus(BLOCKS *blocks) blockhash = btc_blockhash(blocks->height); // Something's amiss - let it try again later if (!blockhash) - return; + return false; + + if (strlen(blockhash) != SHA256SIZHEX) { + free(blockhash); + return false; + } if (strcmp(blockhash, hash) != 0) { LOGERR("%s() flagging block %d as %s pool=%s btc=%s", @@ -352,6 +349,8 @@ void btc_blockstatus(BLOCKS *blocks) blocks_confirmed(BLOCKS_ORPHAN_STR), hash, blockhash); + setnow(&now); + ok = blocks_add(NULL, blocks->height, blocks->blockhash, BLOCKS_ORPHAN_STR, EMPTY, @@ -363,6 +362,55 @@ void btc_blockstatus(BLOCKS *blocks) if (!ok) blocks->ignore = true; + free(blockhash); + return false; + } + + free(blockhash); + return true; +} + +// Check to update confirm count +void btc_blockstatus(BLOCKS *blocks) +{ + char hash[TXT_BIG+1]; + char *blockhash; + int32_t confirms; + size_t len; + tv_t now; + bool ok; + + LOGDEBUG("%s() checking %d %s", + __func__, blocks->height, blocks->blockhash); + + // Caller must check this to avoid resending it every time + if (blocks->ignore) { + LOGERR("%s() ignored block %d passed", + __func__, blocks->height); + return; + } + + len = strlen(blocks->blockhash); + if (len != SHA256SIZHEX) { + LOGERR("%s() invalid blockhash size %d (%d) for block %d", + __func__, (int)len, SHA256SIZHEX, blocks->height); + + /* So we don't keep repeating the message + * This should never happen */ + blocks->ignore = true; + + return; + } + + dbhash2btchash(blocks->blockhash, hash, sizeof(hash)); + + blockhash = btc_blockhash(blocks->height); + // Something's amiss - let it try again later + if (!blockhash) + return; + + if (strlen(blockhash) != SHA256SIZHEX) { + free(blockhash); return; } @@ -373,6 +421,8 @@ void btc_blockstatus(BLOCKS *blocks) blocks_confirmed(BLOCKS_42_STR), confirms, BLOCKS_42_VALUE); + setnow(&now); + ok = blocks_add(NULL, blocks->height, blocks->blockhash, BLOCKS_42_STR, EMPTY, @@ -384,4 +434,5 @@ void btc_blockstatus(BLOCKS *blocks) if (!ok) blocks->ignore = true; } + free(blockhash); } diff --git a/src/ckdb_crypt.c b/src/ckdb_crypt.c index e21cddf4..524b0e6c 100644 --- a/src/ckdb_crypt.c +++ b/src/ckdb_crypt.c @@ -1,5 +1,5 @@ /* - * Copyright 2015 Andrew Smith + * Copyright 2015-2016 Andrew Smith * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/klist.h b/src/klist.h index 5f4f303e..c1712dc4 100644 --- a/src/klist.h +++ b/src/klist.h @@ -1,6 +1,6 @@ /* * Copyright 2013-2014 Andrew Smith - BlackArrow Ltd - * Copyright 2015 Andrew Smith + * Copyright 2015-2016 Andrew Smith * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free diff --git a/src/ktree.h b/src/ktree.h index 81a50bfb..715bdcf1 100644 --- a/src/ktree.h +++ b/src/ktree.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2015 Andrew Smith + * Copyright 1995-2016 Andrew Smith * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free