Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/wallet.cpp
// Copyright (c) 2009-2010 Satoshi Nakamoto | // Copyright (c) 2009-2010 Satoshi Nakamoto | ||||
// Copyright (c) 2009-2016 The Bitcoin Core developers | // Copyright (c) 2009-2016 The Bitcoin Core developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include "wallet/wallet.h" | #include "wallet/wallet.h" | ||||
#include "chain.h" | #include "chain.h" | ||||
#include "checkpoints.h" | #include "checkpoints.h" | ||||
#include "config.h" | #include "config.h" | ||||
#include "consensus/consensus.h" | #include "consensus/consensus.h" | ||||
#include "consensus/validation.h" | #include "consensus/validation.h" | ||||
#include "dstencode.h" | #include "dstencode.h" | ||||
#include "fs.h" | |||||
#include "key.h" | #include "key.h" | ||||
#include "keystore.h" | #include "keystore.h" | ||||
#include "net.h" | #include "net.h" | ||||
#include "policy/policy.h" | #include "policy/policy.h" | ||||
#include "primitives/block.h" | #include "primitives/block.h" | ||||
#include "primitives/transaction.h" | #include "primitives/transaction.h" | ||||
#include "script/script.h" | #include "script/script.h" | ||||
#include "script/sighashtype.h" | #include "script/sighashtype.h" | ||||
#include "script/sign.h" | #include "script/sign.h" | ||||
#include "timedata.h" | #include "timedata.h" | ||||
#include "txmempool.h" | #include "txmempool.h" | ||||
#include "ui_interface.h" | #include "ui_interface.h" | ||||
#include "util.h" | #include "util.h" | ||||
#include "utilmoneystr.h" | #include "utilmoneystr.h" | ||||
#include "validation.h" | #include "validation.h" | ||||
#include "wallet/coincontrol.h" | #include "wallet/coincontrol.h" | ||||
#include "wallet/finaltx.h" | #include "wallet/finaltx.h" | ||||
#include <boost/algorithm/string/replace.hpp> | #include <boost/algorithm/string/replace.hpp> | ||||
#include <boost/filesystem.hpp> | |||||
#include <boost/thread.hpp> | #include <boost/thread.hpp> | ||||
#include <cassert> | #include <cassert> | ||||
CWallet *pwalletMain = nullptr; | CWallet *pwalletMain = nullptr; | ||||
/** Transaction fee set by the user */ | /** Transaction fee set by the user */ | ||||
CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); | CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); | ||||
▲ Show 20 Lines • Show All 491 Lines • ▼ Show 20 Lines | bool CWallet::Verify() { | ||||
LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); | LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); | ||||
std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); | std::string walletFile = GetArg("-wallet", DEFAULT_WALLET_DAT); | ||||
LogPrintf("Using wallet %s\n", walletFile); | LogPrintf("Using wallet %s\n", walletFile); | ||||
uiInterface.InitMessage(_("Verifying wallet...")); | uiInterface.InitMessage(_("Verifying wallet...")); | ||||
// Wallet file must be a plain filename without a directory. | // Wallet file must be a plain filename without a directory. | ||||
if (walletFile != | if (walletFile != fs::basename(walletFile) + fs::extension(walletFile)) { | ||||
boost::filesystem::basename(walletFile) + | |||||
boost::filesystem::extension(walletFile)) { | |||||
return InitError( | return InitError( | ||||
strprintf(_("Wallet %s resides outside data directory %s"), | strprintf(_("Wallet %s resides outside data directory %s"), | ||||
walletFile, GetDataDir().string())); | walletFile, GetDataDir().string())); | ||||
} | } | ||||
if (!bitdb.Open(GetDataDir())) { | if (!bitdb.Open(GetDataDir())) { | ||||
// Try moving the database env out of the way. | // Try moving the database env out of the way. | ||||
boost::filesystem::path pathDatabase = GetDataDir() / "database"; | fs::path pathDatabase = GetDataDir() / "database"; | ||||
boost::filesystem::path pathDatabaseBak = | fs::path pathDatabaseBak = | ||||
GetDataDir() / strprintf("database.%d.bak", GetTime()); | GetDataDir() / strprintf("database.%d.bak", GetTime()); | ||||
try { | try { | ||||
boost::filesystem::rename(pathDatabase, pathDatabaseBak); | fs::rename(pathDatabase, pathDatabaseBak); | ||||
LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), | LogPrintf("Moved old %s to %s. Retrying.\n", pathDatabase.string(), | ||||
pathDatabaseBak.string()); | pathDatabaseBak.string()); | ||||
} catch (const boost::filesystem::filesystem_error &) { | } catch (const fs::filesystem_error &) { | ||||
// Failure is ok (well, not really, but it's not worse than what we | // Failure is ok (well, not really, but it's not worse than what we | ||||
// started with) | // started with) | ||||
} | } | ||||
// try again | // try again | ||||
if (!bitdb.Open(GetDataDir())) { | if (!bitdb.Open(GetDataDir())) { | ||||
// If it still fails, it probably means we can't even create the | // If it still fails, it probably means we can't even create the | ||||
// database env. | // database env. | ||||
return InitError(strprintf( | return InitError(strprintf( | ||||
_("Error initializing wallet database environment %s!"), | _("Error initializing wallet database environment %s!"), | ||||
GetDataDir())); | GetDataDir())); | ||||
} | } | ||||
} | } | ||||
if (GetBoolArg("-salvagewallet", false)) { | if (GetBoolArg("-salvagewallet", false)) { | ||||
// Recover readable keypairs: | // Recover readable keypairs: | ||||
if (!CWalletDB::Recover(bitdb, walletFile, true)) return false; | if (!CWalletDB::Recover(bitdb, walletFile, true)) return false; | ||||
} | } | ||||
if (boost::filesystem::exists(GetDataDir() / walletFile)) { | if (fs::exists(GetDataDir() / walletFile)) { | ||||
CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); | CDBEnv::VerifyResult r = bitdb.Verify(walletFile, CWalletDB::Recover); | ||||
if (r == CDBEnv::RECOVER_OK) { | if (r == CDBEnv::RECOVER_OK) { | ||||
InitWarning(strprintf( | InitWarning(strprintf( | ||||
_("Warning: Wallet file corrupt, data salvaged!" | _("Warning: Wallet file corrupt, data salvaged!" | ||||
" Original %s saved as %s in %s; if" | " Original %s saved as %s in %s; if" | ||||
" your balance or transactions are incorrect you should" | " your balance or transactions are incorrect you should" | ||||
" restore from a backup."), | " restore from a backup."), | ||||
walletFile, "wallet.{timestamp}.bak", GetDataDir())); | walletFile, "wallet.{timestamp}.bak", GetDataDir())); | ||||
▲ Show 20 Lines • Show All 3,797 Lines • ▼ Show 20 Lines | while (true) { | ||||
if (!bitdb.mapFileUseCount.count(strWalletFile) || | if (!bitdb.mapFileUseCount.count(strWalletFile) || | ||||
bitdb.mapFileUseCount[strWalletFile] == 0) { | bitdb.mapFileUseCount[strWalletFile] == 0) { | ||||
// Flush log data to the dat file. | // Flush log data to the dat file. | ||||
bitdb.CloseDb(strWalletFile); | bitdb.CloseDb(strWalletFile); | ||||
bitdb.CheckpointLSN(strWalletFile); | bitdb.CheckpointLSN(strWalletFile); | ||||
bitdb.mapFileUseCount.erase(strWalletFile); | bitdb.mapFileUseCount.erase(strWalletFile); | ||||
// Copy wallet file. | // Copy wallet file. | ||||
boost::filesystem::path pathSrc = GetDataDir() / strWalletFile; | fs::path pathSrc = GetDataDir() / strWalletFile; | ||||
boost::filesystem::path pathDest(strDest); | fs::path pathDest(strDest); | ||||
if (boost::filesystem::is_directory(pathDest)) { | if (fs::is_directory(pathDest)) { | ||||
pathDest /= strWalletFile; | pathDest /= strWalletFile; | ||||
} | } | ||||
try { | try { | ||||
if (boost::filesystem::equivalent(pathSrc, pathDest)) { | if (fs::equivalent(pathSrc, pathDest)) { | ||||
LogPrintf("cannot backup to wallet source file %s\n", | LogPrintf("cannot backup to wallet source file %s\n", | ||||
pathDest.string()); | pathDest.string()); | ||||
return false; | return false; | ||||
} | } | ||||
#if BOOST_VERSION >= 104000 | #if BOOST_VERSION >= 104000 | ||||
boost::filesystem::copy_file( | fs::copy_file(pathSrc, pathDest, | ||||
pathSrc, pathDest, | fs::copy_option::overwrite_if_exists); | ||||
boost::filesystem::copy_option::overwrite_if_exists); | |||||
#else | #else | ||||
boost::filesystem::copy_file(pathSrc, pathDest); | fs::copy_file(pathSrc, pathDest); | ||||
#endif | #endif | ||||
LogPrintf("copied %s to %s\n", strWalletFile, | LogPrintf("copied %s to %s\n", strWalletFile, | ||||
pathDest.string()); | pathDest.string()); | ||||
return true; | return true; | ||||
} catch (const boost::filesystem::filesystem_error &e) { | } catch (const fs::filesystem_error &e) { | ||||
LogPrintf("error copying %s to %s - %s\n", strWalletFile, | LogPrintf("error copying %s to %s - %s\n", strWalletFile, | ||||
pathDest.string(), e.what()); | pathDest.string(), e.what()); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
MilliSleep(100); | MilliSleep(100); | ||||
▲ Show 20 Lines • Show All 63 Lines • Show Last 20 Lines |