diff options
Diffstat (limited to 'src/init.cpp')
| -rw-r--r-- | src/init.cpp | 398 |
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; } - |