aboutsummaryrefslogtreecommitdiff
path: root/src/init.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/init.cpp')
-rw-r--r--src/init.cpp127
1 files changed, 89 insertions, 38 deletions
diff --git a/src/init.cpp b/src/init.cpp
index 7e2cda6297..4d5720306d 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -2,7 +2,7 @@
// 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"
@@ -50,6 +50,8 @@ void StartShutdown()
#endif
}
+static CCoinsViewDB *pcoinsdbview;
+
void Shutdown(void* parg)
{
static CCriticalSection cs_Shutdown;
@@ -74,6 +76,14 @@ void Shutdown(void* parg)
nTransactionsUpdated++;
bitdb.Flush(false);
StopNode();
+ {
+ LOCK(cs_main);
+ pcoinsTip->Flush();
+ pblocktree->Flush();
+ delete pcoinsTip;
+ delete pcoinsdbview;
+ delete pblocktree;
+ }
bitdb.Flush(true);
boost::filesystem::remove(GetPidFile());
UnregisterWallet(pwalletMain);
@@ -144,7 +154,7 @@ bool AppInit(int argc, char* argv[])
strUsage += "\n" + HelpMessage();
- fprintf(stderr, "%s", strUsage.c_str());
+ fprintf(stdout, "%s", strUsage.c_str());
return false;
}
@@ -279,6 +289,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" +
@@ -297,6 +308,7 @@ std::string HelpMessage()
return strUsage;
}
+
/** Initialize bitcoin.
* @pre Parameters should be parsed and config file should be read.
*/
@@ -379,6 +391,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,13 +451,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)
@@ -472,7 +491,7 @@ bool AppInit2()
if (!fLogTimestamps)
printf("Startup time: %s\n", DateTimeStrFormat("%x %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)
@@ -480,7 +499,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."), 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());
+ 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);
@@ -586,21 +639,25 @@ bool AppInit2()
BOOST_FOREACH(string strDest, mapMultiArgs["-seednode"])
AddOneShot(strDest);
- // ********************************************************* Step 6: load blockchain
+ // ********************************************************* Step 7: load blockchain
- 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();
+ pblocktree = new CBlockTreeDB();
+ pcoinsdbview = new CCoinsViewDB();
+ pcoinsTip = new CCoinsViewCache(*pcoinsdbview);
+
if (!LoadBlockIndex())
- strErrors << _("Error loading blkindex.dat") << "\n";
+ return InitError(_("Error loading blkindex.dat"));
// as LoadBlockIndex can take several minutes, it's possible the user
// requested to kill bitcoin-qt during the last operation. If so, exit.
@@ -641,18 +698,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)
@@ -718,33 +781,22 @@ 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..."));
+ if (!ConnectBestBlock())
+ strErrors << "Failed to connect best block";
+ std::vector<boost::filesystem::path> *vPath = new std::vector<boost::filesystem::path>();
if (mapArgs.count("-loadblock"))
{
- uiInterface.InitMessage(_("Importing blockchain data file."));
-
BOOST_FOREACH(string strFile, mapMultiArgs["-loadblock"])
- {
- FILE *file = fopen(strFile.c_str(), "rb");
- if (file)
- LoadExternalBlockFile(file);
- }
- }
-
- filesystem::path pathBootstrap = GetDataDir() / "bootstrap.dat";
- if (filesystem::exists(pathBootstrap)) {
- uiInterface.InitMessage(_("Importing bootstrap blockchain data file."));
-
- FILE *file = fopen(pathBootstrap.string().c_str(), "rb");
- if (file) {
- filesystem::path pathBootstrapOld = GetDataDir() / "bootstrap.dat.old";
- LoadExternalBlockFile(file);
- RenameOver(pathBootstrap, pathBootstrapOld);
- }
+ vPath->push_back(strFile);
}
+ NewThread(ThreadImport, vPath);
- // ********************************************************* Step 9: load peers
+ // ********************************************************* Step 10: load peers
uiInterface.InitMessage(_("Loading addresses..."));
printf("Loading addresses...\n");
@@ -759,7 +811,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;
@@ -779,7 +831,7 @@ bool AppInit2()
if (fServer)
NewThread(ThreadRPCServer, NULL);
- // ********************************************************* Step 11: finished
+ // ********************************************************* Step 12: finished
uiInterface.InitMessage(_("Done loading"));
printf("Done loading\n");
@@ -799,4 +851,3 @@ bool AppInit2()
return true;
}
-