From c3df1b8747750b8ef4a43738be8cfc28f8dffc88 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Thu, 24 Jan 2019 17:16:42 +0800 Subject: [PATCH] add auto purge of orphans from before notarisation. --- src/komodo.h | 2 ++ src/main.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.h | 2 +- 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/komodo.h b/src/komodo.h index 4a8bd7d96..62310a0ed 100644 --- a/src/komodo.h +++ b/src/komodo.h @@ -707,6 +707,8 @@ int32_t komodo_voutupdate(int32_t *isratificationp,int32_t notaryid,uint8_t *scr komodo_stateupdate(height,0,0,0,zero,0,0,0,0,0,0,0,0,0,0,sp->MoM,sp->MoMdepth); if ( ASSETCHAINS_SYMBOL[0] != 0 ) printf("[%s] ht.%d NOTARIZED.%d %s.%s %sTXID.%s lens.(%d %d) MoM.%s %d\n",ASSETCHAINS_SYMBOL,height,*notarizedheightp,ASSETCHAINS_SYMBOL[0]==0?"KMD":ASSETCHAINS_SYMBOL,srchash.ToString().c_str(),ASSETCHAINS_SYMBOL[0]==0?"BTC":"KMD",desttxid.ToString().c_str(),opretlen,len,sp->MoM.ToString().c_str(),sp->MoMdepth); + if (RemoveOrphanedBlocks(*notarizedheightp)) + fprintf(stderr, "Sucessfully removed all known orphaned blocks before height %d\n",*notarizedheightp); if ( ASSETCHAINS_SYMBOL[0] == 0 ) { if ( signedfp == 0 ) diff --git a/src/main.cpp b/src/main.cpp index 614f13d44..a2980dea8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1979,6 +1979,72 @@ bool GetAddressUnspent(uint160 addressHash, int type, return true; } +struct CompareBlocksByHeightMain +{ + bool operator()(const CBlockIndex* a, const CBlockIndex* b) const + { + /* Make sure that unequal blocks with the same height do not compare + equal. Use the pointers themselves to make a distinction. */ + + if (a->GetHeight() != b->GetHeight()) + return (a->GetHeight() > b->GetHeight()); + + return a < b; + } +}; + +bool RemoveOrphanedBlocks(int32_t notarized_height) +{ + LOCK(cs_main); + std::vector prunedblocks; + std::set setTips; + int32_t n = 0; + // get notarised timestamp and use this as a backup incase the forked block has no height. + // we -600 to make sure the time is within future block constraints. + uint32_t notarized_timestamp = komodo_heightstamp(notarized_height)-600; + fprintf(stderr, "removing oprhans from before %d\n", notarized_height); + // Most of this code is a direct copy from GetChainTips RPC. Which gives a return of all + // blocks that are not in the main chain. + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + { + n++; + setTips.insert(item.second); + } + n = 0; + BOOST_FOREACH(const PAIRTYPE(const uint256, CBlockIndex*)& item, mapBlockIndex) + { + const CBlockIndex* pprev=0; + n++; + if ( item.second != 0 ) + pprev = item.second->pprev; + if (pprev) + setTips.erase(pprev); + } + const CBlockIndex *forked; + BOOST_FOREACH(const CBlockIndex* block, setTips) + { + // We skip anything over notarised height to avoid breaking normal consensus rules. + if ( block->GetHeight() > notarized_height || block->nTime > notarized_timestamp ) + continue; + // We can also check if the block is in the active chain as a backup test. + forked = chainActive.FindFork(block); + // Here we save each forked block to a vector for removal later. + if ( forked != 0 ) + prunedblocks.push_back(block); + } + if (pblocktree->EraseBatchSync(prunedblocks)) + { + // Blocks cleared from disk succesfully, using internal DB batch erase function. Which exists, but has never been used before. + // We need to try and clear the block index from mapBlockIndex now, otherwise node will need a restart. + BOOST_FOREACH(const CBlockIndex* block, prunedblocks) + { + mapBlockIndex.erase(block->GetBlockHash()); + } + return true; + } + return false; +} + /*uint64_t myGettxout(uint256 hash,int32_t n) { CCoins coins; diff --git a/src/main.h b/src/main.h index 463c91237..35c01c23a 100644 --- a/src/main.h +++ b/src/main.h @@ -806,7 +806,7 @@ bool GetAddressUnspent(uint160 addressHash, int type, bool WriteBlockToDisk(CBlock& block, CDiskBlockPos& pos, const CMessageHeader::MessageStartChars& messageStart); bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos,bool checkPOW); bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex,bool checkPOW); - +bool RemoveOrphanedBlocks(int32_t notarized_height); /** Functions for validating blocks and updating the block tree */