diff --git a/src/wallet/bdb.h b/src/wallet/bdb.h --- a/src/wallet/bdb.h +++ b/src/wallet/bdb.h @@ -160,6 +160,12 @@ */ void Flush(bool shutdown); + /* + * flush the wallet passively (TRY_LOCK) + * ideal to be called periodically + */ + bool PeriodicFlush(); + void IncrementUpdateCounter(); void ReloadDbEnv(); @@ -169,6 +175,9 @@ unsigned int nLastFlushed; int64_t nLastWalletUpdate; + /** Verifies the environment and database file */ + bool Verify(bilingual_str &error); + /** * Pointer to shared database environment. * @@ -238,18 +247,6 @@ void Flush(); void Close(); - /* - * flush the wallet passively (TRY_LOCK)i - * ideal to be called periodically - */ - static bool PeriodicFlush(BerkeleyDatabase &database); - /* verifies the database environment */ - static bool VerifyEnvironment(const fs::path &file_path, - bilingual_str &errorStr); - /* verifies the database file */ - static bool VerifyDatabaseFile(const fs::path &file_path, - bilingual_str &errorStr); - template bool Read(const K &key, T &value) { if (!pdb) { return false; @@ -348,9 +345,6 @@ bool TxnBegin(); bool TxnCommit(); bool TxnAbort(); - - static bool Rewrite(BerkeleyDatabase &database, - const char *pszSkip = nullptr); }; #endif // BITCOIN_WALLET_BDB_H diff --git a/src/wallet/bdb.cpp b/src/wallet/bdb.cpp --- a/src/wallet/bdb.cpp +++ b/src/wallet/bdb.cpp @@ -313,12 +313,9 @@ return &m_dbt; } -bool BerkeleyBatch::VerifyEnvironment(const fs::path &file_path, - bilingual_str &errorStr) { - std::string walletFile; - std::shared_ptr env = - GetWalletEnv(file_path, walletFile); +bool BerkeleyDatabase::Verify(bilingual_str &errorStr) { fs::path walletDir = env->Directory(); + fs::path file_path = walletDir / strFile; LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(nullptr, nullptr, nullptr)); @@ -330,22 +327,12 @@ return false; } - return true; -} - -bool BerkeleyBatch::VerifyDatabaseFile(const fs::path &file_path, - bilingual_str &errorStr) { - std::string walletFile; - std::shared_ptr env = - GetWalletEnv(file_path, walletFile); - fs::path walletDir = env->Directory(); - - if (fs::exists(walletDir / walletFile)) { - if (!env->Verify(walletFile)) { + if (fs::exists(file_path)) { + if (!env->Verify(strFile)) { errorStr = strprintf(_("%s corrupt. Try using the wallet tool " "bitcoin-wallet to salvage or restoring a backup."), - walletFile); + file_path); return false; } } @@ -540,12 +527,10 @@ Open(true); } -bool BerkeleyBatch::Rewrite(BerkeleyDatabase &database, const char *pszSkip) { - if (database.IsDummy()) { +bool BerkeleyDatabase::Rewrite(const char *pszSkip) { + if (IsDummy()) { return true; } - BerkeleyEnvironment *env = database.env.get(); - const std::string &strFile = database.strFile; while (true) { { LOCK(cs_db); @@ -559,9 +544,8 @@ bool fSuccess = true; LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); std::string strFileRes = strFile + ".rewrite"; - { - // surround usage of db with extra {} - BerkeleyBatch db(database, "r"); + { // surround usage of db with extra {} + BerkeleyBatch db(*this, "r"); std::unique_ptr pdbCopy = std::make_unique(env->dbenv.get(), 0); @@ -702,13 +686,11 @@ } } -bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase &database) { - if (database.IsDummy()) { +bool BerkeleyDatabase::PeriodicFlush() { + if (IsDummy()) { return true; } bool ret = false; - BerkeleyEnvironment *env = database.env.get(); - const std::string &strFile = database.strFile; TRY_LOCK(cs_db, lockDb); if (lockDb) { // Don't do this if any databases are in use @@ -741,10 +723,6 @@ return ret; } -bool BerkeleyDatabase::Rewrite(const char *pszSkip) { - return BerkeleyBatch::Rewrite(*this, pszSkip); -} - bool BerkeleyDatabase::Backup(const std::string &strDest) const { if (IsDummy()) { return false; diff --git a/src/wallet/salvage.cpp b/src/wallet/salvage.cpp --- a/src/wallet/salvage.cpp +++ b/src/wallet/salvage.cpp @@ -21,6 +21,13 @@ std::shared_ptr env = GetWalletEnv(file_path, filename); + if (!env->Open(true /* retry */)) { + tfm::format(std::cerr, + "Error initializing wallet database environment %s!", + env->Directory()); + return false; + } + // Recovery procedure: // move wallet file to walletfilename.timestamp.bak // Call Salvage with fAggressive=true to diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -4144,17 +4144,13 @@ WalletDatabase::Create(wallet_path); try { - if (!WalletBatch::VerifyEnvironment(wallet_path, error_string)) { - return false; - } + return database->Verify(error_string); } catch (const fs::filesystem_error &e) { error_string = Untranslated( strprintf("Error loading wallet %s. %s", location.GetName(), fsbridge::get_filesystem_error_message(e))); return false; } - - return WalletBatch::VerifyDatabaseFile(wallet_path, error_string); } std::shared_ptr CWallet::CreateWalletFromFile( diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -952,7 +952,7 @@ if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) { - if (BerkeleyBatch::PeriodicFlush(dbh)) { + if (dbh.PeriodicFlush()) { dbh.nLastFlushed = nUpdateCounter; } } @@ -961,16 +961,6 @@ fOneThread = false; } -bool WalletBatch::VerifyEnvironment(const fs::path &wallet_path, - bilingual_str &errorStr) { - return BerkeleyBatch::VerifyEnvironment(wallet_path, errorStr); -} - -bool WalletBatch::VerifyDatabaseFile(const fs::path &wallet_path, - bilingual_str &errorStr) { - return BerkeleyBatch::VerifyDatabaseFile(wallet_path, errorStr); -} - bool WalletBatch::WriteDestData(const CTxDestination &address, const std::string &key, const std::string &value) { diff --git a/src/wallet/wallettool.cpp b/src/wallet/wallettool.cpp --- a/src/wallet/wallettool.cpp +++ b/src/wallet/wallettool.cpp @@ -132,7 +132,7 @@ // Initialize the environment before recovery bilingual_str error_string; try { - WalletBatch::VerifyEnvironment(path, error_string); + database->Verify(error_string); } catch (const fs::filesystem_error &e) { error_string = Untranslated(strprintf("Error loading wallet. %s", @@ -163,14 +163,6 @@ tfm::format(std::cerr, "Error: no wallet file at %s\n", name); return false; } - bilingual_str error; - if (!WalletBatch::VerifyEnvironment(path, error)) { - tfm::format(std::cerr, - "%s\nError loading %s. Is wallet being used by other " - "process?\n", - error.original, name); - return false; - } if (command == "info") { std::shared_ptr wallet_instance = LoadWallet(name, path); diff --git a/test/functional/tool_wallet.py b/test/functional/tool_wallet.py --- a/test/functional/tool_wallet.py +++ b/test/functional/tool_wallet.py @@ -85,8 +85,7 @@ self.assert_raises_tool_error( 'Error parsing command line arguments: Invalid parameter -foo', '-foo') self.assert_raises_tool_error( - 'Error initializing wallet database environment "{}"!\nError loading wallet.dat. Is wallet being used by other process?' - .format(os.path.join(self.nodes[0].datadir, self.chain, 'wallets')), + 'Error loading wallet.dat. Is wallet being used by another process?', '-wallet=wallet.dat', 'info', )