From 1d740055daa6e1668f047186d208b0693c6b21ba Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 20 Feb 2012 20:50:26 +0100 Subject: [PATCH] -loadblock to load from an external blk000?.dat file --- src/db.cpp | 4 ++-- src/init.cpp | 13 +++++++++++- src/main.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.h | 2 ++ 4 files changed, 72 insertions(+), 3 deletions(-) diff --git a/src/db.cpp b/src/db.cpp index 39a41894d7f23..670f0a876ce70 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -608,7 +608,7 @@ bool CTxDB::LoadBlockIndex() map, CBlockIndex*> mapBlockPos; for (CBlockIndex* pindex = pindexBest; pindex && pindex->pprev; pindex = pindex->pprev) { - if (pindex->nHeight < nBestHeight-nCheckDepth) + if (fRequestShutdown || pindex->nHeight < nBestHeight-nCheckDepth) break; CBlock block; if (!block.ReadFromDisk(pindex)) @@ -710,7 +710,7 @@ bool CTxDB::LoadBlockIndex() } } } - if (pindexFork) + if (pindexFork && !fRequestShutdown) { // Reorg back to the fork printf("LoadBlockIndex() : *** moving best chain pointer back to block %d\n", pindexFork->nHeight); diff --git a/src/init.cpp b/src/init.cpp index 14db9e7f5ea40..a021e849ff461 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -224,7 +224,8 @@ bool AppInit2(int argc, char* argv[]) " -keypool= \t " + _("Set key pool size to (default: 100)") + "\n" + " -rescan \t " + _("Rescan the block chain for missing wallet transactions") + "\n" + " -checkblocks= \t\t " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" + - " -checklevel= \t\t " + _("How thorough the block verification is (0-6, default: 1)") + "\n"; + " -checklevel= \t\t " + _("How thorough the block verification is (0-6, default: 1)") + "\n" + + " -loadblock=\t " + _("Imports blocks from external blk000?.dat file") + "\n"; strUsage += string() + _("\nSSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n" + @@ -364,6 +365,16 @@ bool AppInit2(int argc, char* argv[]) } printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + if (mapArgs.count("-loadblock")) + { + BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"]) + { + FILE *file = fopen(strFile.c_str(), "rb"); + if (file) + LoadExternalBlockFile(file); + } + } + InitMessage(_("Loading wallet...")); printf("Loading wallet...\n"); nStart = GetTimeMillis(); diff --git a/src/main.cpp b/src/main.cpp index 78d84d906484d..e2f1af4091ed1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2011,6 +2011,62 @@ void PrintBlockTree() } } +bool LoadExternalBlockFile(FILE* fileIn) +{ + int nLoaded = 0; + { + LOCK(cs_main); + try { + CAutoFile blkdat(fileIn, SER_DISK, CLIENT_VERSION); + unsigned int nPos = 0; + while (nPos != -1 && blkdat.good() && !fRequestShutdown) + { + unsigned char pchData[65536]; + do { + fseek(blkdat, nPos, SEEK_SET); + int nRead = fread(pchData, 1, sizeof(pchData), blkdat); + if (nRead <= 8) + { + nPos = -1; + break; + } + void* nFind = memchr(pchData, pchMessageStart[0], nRead+1-sizeof(pchMessageStart)); + if (nFind) + { + if (memcmp(nFind, pchMessageStart, sizeof(pchMessageStart))==0) + { + nPos += ((unsigned char*)nFind - pchData) + sizeof(pchMessageStart); + break; + } + nPos += ((unsigned char*)nFind - pchData) + 1; + } + else + nPos += sizeof(pchData) - sizeof(pchMessageStart) + 1; + } while(!fRequestShutdown); + if (nPos == -1) + break; + fseek(blkdat, nPos, SEEK_SET); + unsigned int nSize; + blkdat >> nSize; + if (nSize > 0 && nSize <= MAX_BLOCK_SIZE) + { + CBlock block; + blkdat >> block; + if (ProcessBlock(NULL,&block)) + { + nLoaded++; + nPos += 4 + nSize; + } + } + } + } + catch (std::exception &e) + { + } + } + printf("Loaded %i blocks from external file\n", nLoaded); + return nLoaded > 0; +} diff --git a/src/main.h b/src/main.h index a814092ac2781..af294b55c73ee 100644 --- a/src/main.h +++ b/src/main.h @@ -69,6 +69,7 @@ extern int64 nHPSTimerStart; extern int64 nTimeBestReceived; extern CCriticalSection cs_setpwalletRegistered; extern std::set setpwalletRegistered; +extern unsigned char pchMessageStart[4]; // Settings extern int64 nTransactionFee; @@ -91,6 +92,7 @@ bool LoadBlockIndex(bool fAllowNew=true); void PrintBlockTree(); bool ProcessMessages(CNode* pfrom); bool SendMessages(CNode* pto, bool fSendTrickle); +bool LoadExternalBlockFile(FILE* fileIn); void GenerateBitcoins(bool fGenerate, CWallet* pwallet); CBlock* CreateNewBlock(CReserveKey& reservekey); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce);