From 85eb2cef33fcf3e5c785d54b172eb3e8f932e3cb Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sun, 13 Oct 2013 22:15:48 +0200 Subject: [PATCH 1/2] Do not use the redundant BestInvalidWork record in the block database. As block index entries have a flag for marking invalid blocks, the 'best invalid work' information can be derived from there. In addition, remove the global from main.h --- src/main.cpp | 26 ++++++++++++-------------- src/main.h | 1 - src/txdb.cpp | 6 +----- src/txdb.h | 1 - 4 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 640fbac8b..6a679fcad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,7 @@ unsigned int nTransactionsUpdated = 0; map mapBlockIndex; CChain chainActive; -uint256 nBestInvalidWork = 0; +CBlockIndex *pindexBestInvalid; set setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed int64 nTimeBestReceived = 0; int nScriptCheckThreads = 0; @@ -1349,7 +1349,7 @@ void CheckForkWarningConditions() if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72) pindexBestForkTip = NULL; - if (pindexBestForkTip || nBestInvalidWork > chainActive.Tip()->nChainWork + (chainActive.Tip()->GetBlockWork() * 6).getuint256()) + if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (chainActive.Tip()->GetBlockWork() * 6).getuint256())) { if (!fLargeWorkForkFound) { @@ -1416,10 +1416,13 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) void static InvalidChainFound(CBlockIndex* pindexNew) { - if (pindexNew->nChainWork > nBestInvalidWork) + if (!pindexBestInvalid || pindexNew->nChainWork > pindexBestInvalid->nChainWork) { - nBestInvalidWork = pindexNew->nChainWork; - pblocktree->WriteBestInvalidWork(CBigNum(nBestInvalidWork)); + pindexBestInvalid = pindexNew; + // The current code doesn't actually read the BestInvalidWork entry in + // the block database anymore, as it is derived from the flags in block + // index entry. We only write it for backward compatibility. + pblocktree->WriteBestInvalidWork(CBigNum(pindexBestInvalid->nChainWork)); uiInterface.NotifyBlocksChanged(); } LogPrintf("InvalidChainFound: invalid block=%s height=%d log2_work=%.8g date=%s\n", @@ -2769,6 +2772,8 @@ bool static LoadBlockIndexDB() pindex->nChainTx = (pindex->pprev ? pindex->pprev->nChainTx : 0) + pindex->nTx; if ((pindex->nStatus & BLOCK_VALID_MASK) >= BLOCK_VALID_TRANSACTIONS && !(pindex->nStatus & BLOCK_FAILED_MASK)) setBlockIndexValid.insert(pindex); + if (pindex->nStatus & BLOCK_FAILED_MASK && (!pindexBestInvalid || pindex->nChainWork > pindexBestInvalid->nChainWork)) + pindexBestInvalid = pindex; } // Load block file info @@ -2777,11 +2782,6 @@ bool static LoadBlockIndexDB() if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile)) LogPrintf("LoadBlockIndexDB(): last block file info: %s\n", infoLastBlockFile.ToString().c_str()); - // Load nBestInvalidWork, OK if it doesn't exist - CBigNum bnBestInvalidWork; - pblocktree->ReadBestInvalidWork(bnBestInvalidWork); - nBestInvalidWork = bnBestInvalidWork.getuint256(); - // Check whether we need to continue reindexing bool fReindexing = false; pblocktree->ReadReindexing(fReindexing); @@ -2791,12 +2791,10 @@ bool static LoadBlockIndexDB() pblocktree->ReadFlag("txindex", fTxIndex); LogPrintf("LoadBlockIndexDB(): transaction index %s\n", fTxIndex ? "enabled" : "disabled"); - // Load hashBestChain pointer to end of best chain + // Load pointer to end of best chain chainActive.SetTip(pcoinsTip->GetBestBlock()); if (chainActive.Tip() == NULL) return true; - - // register best chain LogPrintf("LoadBlockIndexDB(): hashBestChain=%s height=%d date=%s\n", chainActive.Tip()->GetBlockHash().ToString().c_str(), chainActive.Height(), DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()).c_str()); @@ -2882,7 +2880,7 @@ void UnloadBlockIndex() mapBlockIndex.clear(); setBlockIndexValid.clear(); chainActive.SetTip(NULL); - nBestInvalidWork = 0; + pindexBestInvalid = NULL; } bool LoadBlockIndex() diff --git a/src/main.h b/src/main.h index b56a4a5e1..77e479269 100644 --- a/src/main.h +++ b/src/main.h @@ -74,7 +74,6 @@ extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern std::map mapBlockIndex; extern std::set setBlockIndexValid; -extern uint256 nBestInvalidWork; extern unsigned int nTransactionsUpdated; extern uint64 nLastBlockTx; extern uint64 nLastBlockSize; diff --git a/src/txdb.cpp b/src/txdb.cpp index 5e7b78296..27d6caf4d 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -74,13 +74,9 @@ bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex) return Write(make_pair('b', blockindex.GetBlockHash()), blockindex); } -bool CBlockTreeDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork) -{ - return Read('I', bnBestInvalidWork); -} - bool CBlockTreeDB::WriteBestInvalidWork(const CBigNum& bnBestInvalidWork) { + // Obsolete; only written for backward compatibility. return Write('I', bnBestInvalidWork); } diff --git a/src/txdb.h b/src/txdb.h index e3560a9c5..b555be3de 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -35,7 +35,6 @@ private: void operator=(const CBlockTreeDB&); public: bool WriteBlockIndex(const CDiskBlockIndex& blockindex); - bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork); bool WriteBestInvalidWork(const CBigNum& bnBestInvalidWork); bool ReadBlockFileInfo(int nFile, CBlockFileInfo &fileinfo); bool WriteBlockFileInfo(int nFile, const CBlockFileInfo &fileinfo); From caca6aa4eb54b71b5e4e9ccfa69341f985b178d9 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 14 Oct 2013 02:13:44 +0200 Subject: [PATCH 2/2] Make some globals in main non-public. This means they are declared static, and their extern definition in main.h is removed. Also moved CBlockIndexWorkComparator to the .cpp file. --- src/main.cpp | 27 +++++++++++++++++++++------ src/main.h | 20 -------------------- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 6a679fcad..f7f5ff126 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,8 +33,6 @@ unsigned int nTransactionsUpdated = 0; map mapBlockIndex; CChain chainActive; -CBlockIndex *pindexBestInvalid; -set setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed int64 nTimeBestReceived = 0; int nScriptCheckThreads = 0; bool fImporting = false; @@ -65,7 +63,28 @@ const string strMessageMagic = "Bitcoin Signed Message:\n"; // Settings int64 nTransactionFee = 0; +// Internal stuff +namespace { +struct CBlockIndexWorkComparator +{ + bool operator()(CBlockIndex *pa, CBlockIndex *pb) { + if (pa->nChainWork > pb->nChainWork) return false; + if (pa->nChainWork < pb->nChainWork) return true; + + if (pa->GetBlockHash() < pb->GetBlockHash()) return false; + if (pa->GetBlockHash() > pb->GetBlockHash()) return true; + + return false; // identical blocks + } +}; + +CBlockIndex *pindexBestInvalid; +set setBlockIndexValid; // may contain all CBlockIndex*'s that have validness >=BLOCK_VALID_TRANSACTIONS, and must contain those who aren't failed +CCriticalSection cs_LastBlockFile; +CBlockFileInfo infoLastBlockFile; +int nLastBlockFile = 0; +} ////////////////////////////////////////////////////////////////////////////// // @@ -2694,10 +2713,6 @@ bool CheckDiskSpace(uint64 nAdditionalBytes) return true; } -CCriticalSection cs_LastBlockFile; -CBlockFileInfo infoLastBlockFile; -int nLastBlockFile = 0; - FILE* OpenDiskFile(const CDiskBlockPos &pos, const char *prefix, bool fReadOnly) { if (pos.IsNull()) diff --git a/src/main.h b/src/main.h index 77e479269..d568d8e6b 100644 --- a/src/main.h +++ b/src/main.h @@ -26,8 +26,6 @@ class CAddress; class CInv; class CNode; -struct CBlockIndexWorkComparator; - /** The maximum allowed size for a serialized block, in bytes (network rule) */ static const unsigned int MAX_BLOCK_SIZE = 1000000; /** The maximum size for mined blocks */ @@ -73,7 +71,6 @@ extern CScript COINBASE_FLAGS; extern CCriticalSection cs_main; extern std::map mapBlockIndex; -extern std::set setBlockIndexValid; extern unsigned int nTransactionsUpdated; extern uint64 nLastBlockTx; extern uint64 nLastBlockSize; @@ -646,10 +643,6 @@ public: } }; -extern CCriticalSection cs_LastBlockFile; -extern CBlockFileInfo infoLastBlockFile; -extern int nLastBlockFile; - enum BlockStatus { BLOCK_VALID_UNKNOWN = 0, BLOCK_VALID_HEADER = 1, // parsed, version ok, hash satisfies claimed PoW, 1 <= vtx count <= max, timestamp not in future @@ -849,19 +842,6 @@ public: } }; -struct CBlockIndexWorkComparator -{ - bool operator()(CBlockIndex *pa, CBlockIndex *pb) { - if (pa->nChainWork > pb->nChainWork) return false; - if (pa->nChainWork < pb->nChainWork) return true; - - if (pa->GetBlockHash() < pb->GetBlockHash()) return false; - if (pa->GetBlockHash() > pb->GetBlockHash()) return true; - - return false; // identical blocks - } -}; - /** Used to marshal pointers into hashes for db storage. */