aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db.cpp23
-rw-r--r--main.cpp97
-rw-r--r--main.h1
-rw-r--r--rpc.cpp4
-rw-r--r--serialize.h2
-rw-r--r--ui.cpp2
6 files changed, 81 insertions, 48 deletions
diff --git a/db.cpp b/db.cpp
index 7116b0aa30..8134a9059c 100644
--- a/db.cpp
+++ b/db.cpp
@@ -459,6 +459,29 @@ bool CTxDB::LoadBlockIndex()
// 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;
}
diff --git a/main.cpp b/main.cpp
index 6fe0c0e9ed..6311735e64 100644
--- a/main.cpp
+++ b/main.cpp
@@ -1234,6 +1234,57 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
}
+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 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
// 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();
diff --git a/main.h b/main.h
index 771b21bfcd..1cc410be61 100644
--- a/main.h
+++ b/main.h
@@ -1065,6 +1065,7 @@ public:
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();
diff --git a/rpc.cpp b/rpc.cpp
index d03a7ce767..679951af23 100644
--- a/rpc.cpp
+++ b/rpc.cpp
@@ -120,7 +120,7 @@ Value getblockcount(const Array& params, bool fHelp)
"getblockcount\n"
"Returns the number of blocks in the longest block chain.");
- return nBestHeight + 1;
+ return nBestHeight;
}
@@ -240,7 +240,7 @@ Value getinfo(const Array& params, bool fHelp)
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));
diff --git a/serialize.h b/serialize.h
index 208a96d2f3..e5e1f0f883 100644
--- a/serialize.h
+++ b/serialize.h
@@ -20,7 +20,7 @@ class CDataStream;
class CAutoFile;
static const int VERSION = 310;
-static const char* pszSubVer = ".1";
+static const char* pszSubVer = ".2";
diff --git a/ui.cpp b/ui.cpp
index 885adeaa82..b8f50b4511 100644
--- a/ui.cpp
+++ b/ui.cpp
@@ -1027,7 +1027,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event)
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)