Browse Source

blocks-1,

verify block chain on load, so wouldn't have needed to delete blk*.dat, it would have done a reorg automatically
0.8
Satoshi Nakamoto 14 years ago committed by Gavin Andresen
parent
commit
bb3fd02930
  1. 23
      db.cpp
  2. 74
      main.cpp
  3. 1
      main.h
  4. 4
      rpc.cpp
  5. 2
      serialize.h
  6. 2
      ui.cpp

23
db.cpp

@ -459,6 +459,29 @@ bool CTxDB::LoadBlockIndex() @@ -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;
}

74
main.cpp

@ -1234,33 +1234,10 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew) @@ -1234,33 +1234,10 @@ bool Reorganize(CTxDB& txdb, CBlockIndex* pindexNew)
}
bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
{
// Check for duplicate
uint256 hash = GetHash();
if (mapBlockIndex.count(hash))
return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str());
// Construct new block index object
CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
if (!pindexNew)
return error("AddToBlockIndex() : new CBlockIndex failed");
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
pindexNew->phashBlock = &((*mi).first);
map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
if (miPrev != mapBlockIndex.end())
{
pindexNew->pprev = (*miPrev).second;
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
}
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
CTxDB txdb;
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
// New best
if (pindexNew->bnChainWork > bnBestChainWork)
{
txdb.TxnBegin();
if (pindexGenesisBlock == NULL && hash == hashGenesisBlock)
{
@ -1274,7 +1251,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) @@ -1274,7 +1251,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
{
txdb.TxnAbort();
Lockdown(pindexNew);
return error("AddToBlockIndex() : ConnectBlock failed");
return error("SetBestChain() : ConnectBlock failed");
}
txdb.TxnCommit();
pindexNew->pprev->pnext = pindexNew;
@ -1290,7 +1267,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) @@ -1290,7 +1267,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
{
txdb.TxnAbort();
Lockdown(pindexNew);
return error("AddToBlockIndex() : Reorganize failed");
return error("SetBestChain() : Reorganize failed");
}
}
txdb.TxnCommit();
@ -1302,8 +1279,40 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) @@ -1302,8 +1279,40 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos)
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());
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
uint256 hash = GetHash();
if (mapBlockIndex.count(hash))
return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,16).c_str());
// Construct new block index object
CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this);
if (!pindexNew)
return error("AddToBlockIndex() : new CBlockIndex failed");
map<uint256, CBlockIndex*>::iterator mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first;
pindexNew->phashBlock = &((*mi).first);
map<uint256, CBlockIndex*>::iterator miPrev = mapBlockIndex.find(hashPrevBlock);
if (miPrev != mapBlockIndex.end())
{
pindexNew->pprev = (*miPrev).second;
pindexNew->nHeight = pindexNew->pprev->nHeight + 1;
}
pindexNew->bnChainWork = (pindexNew->pprev ? pindexNew->pprev->bnChainWork : 0) + pindexNew->GetBlockWork();
CTxDB txdb;
txdb.WriteBlockIndex(CDiskBlockIndex(pindexNew));
// New best
if (pindexNew->bnChainWork > bnBestChainWork)
if (!SetBestChain(txdb, pindexNew))
return false;
txdb.Close();
@ -1393,7 +1402,16 @@ bool CBlock::AcceptBlock() @@ -1393,7 +1402,16 @@ bool CBlock::AcceptBlock()
(pindexPrev->nHeight+1 == 68555 && hash != uint256("0x00000000001e1b4903550a0b96e9a9405c8a95f387162e4944e8d9fbe501cd6a")) ||
(pindexPrev->nHeight+1 == 70567 && hash != uint256("0x00000000006a49b14bcf27462068f1264c961f11fa2e0eddd2be0791e1d4124a")) ||
(pindexPrev->nHeight+1 == 74000 && hash != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")))
return error("AcceptBlock() : rejected by checkpoint lockin");
return error("AcceptBlock() : rejected by checkpoint lockin at %d", pindexPrev->nHeight+1);
// Scanback checkpoint lockin
for (CBlockIndex* pindex = pindexPrev; pindex->nHeight >= 74000; pindex = pindex->pprev)
{
if (pindex->nHeight == 74000 && pindex->GetBlockHash() != uint256("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20"))
return error("AcceptBlock() : rejected by scanback lockin at %d", pindex->nHeight);
if (pindex->nHeight == 74638 && pindex->GetBlockHash() == uint256("0x0000000000790ab3f22ec756ad43b6ab569abf0bddeb97c67a6f7b1470a7ec1c"))
return error("AcceptBlock() : rejected by scanback lockin at %d", pindex->nHeight);
}
// Write block to history file
if (!CheckDiskSpace(::GetSerializeSize(*this, SER_DISK)))

1
main.h

@ -1065,6 +1065,7 @@ public: @@ -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();

4
rpc.cpp

@ -120,7 +120,7 @@ Value getblockcount(const Array& params, bool fHelp) @@ -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) @@ -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));

2
serialize.h

@ -20,7 +20,7 @@ class CDataStream; @@ -20,7 +20,7 @@ class CDataStream;
class CAutoFile;
static const int VERSION = 310;
static const char* pszSubVer = ".0";
static const char* pszSubVer = ".2";

2
ui.cpp

@ -1027,7 +1027,7 @@ void CMainFrame::OnPaintListCtrl(wxPaintEvent& event) @@ -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)

Loading…
Cancel
Save