aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp398
1 files changed, 331 insertions, 67 deletions
diff --git a/src/init.cpp b/src/init.cpp
index ec32b6209..64f91a349 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -2,13 +2,15 @@
// Copyright (c) 2009-2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-#include "db.h"
+
+#include "txdb.h"
#include "walletdb.h"
#include "bitcoinrpc.h"
#include "net.h"
#include "init.h"
#include "util.h"
#include "ui_interface.h"
+
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/convenience.hpp>
@@ -26,6 +28,13 @@ using namespace boost;
CWallet* pwalletMain;
CClientUIInterface uiInterface;
+// Used to pass flags to the Bind() function
+enum BindFlags {
+ BF_NONE = 0,
+ BF_EXPLICIT = (1U << 0),
+ BF_REPORT_ERROR = (1U << 1)
+};
+
//////////////////////////////////////////////////////////////////////////////
//
// Shutdown
@@ -50,6 +59,8 @@ void StartShutdown()
#endif
}
+static CCoinsViewDB *pcoinsdbview;
+
void Shutdown(void* parg)
{
static CCriticalSection cs_Shutdown;
@@ -71,9 +82,24 @@ void Shutdown(void* parg)
if (fFirstThread)
{
fShutdown = true;
+ fRequestShutdown = true;
nTransactionsUpdated++;
bitdb.Flush(false);
+ {
+ LOCK(cs_main);
+ ThreadScriptCheckQuit();
+ }
StopNode();
+ {
+ LOCK(cs_main);
+ if (pblocktree)
+ pblocktree->Flush();
+ if (pcoinsTip)
+ pcoinsTip->Flush();
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pblocktree;
+ }
bitdb.Flush(true);
boost::filesystem::remove(GetPidFile());
UnregisterWallet(pwalletMain);
@@ -144,7 +170,7 @@ bool AppInit(int argc, char* argv[])
strUsage += "\n" + HelpMessage();
- fprintf(stderr, "%s", strUsage.c_str());
+ fprintf(stdout, "%s", strUsage.c_str());
return false;
}
@@ -162,9 +188,9 @@ bool AppInit(int argc, char* argv[])
fRet = AppInit2();
}
catch (std::exception& e) {
- PrintException(&e, "AppInit()");
+ PrintExceptionContinue(&e, "AppInit()");
} catch (...) {
- PrintException(NULL, "AppInit()");
+ PrintExceptionContinue(NULL, "AppInit()");
}
if (!fRet)
Shutdown(NULL);
@@ -190,23 +216,22 @@ int main(int argc, char* argv[])
bool static InitError(const std::string &str)
{
- uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::MODAL);
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_ERROR);
return false;
}
bool static InitWarning(const std::string &str)
{
- uiInterface.ThreadSafeMessageBox(str, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL);
+ uiInterface.ThreadSafeMessageBox(str, "", CClientUIInterface::MSG_WARNING);
return true;
}
-
-bool static Bind(const CService &addr, bool fError = true) {
- if (IsLimited(addr))
+bool static Bind(const CService &addr, unsigned int flags) {
+ if (!(flags & BF_EXPLICIT) && IsLimited(addr))
return false;
std::string strError;
if (!BindListenPort(addr, strError)) {
- if (fError)
+ if (flags & BF_REPORT_ERROR)
return InitError(strError);
return false;
}
@@ -224,7 +249,6 @@ std::string HelpMessage()
" -gen=0 " + _("Don't generate coins") + "\n" +
" -datadir=<dir> " + _("Specify data directory") + "\n" +
" -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" +
- " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" +
" -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000)") + "\n" +
" -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" +
" -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" +
@@ -239,8 +263,9 @@ std::string HelpMessage()
" -onlynet=<net> " + _("Only connect to nodes in network <net> (IPv4, IPv6 or Tor)") + "\n" +
" -discover " + _("Discover own IP address (default: 1 when listening and no -externalip)") + "\n" +
" -irc " + _("Find peers using internet relay chat (default: 0)") + "\n" +
+ " -checkpoints " + _("Only accept block chain matching built-in checkpoints (default: 1)") + "\n" +
" -listen " + _("Accept connections from outside (default: 1 if no -proxy or -connect)") + "\n" +
- " -bind=<addr> " + _("Bind to given address. Use [host]:port notation for IPv6") + "\n" +
+ " -bind=<addr> " + _("Bind to given address and always listen on it. Use [host]:port notation for IPv6") + "\n" +
" -dnsseed " + _("Find peers using DNS lookup (default: 1 unless -connect)") + "\n" +
" -banscore=<n> " + _("Threshold for disconnecting misbehaving peers (default: 100)") + "\n" +
" -bantime=<n> " + _("Number of seconds to keep misbehaving peers from reconnecting (default: 86400)") + "\n" +
@@ -253,7 +278,6 @@ std::string HelpMessage()
" -upnp " + _("Use UPnP to map the listening port (default: 0)") + "\n" +
#endif
#endif
- " -detachdb " + _("Detach block and address databases. Increases shutdown time (default: 0)") + "\n" +
" -paytxfee=<amt> " + _("Fee per KB to add to transactions you send") + "\n" +
#ifdef QT_GUI
" -server " + _("Accept command line and JSON-RPC commands") + "\n" +
@@ -272,7 +296,7 @@ std::string HelpMessage()
#endif
" -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n" +
" -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n" +
- " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332)") + "\n" +
+ " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 8332 or testnet: 18332)") + "\n" +
" -rpcallowip=<ip> " + _("Allow JSON-RPC connections from specified IP address") + "\n" +
" -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n" +
" -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n" +
@@ -280,9 +304,13 @@ std::string HelpMessage()
" -upgradewallet " + _("Upgrade wallet to latest format") + "\n" +
" -keypool=<n> " + _("Set key pool size to <n> (default: 100)") + "\n" +
" -rescan " + _("Rescan the block chain for missing wallet transactions") + "\n" +
- " -checkblocks=<n> " + _("How many blocks to check at startup (default: 2500, 0 = all)") + "\n" +
- " -checklevel=<n> " + _("How thorough the block verification is (0-6, default: 1)") + "\n" +
- " -loadblock=<file> " + _("Imports blocks from external blk000?.dat file") + "\n" +
+ " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\n" +
+ " -checkblocks=<n> " + _("How many blocks to check at startup (default: 288, 0 = all)") + "\n" +
+ " -checklevel=<n> " + _("How thorough the block verification is (0-4, default: 3)") + "\n" +
+ " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n" +
+ " -loadblock=<file> " + _("Imports blocks from external blk000??.dat file") + "\n" +
+ " -reindex " + _("Rebuild blockchain index from current blk000??.dat files") + "\n" +
+ " -par=N " + _("Set the number of script verification threads (1-16, 0=auto, default: 0)") + "\n" +
"\n" + _("Block creation options:") + "\n" +
" -blockminsize=<n> " + _("Set minimum block size in bytes (default: 0)") + "\n" +
@@ -298,6 +326,82 @@ std::string HelpMessage()
return strUsage;
}
+struct CImportingNow
+{
+ CImportingNow() {
+ assert(fImporting == false);
+ fImporting = true;
+ }
+
+ ~CImportingNow() {
+ assert(fImporting == true);
+ fImporting = false;
+ }
+};
+
+struct CImportData {
+ std::vector<boost::filesystem::path> vFiles;
+};
+
+void ThreadImport(void *data) {
+ CImportData *import = reinterpret_cast<CImportData*>(data);
+
+ RenameThread("bitcoin-loadblk");
+
+ vnThreadsRunning[THREAD_IMPORT]++;
+
+ // -reindex
+ if (fReindex) {
+ CImportingNow imp;
+ int nFile = 0;
+ while (!fRequestShutdown) {
+ CDiskBlockPos pos(nFile, 0);
+ FILE *file = OpenBlockFile(pos, true);
+ if (!file)
+ break;
+ printf("Reindexing block file blk%05u.dat...\n", (unsigned int)nFile);
+ LoadExternalBlockFile(file, &pos);
+ nFile++;
+ }
+ if (!fRequestShutdown) {
+ pblocktree->WriteReindexing(false);
+ fReindex = false;
+ printf("Reindexing finished\n");
+ // To avoid ending up in a situation without genesis block, re-try initializing (no-op if reindexing worked):
+ InitBlockIndex();
+ }
+ }
+
+ // hardcoded $DATADIR/bootstrap.dat
+ filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
+ if (filesystem::exists(pathBootstrap) && !fRequestShutdown) {
+ FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
+ if (file) {
+ CImportingNow imp;
+ filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
+ printf("Importing bootstrap.dat...\n");
+ LoadExternalBlockFile(file);
+ RenameOver(pathBootstrap, pathBootstrapOld);
+ }
+ }
+
+ // -loadblock=
+ BOOST_FOREACH(boost::filesystem::path &path, import->vFiles) {
+ if (fRequestShutdown)
+ break;
+ FILE *file = fopen(path.string().c_str(), "rb");
+ if (file) {
+ CImportingNow imp;
+ printf("Importing %s...\n", path.string().c_str());
+ LoadExternalBlockFile(file);
+ }
+ }
+
+ delete import;
+
+ vnThreadsRunning[THREAD_IMPORT]--;
+}
+
/** Initialize bitcoin.
* @pre Parameters should be parsed and config file should be read.
*/
@@ -380,9 +484,24 @@ bool AppInit2()
SoftSetBoolArg("-discover", false);
}
+ if (GetBoolArg("-salvagewallet")) {
+ // Rewrite just private keys: rescan to find transactions
+ SoftSetBoolArg("-rescan", true);
+ }
+
// ********************************************************* Step 3: parameter-to-internal-flags
fDebug = GetBoolArg("-debug");
+ fBenchmark = GetBoolArg("-benchmark");
+
+ // -par=0 means autodetect, but nScriptCheckThreads==0 means no concurrency
+ nScriptCheckThreads = GetArg("-par", 0);
+ if (nScriptCheckThreads == 0)
+ nScriptCheckThreads = boost::thread::hardware_concurrency();
+ if (nScriptCheckThreads <= 1)
+ nScriptCheckThreads = 0;
+ else if (nScriptCheckThreads > MAX_SCRIPTCHECK_THREADS)
+ nScriptCheckThreads = MAX_SCRIPTCHECK_THREADS;
// -debug implies fDebug*
if (fDebug)
@@ -390,8 +509,6 @@ bool AppInit2()
else
fDebugNet = GetBoolArg("-debugnet");
- bitdb.SetDetach(GetBoolArg("-detachdb", false));
-
#if !defined(WIN32) && !defined(QT_GUI)
fDaemon = GetBoolArg("-daemon");
#else
@@ -435,13 +552,15 @@ bool AppInit2()
// ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log
+ std::string strDataDir = GetDataDir().string();
+
// Make sure only a single Bitcoin process is using the data directory.
boost::filesystem::path pathLockFile = GetDataDir() / ".lock";
FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist.
if (file) fclose(file);
static boost::interprocess::file_lock lock(pathLockFile.string().c_str());
if (!lock.try_lock())
- return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str()));
+ return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), strDataDir.c_str()));
#if !defined(WIN32) && !defined(QT_GUI)
if (fDaemon)
@@ -471,17 +590,57 @@ bool AppInit2()
printf("Bitcoin version %s (%s)\n", FormatFullVersion().c_str(), CLIENT_DATE.c_str());
printf("Using OpenSSL version %s\n", SSLeay_version(SSLEAY_VERSION));
if (!fLogTimestamps)
- printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str());
+ printf("Startup time: %s\n", DateTimeStrFormat("%Y-%m-%d %H:%M:%S", GetTime()).c_str());
printf("Default data directory %s\n", GetDefaultDataDir().string().c_str());
- printf("Used data directory %s\n", GetDataDir().string().c_str());
+ printf("Used data directory %s\n", strDataDir.c_str());
std::ostringstream strErrors;
if (fDaemon)
fprintf(stdout, "Bitcoin server starting\n");
+ if (nScriptCheckThreads) {
+ printf("Using %u threads for script verification\n", nScriptCheckThreads);
+ for (int i=0; i<nScriptCheckThreads-1; i++)
+ NewThread(ThreadScriptCheck, NULL);
+ }
+
int64 nStart;
- // ********************************************************* Step 5: network initialization
+ // ********************************************************* Step 5: verify wallet database integrity
+
+ uiInterface.InitMessage(_("Verifying wallet integrity..."));
+
+ if (!bitdb.Open(GetDataDir()))
+ {
+ string msg = strprintf(_("Error initializing database environment %s!"
+ " To recover, BACKUP THAT DIRECTORY, then remove"
+ " everything from it except for wallet.dat."), strDataDir.c_str());
+ return InitError(msg);
+ }
+
+ if (GetBoolArg("-salvagewallet"))
+ {
+ // Recover readable keypairs:
+ if (!CWalletDB::Recover(bitdb, "wallet.dat", true))
+ return false;
+ }
+
+ if (filesystem::exists(GetDataDir() / "wallet.dat"))
+ {
+ CDBEnv::VerifyResult r = bitdb.Verify("wallet.dat", CWalletDB::Recover);
+ if (r == CDBEnv::RECOVER_OK)
+ {
+ string msg = strprintf(_("Warning: wallet.dat corrupt, data salvaged!"
+ " Original wallet.dat saved as wallet.{timestamp}.bak in %s; if"
+ " your balance or transactions are incorrect you should"
+ " restore from a backup."), strDataDir.c_str());
+ InitWarning(msg);
+ }
+ if (r == CDBEnv::RECOVER_FAIL)
+ return InitError(_("wallet.dat corrupt, salvage failed"));
+ }
+
+ // ********************************************************* Step 6: network initialization
int nSocksVersion = GetArg("-socks", 5);
@@ -550,32 +709,28 @@ bool AppInit2()
#endif
bool fBound = false;
- if (!fNoListen)
- {
- std::string strError;
+ if (!fNoListen) {
if (mapArgs.count("-bind")) {
BOOST_FOREACH(std::string strBind, mapMultiArgs["-bind"]) {
CService addrBind;
if (!Lookup(strBind.c_str(), addrBind, GetListenPort(), false))
return InitError(strprintf(_("Cannot resolve -bind address: '%s'"), strBind.c_str()));
- fBound |= Bind(addrBind);
+ fBound |= Bind(addrBind, (BF_EXPLICIT | BF_REPORT_ERROR));
}
- } else {
+ }
+ else {
struct in_addr inaddr_any;
inaddr_any.s_addr = INADDR_ANY;
#ifdef USE_IPV6
- if (!IsLimited(NET_IPV6))
- fBound |= Bind(CService(in6addr_any, GetListenPort()), false);
+ fBound |= Bind(CService(in6addr_any, GetListenPort()), BF_NONE);
#endif
- if (!IsLimited(NET_IPV4))
- fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound);
+ fBound |= Bind(CService(inaddr_any, GetListenPort()), !fBound ? BF_REPORT_ERROR : BF_NONE);
}
if (!fBound)
return InitError(_("Failed to listen on any port. Use -listen=0 if you want this."));
}
- if (mapArgs.count("-externalip"))
- {
+ if (mapArgs.count("-externalip")) {
BOOST_FOREACH(string strAddr, mapMultiArgs["-externalip"]) {
CService addrLocal(strAddr, GetListenPort(), fNameLookup);
if (!addrLocal.IsValid())
@@ -587,21 +742,123 @@ bool AppInit2()
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
- // ********************************************************* Step 6: load blockchain
+ // ********************************************************* Step 7: load block chain
+
+ fReindex = GetBoolArg("-reindex");
- if (GetBoolArg("-loadblockindextest"))
+ if (!bitdb.Open(GetDataDir()))
{
- CTxDB txdb("r");
- txdb.LoadBlockIndex();
- PrintBlockTree();
- return false;
+ string msg = strprintf(_("Error initializing database environment %s!"
+ " To recover, BACKUP THAT DIRECTORY, then remove"
+ " everything from it except for wallet.dat."), strDataDir.c_str());
+ return InitError(msg);
}
- uiInterface.InitMessage(_("Loading block index..."));
- printf("Loading block index...\n");
- nStart = GetTimeMillis();
- if (!LoadBlockIndex())
- strErrors << _("Error loading blkindex.dat") << "\n";
+ // Upgrading to 0.8; hard-link the old blknnnn.dat files into /blocks/
+ filesystem::path blocksDir = GetDataDir() / "blocks";
+ if (!filesystem::exists(blocksDir))
+ {
+ filesystem::create_directories(blocksDir);
+ bool linked = false;
+ for (unsigned int i = 1; i < 10000; i++) {
+ filesystem::path source = GetDataDir() / strprintf("blk%04u.dat", i);
+ if (!filesystem::exists(source)) break;
+ filesystem::path dest = blocksDir / strprintf("blk%05u.dat", i-1);
+ try {
+ filesystem::create_hard_link(source, dest);
+ printf("Hardlinked %s -> %s\n", source.string().c_str(), dest.string().c_str());
+ linked = true;
+ } catch (filesystem::filesystem_error & e) {
+ // Note: hardlink creation failing is not a disaster, it just means
+ // blocks will get re-downloaded from peers.
+ printf("Error hardlinking blk%04u.dat : %s\n", i, e.what());
+ break;
+ }
+ }
+ if (linked)
+ {
+ fReindex = true;
+ }
+ }
+
+ // cache size calculations
+ size_t nTotalCache = GetArg("-dbcache", 25) << 20;
+ if (nTotalCache < (1 << 22))
+ nTotalCache = (1 << 22); // total cache cannot be less than 4 MiB
+ size_t nBlockTreeDBCache = nTotalCache / 8;
+ if (nBlockTreeDBCache > (1 << 21) && !GetBoolArg("-txindex", false))
+ nBlockTreeDBCache = (1 << 21); // block tree db cache shouldn't be larger than 2 MiB
+ nTotalCache -= nBlockTreeDBCache;
+ size_t nCoinDBCache = nTotalCache / 2; // use half of the remaining cache for coindb cache
+ nTotalCache -= nCoinDBCache;
+ nCoinCacheSize = nTotalCache / 300; // coins in memory require around 300 bytes
+
+ bool fLoaded = false;
+ while (!fLoaded) {
+ bool fReset = fReindex;
+ std::string strLoadError;
+
+ uiInterface.InitMessage(_("Loading block index..."));
+
+ nStart = GetTimeMillis();
+ do {
+ try {
+ UnloadBlockIndex();
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pblocktree;
+
+ pblocktree = new CBlockTreeDB(nBlockTreeDBCache, false, fReindex);
+ pcoinsdbview = new CCoinsViewDB(nCoinDBCache, false, fReindex);
+ pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
+
+ if (fReindex)
+ pblocktree->WriteReindexing(true);
+
+ if (!LoadBlockIndex()) {
+ strLoadError = _("Error loading block database");
+ break;
+ }
+
+ // Initialize the block index (no-op if non-empty database was already loaded)
+ if (!InitBlockIndex()) {
+ strLoadError = _("Error initializing block database");
+ break;
+ }
+
+ uiInterface.InitMessage(_("Verifying database..."));
+ if (!VerifyDB()) {
+ strLoadError = _("Corrupted block database detected");
+ break;
+ }
+ } catch(std::exception &e) {
+ strLoadError = _("Error opening block database");
+ break;
+ }
+
+ fLoaded = true;
+ } while(false);
+
+ if (!fLoaded) {
+ // first suggest a reindex
+ if (!fReset) {
+ bool fRet = uiInterface.ThreadSafeMessageBox(
+ strLoadError + ".\n" + _("Do you want to rebuild the block database now?"),
+ "", CClientUIInterface::MSG_ERROR | CClientUIInterface::BTN_ABORT);
+ if (fRet) {
+ fReindex = true;
+ fRequestShutdown = false;
+ } else {
+ return false;
+ }
+ } else {
+ return InitError(strLoadError);
+ }
+ }
+ }
+
+ if (mapArgs.count("-txindex") && fTxIndex != GetBoolArg("-txindex", false))
+ return InitError(_("You need to rebuild the databases using -reindex to change -txindex"));
// as LoadBlockIndex can take several minutes, it's possible the user
// requested to kill bitcoin-qt during the last operation. If so, exit.
@@ -642,18 +899,24 @@ bool AppInit2()
return false;
}
- // ********************************************************* Step 7: load wallet
+ // ********************************************************* Step 8: load wallet
uiInterface.InitMessage(_("Loading wallet..."));
- printf("Loading wallet...\n");
+
nStart = GetTimeMillis();
bool fFirstRun = true;
pwalletMain = new CWallet("wallet.dat");
- int nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
+ DBErrors nLoadWalletRet = pwalletMain->LoadWallet(fFirstRun);
if (nLoadWalletRet != DB_LOAD_OK)
{
if (nLoadWalletRet == DB_CORRUPT)
strErrors << _("Error loading wallet.dat: Wallet corrupted") << "\n";
+ else if (nLoadWalletRet == DB_NONCRITICAL_ERROR)
+ {
+ string msg(_("Warning: error reading wallet.dat! All keys read correctly, but transaction data"
+ " or address book entries might be missing or incorrect."));
+ InitWarning(msg);
+ }
else if (nLoadWalletRet == DB_TOO_NEW)
strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n";
else if (nLoadWalletRet == DB_NEED_REWRITE)
@@ -710,7 +973,7 @@ bool AppInit2()
if (walletdb.ReadBestBlock(locator))
pindexRescan = locator.GetBlockIndex();
}
- if (pindexBest != pindexRescan)
+ if (pindexBest && pindexBest != pindexRescan)
{
uiInterface.InitMessage(_("Rescanning..."));
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
@@ -719,23 +982,26 @@ bool AppInit2()
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
}
- // ********************************************************* Step 8: import blocks
+ // ********************************************************* Step 9: import blocks
+
+ // scan for better chains in the block chain database, that are not yet connected in the active best chain
+ uiInterface.InitMessage(_("Importing blocks from block database..."));
+ CValidationState state;
+ if (!ConnectBestBlock(state))
+ strErrors << "Failed to connect best block";
+ CImportData *pimport = new CImportData();
if (mapArgs.count("-loadblock"))
{
- uiInterface.InitMessage(_("Importing blocks..."));
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
- {
- FILE *file = fopen(strFile.c_str(), "rb");
- if (file)
- LoadExternalBlockFile(file);
- }
+ pimport->vFiles.push_back(strFile);
}
+ NewThread(ThreadImport, pimport);
- // ********************************************************* Step 9: load peers
+ // ********************************************************* Step 10: load peers
uiInterface.InitMessage(_("Loading addresses..."));
- printf("Loading addresses...\n");
+
nStart = GetTimeMillis();
{
@@ -747,7 +1013,7 @@ bool AppInit2()
printf("Loaded %i addresses from peers.dat %"PRI64d"ms\n",
addrman.size(), GetTimeMillis() - nStart);
- // ********************************************************* Step 10: start node
+ // ********************************************************* Step 11: start node
if (!CheckDiskSpace())
return false;
@@ -755,11 +1021,11 @@ bool AppInit2()
RandAddSeedPerfmon();
//// debug print
- printf("mapBlockIndex.size() = %d\n", mapBlockIndex.size());
- printf("nBestHeight = %d\n", nBestHeight);
- printf("setKeyPool.size() = %d\n", pwalletMain->setKeyPool.size());
- printf("mapWallet.size() = %d\n", pwalletMain->mapWallet.size());
- printf("mapAddressBook.size() = %d\n", pwalletMain->mapAddressBook.size());
+ printf("mapBlockIndex.size() = %"PRIszu"\n", mapBlockIndex.size());
+ printf("nBestHeight = %d\n", nBestHeight);
+ printf("setKeyPool.size() = %"PRIszu"\n", pwalletMain->setKeyPool.size());
+ printf("mapWallet.size() = %"PRIszu"\n", pwalletMain->mapWallet.size());
+ printf("mapAddressBook.size() = %"PRIszu"\n", pwalletMain->mapAddressBook.size());
if (!NewThread(StartNode, NULL))
InitError(_("Error: could not start node"));
@@ -767,10 +1033,9 @@ bool AppInit2()
if (fServer)
NewThread(ThreadRPCServer, NULL);
- // ********************************************************* Step 11: finished
+ // ********************************************************* Step 12: finished
uiInterface.InitMessage(_("Done loading"));
- printf("Done loading\n");
if (!strErrors.str().empty())
return InitError(strErrors.str());
@@ -787,4 +1052,3 @@ bool AppInit2()
return true;
}
-