diff options
Diffstat (limited to 'src/init.cpp')
-rw-r--r-- | src/init.cpp | 65 |
1 files changed, 56 insertions, 9 deletions
diff --git a/src/init.cpp b/src/init.cpp index d271893644..e491652382 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -279,6 +279,7 @@ 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" + + " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + "\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" + @@ -379,6 +380,11 @@ 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"); @@ -434,6 +440,8 @@ bool AppInit2() // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log + const char* pszDataDir = GetDataDir().string().c_str(); + // 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. @@ -481,7 +489,41 @@ bool AppInit2() int64 nStart; - // ********************************************************* Step 5: network initialization + // ********************************************************* Step 5: verify database integrity + + uiInterface.InitMessage(_("Verifying database 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."), pszDataDir); + 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."), pszDataDir); + uiInterface.ThreadSafeMessageBox(msg, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + } + if (r == CDBEnv::RECOVER_FAIL) + return InitError(_("wallet.dat corrupt, salvage failed")); + } + + // ********************************************************* Step 6: network initialization int nSocksVersion = GetArg("-socks", 5); @@ -587,7 +629,7 @@ bool AppInit2() BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"]) AddOneShot(strDest); - // ********************************************************* Step 6: load blockchain + // ********************************************************* Step 7: load blockchain if (!bitdb.Open(GetDataDir())) { @@ -650,18 +692,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.")); + uiInterface.ThreadSafeMessageBox(msg, _("Bitcoin"), CClientUIInterface::OK | CClientUIInterface::ICON_EXCLAMATION | CClientUIInterface::MODAL); + } else if (nLoadWalletRet == DB_TOO_NEW) strErrors << _("Error loading wallet.dat: Wallet requires newer version of Bitcoin") << "\n"; else if (nLoadWalletRet == DB_NEED_REWRITE) @@ -727,7 +775,7 @@ bool AppInit2() printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); } - // ********************************************************* Step 8: import blocks + // ********************************************************* Step 9: import blocks if (mapArgs.count("-loadblock")) { @@ -753,7 +801,7 @@ bool AppInit2() } } - // ********************************************************* Step 9: load peers + // ********************************************************* Step 10: load peers uiInterface.InitMessage(_("Loading addresses...")); printf("Loading addresses...\n"); @@ -768,7 +816,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; @@ -788,7 +836,7 @@ bool AppInit2() if (fServer) NewThread(ThreadRPCServer, NULL); - // ********************************************************* Step 11: finished + // ********************************************************* Step 12: finished uiInterface.InitMessage(_("Done loading")); printf("Done loading\n"); @@ -808,4 +856,3 @@ bool AppInit2() return true; } - |