changeset 3655:fbeafbac210f draft

Use singleton block tree database instance
author Pieter Wuille <pieter.wuille@gmail.com>
date Mon, 03 Sep 2012 15:26:57 +0200
parents 6c563b4f0533
children aff53d102f35
files src/db.cpp src/db.h src/init.cpp src/main.cpp src/main.h src/test/test_bitcoin.cpp
diffstat 6 files changed, 61 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -273,7 +273,7 @@
 
 static bool IsChainFile(std::string strFile)
 {
-    if (strFile == "coins.dat" || strFile == "chain.dat")
+    if (strFile == "coins.dat" || strFile == "blktree.dat")
         return true;
 
     return false;
@@ -483,7 +483,7 @@
 
 
 //
-// CChainDB and CCoinsDB
+// CBlockTreeDB and CCoinsDB
 //
 
 bool CCoinsDB::HaveCoins(uint256 hash) {
@@ -504,7 +504,7 @@
         return Write(make_pair('c', hash), coins);
 }
 
-bool CChainDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
+bool CBlockTreeDB::WriteBlockIndex(const CDiskBlockIndex& blockindex)
 {
     return Write(make_pair('b', blockindex.GetBlockHash()), blockindex);
 }
@@ -519,29 +519,29 @@
     return Write('B', hashBestChain);
 }
 
-bool CChainDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork)
+bool CBlockTreeDB::ReadBestInvalidWork(CBigNum& bnBestInvalidWork)
 {
     return Read('I', bnBestInvalidWork);
 }
 
-bool CChainDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork)
+bool CBlockTreeDB::WriteBestInvalidWork(CBigNum bnBestInvalidWork)
 {
     return Write('I', bnBestInvalidWork);
 }
 
-bool CChainDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
+bool CBlockTreeDB::WriteBlockFileInfo(int nFile, const CBlockFileInfo &info) {
     return Write(make_pair('f', nFile), info);
 }
 
-bool CChainDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
+bool CBlockTreeDB::ReadBlockFileInfo(int nFile, CBlockFileInfo &info) {
     return Read(make_pair('f', nFile), info);
 }
 
-bool CChainDB::WriteLastBlockFile(int nFile) {
+bool CBlockTreeDB::WriteLastBlockFile(int nFile) {
     return Write('l', nFile);
 }
 
-bool CChainDB::ReadLastBlockFile(int &nFile) {
+bool CBlockTreeDB::ReadLastBlockFile(int &nFile) {
     return Read('l', nFile);
 }
 
@@ -601,9 +601,9 @@
     return pindexNew;
 }
 
-bool LoadBlockIndex(CChainDB &chaindb)
+bool LoadBlockIndexDB()
 {
-    if (!chaindb.LoadBlockIndexGuts())
+    if (!pblocktree->LoadBlockIndexGuts())
         return false;
 
     if (fRequestShutdown)
@@ -628,9 +628,9 @@
     }
 
     // Load block file info
-    chaindb.ReadLastBlockFile(nLastBlockFile);
+    pblocktree->ReadLastBlockFile(nLastBlockFile);
     printf("LoadBlockIndex(): last block file = %i\n", nLastBlockFile);
-    if (chaindb.ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
+    if (pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile))
         printf("LoadBlockIndex(): last block file: %s\n", infoLastBlockFile.ToString().c_str());
  
     // Load hashBestChain pointer to end of best chain
@@ -656,7 +656,7 @@
         DateTimeStrFormat("%x %H:%M:%S", pindexBest->GetBlockTime()).c_str());
 
     // Load bnBestInvalidWork, OK if it doesn't exist
-    chaindb.ReadBestInvalidWork(bnBestInvalidWork);
+    pblocktree->ReadBestInvalidWork(bnBestInvalidWork);
 
     // Verify blocks in the best chain
     int nCheckLevel = GetArg("-checklevel", 1);
@@ -693,7 +693,7 @@
 
 
 
-bool CChainDB::LoadBlockIndexGuts()
+bool CBlockTreeDB::LoadBlockIndexGuts()
 {
     // Get database cursor
     Dbc* pcursor = GetCursor();
--- a/src/db.h
+++ b/src/db.h
@@ -348,14 +348,14 @@
 };
 
 
-/** Access to the block database (chain.dat) */
-class CChainDB : public CDB
+/** Access to the block database (blktree.dat) */
+class CBlockTreeDB : public CDB
 {
 public:
-    CChainDB(const char* pszMode="r+") : CDB("chain.dat", pszMode) { }
+    CBlockTreeDB(const char* pszMode="r+") : CDB("blktree.dat", pszMode) { }
 private:
-    CChainDB(const CChainDB&);
-    void operator=(const CChainDB&);
+    CBlockTreeDB(const CBlockTreeDB&);
+    void operator=(const CBlockTreeDB&);
 public:
     bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
     bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
@@ -368,7 +368,7 @@
 };
 
 
-bool LoadBlockIndex(CChainDB &chaindb);
+bool LoadBlockIndexDB();
 
 
 /** Access to the (IP) address database (peers.dat) */
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -79,8 +79,10 @@
         {
             LOCK(cs_main);
             pcoinsTip->Flush();
+            pblocktree->Flush();
             delete pcoinsTip;
             delete pcoinsdbview;
+            delete pblocktree;
         }
         bitdb.Flush(true);
         boost::filesystem::remove(GetPidFile());
@@ -650,6 +652,7 @@
     uiInterface.InitMessage(_("Loading block index..."));
     printf("Loading block index...\n");
     nStart = GetTimeMillis();
+    pblocktree = new CBlockTreeDB("cr+");
     pcoinsdbview = new CCoinsViewDB();
     pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
 
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -270,6 +270,7 @@
 }
 
 CCoinsViewCache *pcoinsTip = NULL;
+CBlockTreeDB *pblocktree = NULL;
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -1143,7 +1144,7 @@
     if (pindexNew->bnChainWork > bnBestInvalidWork)
     {
         bnBestInvalidWork = pindexNew->bnChainWork;
-        CChainDB().WriteBestInvalidWork(bnBestInvalidWork);
+        pblocktree->WriteBestInvalidWork(bnBestInvalidWork);
         uiInterface.NotifyBlocksChanged();
     }
     printf("InvalidChainFound: invalid block=%s  height=%d  work=%s  date=%s\n",
@@ -1159,7 +1160,7 @@
 
 void static InvalidBlockFound(CBlockIndex *pindex) {
     pindex->nStatus |= BLOCK_FAILED_VALID;
-    CChainDB().WriteBlockIndex(CDiskBlockIndex(pindex));
+    pblocktree->WriteBlockIndex(CDiskBlockIndex(pindex));
     setBlockIndexValid.erase(pindex);
     InvalidChainFound(pindex);
     if (pindex->pnext)
@@ -1186,12 +1187,11 @@
         do {
             if (pindexTest->nStatus & BLOCK_FAILED_MASK) {
                 // mark descendants failed
-                CChainDB chaindb;
                 CBlockIndex *pindexFailed = pindexNewBest;
                 while (pindexTest != pindexFailed) {
                     pindexFailed->nStatus |= BLOCK_FAILED_CHILD;
                     setBlockIndexValid.erase(pindexFailed);
-                    chaindb.WriteBlockIndex(CDiskBlockIndex(pindexFailed));
+                    pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexFailed));
                     pindexFailed = pindexFailed->pprev;
                 }
                 InvalidChainFound(pindexNewBest);
@@ -1498,7 +1498,7 @@
     return true;
 }
 
-bool FindUndoPos(CChainDB &chaindb, int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
+bool FindUndoPos(int nFile, CDiskBlockPos &pos, unsigned int nAddSize);
 
 bool CBlock::ConnectBlock(CBlockIndex* pindex, CCoinsViewCache &view, bool fJustCheck)
 {
@@ -1581,11 +1581,9 @@
     // Write undo information to disk
     if (pindex->GetUndoPos().IsNull() || (pindex->nStatus & BLOCK_VALID_MASK) < BLOCK_VALID_SCRIPTS)
     {
-        CChainDB chaindb;
-
         if (pindex->GetUndoPos().IsNull()) {
             CDiskBlockPos pos;
-            if (!FindUndoPos(chaindb, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 8))
+            if (!FindUndoPos(pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 8))
                 return error("ConnectBlock() : FindUndoPos failed");
             if (!blockundo.WriteToDisk(pos))
                 return error("ConnectBlock() : CBlockUndo::WriteToDisk failed");
@@ -1598,7 +1596,7 @@
         pindex->nStatus = (pindex->nStatus & ~BLOCK_VALID_MASK) | BLOCK_VALID_SCRIPTS;
 
         CDiskBlockIndex blockindex(pindex);
-        if (!chaindb.WriteBlockIndex(blockindex))
+        if (!pblocktree->WriteBlockIndex(blockindex))
             return error("ConnectBlock() : WriteBlockIndex failed");
     }
 
@@ -1804,12 +1802,7 @@
     pindexNew->nStatus = BLOCK_VALID_TRANSACTIONS | BLOCK_HAVE_DATA;
     setBlockIndexValid.insert(pindexNew);
 
-    CChainDB chaindb;
-    if (!chaindb.TxnBegin())
-        return false;
-    chaindb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
-    if (!chaindb.TxnCommit())
-        return false;
+    pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew));
 
     // New best?
     if (!ConnectBestBlock())
@@ -1823,13 +1816,15 @@
         hashPrevBestCoinBase = GetTxHash(0);
     }
 
+    pblocktree->Flush();
+
     uiInterface.NotifyBlocksChanged();
     return true;
 }
 
 
 
-bool FindBlockPos(CChainDB &chaindb, CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64 nTime)
+bool FindBlockPos(CDiskBlockPos &pos, unsigned int nAddSize, unsigned int nHeight, uint64 nTime)
 {
     bool fUpdatedLast = false;
 
@@ -1845,7 +1840,7 @@
         fclose(file);
         nLastBlockFile++;
         infoLastBlockFile.SetNull();
-        chaindb.ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
+        pblocktree->ReadBlockFileInfo(nLastBlockFile, infoLastBlockFile); // check whether data for the new file somehow already exist; can fail just fine
         fUpdatedLast = true;
     }
 
@@ -1865,15 +1860,15 @@
         fclose(file);
     }
 
-    if (!chaindb.WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
+    if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
         return error("FindBlockPos() : cannot write updated block info");
     if (fUpdatedLast)
-        chaindb.WriteLastBlockFile(nLastBlockFile);
+        pblocktree->WriteLastBlockFile(nLastBlockFile);
 
     return true;
 }
 
-bool FindUndoPos(CChainDB &chaindb, int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
+bool FindUndoPos(int nFile, CDiskBlockPos &pos, unsigned int nAddSize)
 {
     pos.nFile = nFile;
 
@@ -1883,15 +1878,15 @@
     if (nFile == nLastBlockFile) {
         pos.nPos = infoLastBlockFile.nUndoSize;
         nNewSize = (infoLastBlockFile.nUndoSize += nAddSize);
-        if (!chaindb.WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
+        if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
             return error("FindUndoPos() : cannot write updated block info");
     } else {
         CBlockFileInfo info;
-        if (!chaindb.ReadBlockFileInfo(nFile, info))
+        if (!pblocktree->ReadBlockFileInfo(nFile, info))
             return error("FindUndoPos() : cannot read block info");
         pos.nPos = info.nUndoSize;
         nNewSize = (info.nUndoSize += nAddSize);
-        if (!chaindb.WriteBlockFileInfo(nFile, info))
+        if (!pblocktree->WriteBlockFileInfo(nFile, info))
             return error("FindUndoPos() : cannot write updated block info");
     }
 
@@ -2022,11 +2017,8 @@
     if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK, CLIENT_VERSION)))
         return error("AcceptBlock() : out of disk space");
     CDiskBlockPos blockPos;
-    {
-        CChainDB chaindb;
-        if (!FindBlockPos(chaindb, blockPos, nBlockSize+8, nHeight, nTime))
-            return error("AcceptBlock() : FindBlockPos failed");
-    }
+    if (!FindBlockPos(blockPos, nBlockSize+8, nHeight, nTime))
+        return error("AcceptBlock() : FindBlockPos failed");
     if (!WriteToDisk(blockPos))
         return error("AcceptBlock() : WriteToDisk failed");
     if (!AddToBlockIndex(blockPos))
@@ -2210,12 +2202,10 @@
     }
 
     //
-    // Load block index
+    // Load block index from databases
     //
-    CChainDB chaindb("cr");
-    if (!LoadBlockIndex(chaindb))
+    if (!LoadBlockIndexDB())
         return false;
-    chaindb.Close();
 
     //
     // Init with genesis block
@@ -2267,11 +2257,8 @@
         // Start new block file
         unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION);
         CDiskBlockPos blockPos;
-        {
-            CChainDB chaindb;
-            if (!FindBlockPos(chaindb, blockPos, nBlockSize+8, 0, block.nTime))
-                return error("AcceptBlock() : FindBlockPos failed");
-        }
+        if (!FindBlockPos(blockPos, nBlockSize+8, 0, block.nTime))
+            return error("AcceptBlock() : FindBlockPos failed");
         if (!block.WriteToDisk(blockPos))
             return error("LoadBlockIndex() : writing genesis block to disk failed");
         if (!block.AddToBlockIndex(blockPos))
--- a/src/main.h
+++ b/src/main.h
@@ -86,7 +86,7 @@
 
 class CReserveKey;
 class CCoinsDB;
-class CChainDB;
+class CBlockTreeDB;
 class CDiskBlockPos;
 class CCoins;
 class CTxUndo;
@@ -1865,6 +1865,10 @@
     bool HaveCoins(uint256 txid);
 };
 
+/** Global variable that points to the active CCoinsView (protected by cs_main) */
 extern CCoinsViewCache *pcoinsTip;
 
+/** Global variable that points to the active block tree (protected by cs_main) */
+extern CBlockTreeDB *pblocktree;
+
 #endif
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -12,10 +12,15 @@
 extern void noui_connect();
 
 struct TestingSetup {
+    CCoinsViewDB *pcoinsdbview;
+
     TestingSetup() {
         fPrintToDebugger = true; // don't want to write to debug.log file
         noui_connect();
         bitdb.MakeMock();
+        pblocktree = new CBlockTreeDB("cr+");
+        pcoinsdbview = new CCoinsViewDB();
+        pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
         LoadBlockIndex(true);
         bool fFirstRun;
         pwalletMain = new CWallet("wallet.dat");
@@ -26,6 +31,9 @@
     {
         delete pwalletMain;
         pwalletMain = NULL;
+        delete pcoinsTip;
+        delete pcoinsdbview;
+        delete pblocktree;
         bitdb.Flush(true);
     }
 };