changeset 255:835b9dd8e8cd draft

blocks-1, verify block chain on load, so wouldn't have needed to delete blk*.dat, it would have done a reorg automatically git-svn-id: https://bitcoin.svn.sourceforge.net/svnroot/bitcoin/trunk@137 1a98c847-1fd6-4fd8-948a-caf3550aa51b
author s_nakamoto <s_nakamoto@1a98c847-1fd6-4fd8-948a-caf3550aa51b>
date Mon, 16 Aug 2010 17:05:50 +0000
parents 7993dcea6284
children e4e826afefae
files db.cpp main.cpp main.h rpc.cpp serialize.h ui.cpp
diffstat 6 files changed, 81 insertions(+), 48 deletions(-) [+]
line wrap: on
line diff
--- a/db.cpp
+++ b/db.cpp
@@ -459,6 +459,29 @@
     // Load bnBestInvalidWork, OK if it doesn't exist
     ReadBestInvalidWork(bnBestInvalidWork);
 
+    // Verify blocks in the best chain
+    CBlockIndex* pindexFork = NULL;
+    for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev)
+    {
+        CBlock block;
+        if (!block.ReadFromDisk(pindex))
+            return error("LoadBlockIndex() : block.ReadFromDisk failed");
+        if (!block.CheckBlock())
+        {
+            printf("LoadBlockIndex() : *** found bad block at %d, hash=%s\n", pindex->nHeight, pindex->GetBlockHash().ToString().c_str());
+            pindexFork = pindex->pprev;
+        }
+    }
+    if (pindexFork)
+    {
+        printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight);
+        CBlock block;
+        if (!block.ReadFromDisk(pindexFork))
+            return error("LoadBlockIndex() : block.ReadFromDisk failed");
+        CTxDB txdb;
+        block.SetBestChain(txdb, pindexFork);
+    }
+
     return true;
 }
 
--- a/main.cpp
+++ b/main.cpp
@@ -1234,6 +1234,57 @@
 }
 
 
+bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
+{
+    uint256 hash = GetHash();
+
+    txdb.TxnBegin();
+    if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
+    {
+        pindexGenesisBlock = pindexNew;
+        txdb.WriteHashBestChain(hash);
+    }
+    else if (hashPrevBlock == hashBestChain)
+    {
+        // Adding to current best branch
+        if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
+        {
+            txdb.TxnAbort();
+            Lockdown(pindexNew);
+            return error("SetBestChain() : ConnectBlock failed");
+        }
+        txdb.TxnCommit();
+        pindexNew->pprev->pnext = pindexNew;
+
+        // Delete redundant memory transactions
+        foreach(CTransaction& tx, vtx)
+            tx.RemoveFromMemoryPool();
+    }
+    else
+    {
+        // New best branch
+        if (!Reorganize(txdb, pindexNew))
+        {
+            txdb.TxnAbort();
+            Lockdown(pindexNew);
+            return error("SetBestChain() : Reorganize failed");
+        }
+    }
+    txdb.TxnCommit();
+
+    // New best block
+    hashBestChain = hash;
+    pindexBest = pindexNew;
+    nBestHeight = pindexBest->nHeight;
+    bnBestChainWork = pindexNew->bnChainWork;
+    nTimeBestReceived = GetTime();
+    nTransactionsUpdated++;
+    printf("SetBestChain: new best=%s  height=%d  work=%s\n", hashBestChain.ToString().substr(0,22).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
+
+    return true;
+}
+
+
 bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
 {
     // Check for duplicate
@@ -1260,50 +1311,8 @@
 
     // New best
     if (pindexNew->bnChainWork > bnBestChainWork)
-    {
-        txdb.TxnBegin();
-        if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
-        {
-            pindexGenesisBlock = pindexNew;
-            txdb.WriteHashBestChain(hash);
-        }
-        else if (hashPrevBlock == hashBestChain)
-        {
-            // Adding to current best branch
-            if (!ConnectBlock(txdb, pindexNew) || !txdb.WriteHashBestChain(hash))
-            {
-                txdb.TxnAbort();
-                Lockdown(pindexNew);
-                return error("AddToBlockIndex() : ConnectBlock failed");
-            }
-            txdb.TxnCommit();
-            pindexNew->pprev->pnext = pindexNew;
-
-            // Delete redundant memory transactions
-            foreach(CTransaction& tx, vtx)
-                tx.RemoveFromMemoryPool();
-        }
-        else
-        {
-            // New best branch
-            if (!Reorganize(txdb, pindexNew))
-            {
-                txdb.TxnAbort();
-                Lockdown(pindexNew);
-                return error("AddToBlockIndex() : Reorganize failed");
-            }
-        }
-        txdb.TxnCommit();
-
-        // New best block
-        hashBestChain = hash;
-        pindexBest = pindexNew;
-        nBestHeight = pindexBest->nHeight;
-        bnBestChainWork = pindexNew->bnChainWork;
-        nTimeBestReceived = GetTime();
-        nTransactionsUpdated++;
-        printf("AddToBlockIndex: new best=%s  height=%d  work=%s\n", hashBestChain.ToString().substr(0,22).c_str(), nBestHeight, bnBestChainWork.ToString().c_str());
-    }
+        if (!SetBestChain(txdb, pindexNew))
+            return false;
 
     txdb.Close();
 
--- a/main.h
+++ b/main.h
@@ -1065,6 +1065,7 @@
     bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex);
     bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex);
     bool ReadFromDisk(const CBlockIndex* blockindex, bool fReadTransactions=true);
+    bool SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew);
     bool AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos);
     bool CheckBlock() const;
     bool AcceptBlock();
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -120,7 +120,7 @@
             "getblockcount\n"
             "Returns the number of blocks in the longest block chain.");
 
-    return nBestHeight + 1;
+    return nBestHeight;
 }
 
 
@@ -240,7 +240,7 @@
     Object obj;
     obj.push_back(Pair("version",       (int)VERSION));
     obj.push_back(Pair("balance",       (double)GetBalance() / (double)COIN));
-    obj.push_back(Pair("blocks",        (int)nBestHeight + 1));
+    obj.push_back(Pair("blocks",        (int)nBestHeight));
     obj.push_back(Pair("connections",   (int)vNodes.size()));
     obj.push_back(Pair("proxy",         (fUseProxy ? addrProxy.ToStringIPPort() : string())));
     obj.push_back(Pair("generate",      (bool)fGenerateBitcoins));
--- a/serialize.h
+++ b/serialize.h
@@ -20,7 +20,7 @@
 class CAutoFile;
 
 static const int VERSION = 310;
-static const char* pszSubVer = ".1";
+static const char* pszSubVer = ".2";
 
 
 
--- a/ui.cpp
+++ b/ui.cpp
@@ -1027,7 +1027,7 @@
         strGen = _("(not connected)");
     m_statusBar->SetStatusText(strGen, 1);
 
-    string strStatus = strprintf(_("     %d connections     %d blocks     %d transactions"), vNodes.size(), nBestHeight + 1, nTransactionCount);
+    string strStatus = strprintf(_("     %d connections     %d blocks     %d transactions"), vNodes.size(), nBestHeight, nTransactionCount);
     m_statusBar->SetStatusText(strStatus, 2);
 
     if (fDebug && GetTime() - nThreadSocketHandlerHeartbeat > 60)