diff --git a/init.cpp b/init.cpp index 04bdd68..26a1506 100644 --- a/init.cpp +++ b/init.cpp @@ -327,6 +327,19 @@ bool AppInit2(int argc, char* argv[]) strErrors += _("Error loading blkindex.dat \n"); printf(" block index %15"PRI64d"ms\n", GetTimeMillis() - nStart); + if (mapArgs.count("-initblocks")) { + string strFn = mapArgs["-initblocks"]; + + printf("Initializing block data from static file...\n"); + nStart = GetTimeMillis(); + fBlockImport = true; + if (!InitBlockFile(strFn)) + strErrors += _("Error initializing block data \n"); + fBlockImport = false; + printf(" block data init %15"PRI64d"ms\n", GetTimeMillis() - nStart); + + } + printf("Loading wallet...\n"); nStart = GetTimeMillis(); bool fFirstRun; diff --git a/main.cpp b/main.cpp index a47f3a9..67068d7 100644 --- a/main.cpp +++ b/main.cpp @@ -1144,6 +1144,8 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) bool IsInitialBlockDownload() { + if (fBlockImport) + return true; if (pindexBest == NULL || (!fTestNet && nBestHeight < 105000)) return true; static int64 nLastUpdate; @@ -1894,6 +1896,59 @@ FILE* AppendBlockFile(unsigned int& nFileRet) } } +bool InitBlockFile(string strFn) +{ + unsigned long n_blk = 0; + + FILE *file = fopen(strFn.c_str(), "rb"); + if (!file) { + printf("Failed to open block data file %s\n", strFn.c_str()); + return false; + } + + CAutoFile filein(file); + CBlockFileHeader hdr; + + while (1) + { + try { + if (!hdr.ReadRaw(filein)) + return false; + } + catch (std::ios_base::failure) { + break; + } + + auto_ptr pblock(new CBlock); + + try { + if (!pblock->ReadRaw(filein)) + return false; + } + catch (std::ios_base::failure) { + break; + } + + uint256 hash = pblock->GetHash(); + + if (hash == hashGenesisBlock) { + // ignore; LoadBlockIndex already gave it to us + } else { + if (!ProcessBlock(NULL, pblock.get())) { + printf("Block %lu failed ProcessBlock\n", n_blk); + break; + } + } + + + n_blk++; + } + + printf("InitBlockFile successfully imported %lu blocks\n", n_blk); + + return true; +} + bool LoadBlockIndex(bool fAllowNew) { if (fTestNet) diff --git a/main.h b/main.h index a7ef336..9342f89 100644 --- a/main.h +++ b/main.h @@ -65,6 +65,7 @@ extern int fMinimizeOnClose; bool CheckDiskSpace(uint64 nAdditionalBytes=0); FILE* OpenBlockFile(unsigned int nFile, unsigned int nBlockPos, const char* pszMode="rb"); FILE* AppendBlockFile(unsigned int& nFileRet); +bool InitBlockFile(string strFn); bool AddKey(const CKey& key); vector GenerateNewKey(); bool AddToWallet(const CWalletTx& wtxIn); @@ -1002,6 +1003,34 @@ public: +class CBlockFileHeader +{ +public: + char magic[4]; + unsigned int nSize; + + IMPLEMENT_SERIALIZE + ( + READWRITE(FLATDATA(magic)); + READWRITE(nSize); + ) + + bool ReadRaw(CAutoFile &filein) + { + // Read block + filein >> *this; + + if (memcmp(magic, pchMessageStart, 4)) + return false; + + // TODO: validate remaining file size >= nSize + + return true; + } +}; + + + // @@ -1173,6 +1202,18 @@ public: return true; } + bool ReadRaw(CAutoFile &filein) + { + // Read block + filein >> *this; + + // Check the header + if (!CheckProofOfWork(GetHash(), nBits)) + return error("CBlock::ReadFromDisk() : errors in block header"); + + return true; + } + bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true) { SetNull(); @@ -1184,14 +1225,7 @@ public: if (!fReadTransactions) filein.nType |= SER_BLOCKHEADERONLY; - // Read block - filein >> *this; - - // Check the header - if (!CheckProofOfWork(GetHash(), nBits)) - return error("CBlock::ReadFromDisk() : errors in block header"); - - return true; + return ReadRaw(filein); } diff --git a/util.cpp b/util.cpp index 94b0242..117d2e1 100644 --- a/util.cpp +++ b/util.cpp @@ -18,6 +18,7 @@ bool fCommandLine = false; string strMiscWarning; bool fTestNet = false; bool fNoListen = false; +bool fBlockImport = false; diff --git a/util.h b/util.h index c69bf1c..3cca1ce 100644 --- a/util.h +++ b/util.h @@ -147,6 +147,7 @@ extern bool fCommandLine; extern string strMiscWarning; extern bool fTestNet; extern bool fNoListen; +extern bool fBlockImport; void RandAddSeed(); void RandAddSeedPerfmon();