diff options
Diffstat (limited to 'src/wallet/db.cpp')
-rw-r--r-- | src/wallet/db.cpp | 145 |
1 files changed, 72 insertions, 73 deletions
diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 553cae4d02..10a06e4b9a 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -8,7 +8,6 @@ #include <addrman.h> #include <hash.h> #include <protocol.h> -#include <util.h> #include <utilstrencodings.h> #include <wallet/walletutil.h> @@ -30,14 +29,14 @@ namespace { //! (https://docs.oracle.com/cd/E17275_01/html/programmer_reference/program_copy.html), //! so bitcoin should never create different databases with the same fileid, but //! this error can be triggered if users manually copy database files. -void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db) +void CheckUniqueFileid(const BerkeleyEnvironment& env, const std::string& filename, Db& db) { if (env.IsMock()) return; u_int8_t fileid[DB_FILE_ID_LEN]; int ret = db.get_mpf()->get_fileid(fileid); if (ret != 0) { - throw std::runtime_error(strprintf("CDB: Can't open database %s (get_fileid failed with %d)", filename, ret)); + throw std::runtime_error(strprintf("BerkeleyBatch: Can't open database %s (get_fileid failed with %d)", filename, ret)); } for (const auto& item : env.mapDb) { @@ -46,7 +45,7 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db) memcmp(fileid, item_fileid, sizeof(fileid)) == 0) { const char* item_filename = nullptr; item.second->get_dbname(&item_filename, nullptr); - throw std::runtime_error(strprintf("CDB: Can't open database %s (duplicates fileid %s from %s)", filename, + throw std::runtime_error(strprintf("BerkeleyBatch: Can't open database %s (duplicates fileid %s from %s)", filename, HexStr(std::begin(item_fileid), std::end(item_fileid)), item_filename ? item_filename : "(unknown database)")); } @@ -54,10 +53,10 @@ void CheckUniqueFileid(const CDBEnv& env, const std::string& filename, Db& db) } CCriticalSection cs_db; -std::map<std::string, CDBEnv> g_dbenvs; //!< Map from directory name to open db environment. +std::map<std::string, BerkeleyEnvironment> g_dbenvs; //!< Map from directory name to open db environment. } // namespace -CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename) +BerkeleyEnvironment* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename) { fs::path env_directory; if (fs::is_regular_file(wallet_path)) { @@ -73,7 +72,7 @@ CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename database_filename = "wallet.dat"; } LOCK(cs_db); - // Note: An ununsed temporary CDBEnv object may be created inside the + // Note: An ununsed temporary BerkeleyEnvironment object may be created inside the // emplace function if the key already exists. This is a little inefficient, // but not a big concern since the map will be changed in the future to hold // pointers instead of objects, anyway. @@ -81,10 +80,10 @@ CDBEnv* GetWalletEnv(const fs::path& wallet_path, std::string& database_filename } // -// CDB +// BerkeleyBatch // -void CDBEnv::Close() +void BerkeleyEnvironment::Close() { if (!fDbEnvInit) return; @@ -103,29 +102,29 @@ void CDBEnv::Close() int ret = dbenv->close(0); if (ret != 0) - LogPrintf("CDBEnv::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); + LogPrintf("BerkeleyEnvironment::EnvShutdown: Error %d shutting down database environment: %s\n", ret, DbEnv::strerror(ret)); if (!fMockDb) DbEnv((u_int32_t)0).remove(strPath.c_str(), 0); } -void CDBEnv::Reset() +void BerkeleyEnvironment::Reset() { dbenv.reset(new DbEnv(DB_CXX_NO_EXCEPTIONS)); fDbEnvInit = false; fMockDb = false; } -CDBEnv::CDBEnv(const fs::path& dir_path) : strPath(dir_path.string()) +BerkeleyEnvironment::BerkeleyEnvironment(const fs::path& dir_path) : strPath(dir_path.string()) { Reset(); } -CDBEnv::~CDBEnv() +BerkeleyEnvironment::~BerkeleyEnvironment() { Close(); } -bool CDBEnv::Open(bool retry) +bool BerkeleyEnvironment::Open(bool retry) { if (fDbEnvInit) return true; @@ -142,7 +141,7 @@ bool CDBEnv::Open(bool retry) fs::path pathLogDir = pathIn / "database"; TryCreateDirectories(pathLogDir); fs::path pathErrorFile = pathIn / "db.log"; - LogPrintf("CDBEnv::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); + LogPrintf("BerkeleyEnvironment::Open: LogDir=%s ErrorFile=%s\n", pathLogDir.string(), pathErrorFile.string()); unsigned int nEnvFlags = 0; if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) @@ -170,7 +169,7 @@ bool CDBEnv::Open(bool retry) S_IRUSR | S_IWUSR); if (ret != 0) { dbenv->close(0); - LogPrintf("CDBEnv::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); + LogPrintf("BerkeleyEnvironment::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); if (retry) { // try moving the database env out of the way fs::path pathDatabaseBak = pathIn / strprintf("database.%d.bak", GetTime()); @@ -195,14 +194,14 @@ bool CDBEnv::Open(bool retry) return true; } -void CDBEnv::MakeMock() +void BerkeleyEnvironment::MakeMock() { if (fDbEnvInit) - throw std::runtime_error("CDBEnv::MakeMock: Already initialized"); + throw std::runtime_error("BerkeleyEnvironment::MakeMock: Already initialized"); boost::this_thread::interruption_point(); - LogPrint(BCLog::DB, "CDBEnv::MakeMock\n"); + LogPrint(BCLog::DB, "BerkeleyEnvironment::MakeMock\n"); dbenv->set_cachesize(1, 0, 1); dbenv->set_lg_bsize(10485760 * 4); @@ -221,13 +220,13 @@ void CDBEnv::MakeMock() DB_PRIVATE, S_IRUSR | S_IWUSR); if (ret > 0) - throw std::runtime_error(strprintf("CDBEnv::MakeMock: Error %d opening database environment.", ret)); + throw std::runtime_error(strprintf("BerkeleyEnvironment::MakeMock: Error %d opening database environment.", ret)); fDbEnvInit = true; fMockDb = true; } -CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename) +BerkeleyEnvironment::VerifyResult BerkeleyEnvironment::Verify(const std::string& strFile, recoverFunc_type recoverFunc, std::string& out_backup_filename) { LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); @@ -244,10 +243,10 @@ CDBEnv::VerifyResult CDBEnv::Verify(const std::string& strFile, recoverFunc_type return (fRecovered ? VerifyResult::RECOVER_OK : VerifyResult::RECOVER_FAIL); } -bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename) +bool BerkeleyBatch::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& newFilename) { std::string filename; - CDBEnv* env = GetWalletEnv(file_path, filename); + BerkeleyEnvironment* env = GetWalletEnv(file_path, filename); // Recovery procedure: // move wallet file to walletfilename.timestamp.bak @@ -269,7 +268,7 @@ bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recove return false; } - std::vector<CDBEnv::KeyValPair> salvagedData; + std::vector<BerkeleyEnvironment::KeyValPair> salvagedData; bool fSuccess = env->Salvage(newFilename, true, salvagedData); if (salvagedData.empty()) { @@ -292,7 +291,7 @@ bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recove } DbTxn* ptxn = env->TxnBegin(); - for (CDBEnv::KeyValPair& row : salvagedData) + for (BerkeleyEnvironment::KeyValPair& row : salvagedData) { if (recoverKVcallback) { @@ -313,10 +312,10 @@ bool CDB::Recover(const fs::path& file_path, void *callbackDataIn, bool (*recove return fSuccess; } -bool CDB::VerifyEnvironment(const fs::path& file_path, std::string& errorStr) +bool BerkeleyBatch::VerifyEnvironment(const fs::path& file_path, std::string& errorStr) { std::string walletFile; - CDBEnv* env = GetWalletEnv(file_path, walletFile); + BerkeleyEnvironment* env = GetWalletEnv(file_path, walletFile); fs::path walletDir = env->Directory(); LogPrintf("Using BerkeleyDB version %s\n", DbEnv::version(0, 0, 0)); @@ -337,17 +336,17 @@ bool CDB::VerifyEnvironment(const fs::path& file_path, std::string& errorStr) return true; } -bool CDB::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, CDBEnv::recoverFunc_type recoverFunc) +bool BerkeleyBatch::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, std::string& errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc) { std::string walletFile; - CDBEnv* env = GetWalletEnv(file_path, walletFile); + BerkeleyEnvironment* env = GetWalletEnv(file_path, walletFile); fs::path walletDir = env->Directory(); if (fs::exists(walletDir / walletFile)) { std::string backup_filename; - CDBEnv::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename); - if (r == CDBEnv::VerifyResult::RECOVER_OK) + BerkeleyEnvironment::VerifyResult r = env->Verify(walletFile, recoverFunc, backup_filename); + if (r == BerkeleyEnvironment::VerifyResult::RECOVER_OK) { warningStr = strprintf(_("Warning: Wallet file corrupt, data salvaged!" " Original %s saved as %s in %s; if" @@ -355,7 +354,7 @@ bool CDB::VerifyDatabaseFile(const fs::path& file_path, std::string& warningStr, " restore from a backup."), walletFile, backup_filename, walletDir); } - if (r == CDBEnv::VerifyResult::RECOVER_FAIL) + if (r == BerkeleyEnvironment::VerifyResult::RECOVER_FAIL) { errorStr = strprintf(_("%s corrupt, salvage failed"), walletFile); return false; @@ -370,7 +369,7 @@ static const char *HEADER_END = "HEADER=END"; /* End of key/value data */ static const char *DATA_END = "DATA=END"; -bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<CDBEnv::KeyValPair>& vResult) +bool BerkeleyEnvironment::Salvage(const std::string& strFile, bool fAggressive, std::vector<BerkeleyEnvironment::KeyValPair>& vResult) { LOCK(cs_db); assert(mapFileUseCount.count(strFile) == 0); @@ -384,14 +383,14 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C Db db(dbenv.get(), 0); int result = db.verify(strFile.c_str(), nullptr, &strDump, flags); if (result == DB_VERIFY_BAD) { - LogPrintf("CDBEnv::Salvage: Database salvage found errors, all data may not be recoverable.\n"); + LogPrintf("BerkeleyEnvironment::Salvage: Database salvage found errors, all data may not be recoverable.\n"); if (!fAggressive) { - LogPrintf("CDBEnv::Salvage: Rerun with aggressive mode to ignore errors and continue.\n"); + LogPrintf("BerkeleyEnvironment::Salvage: Rerun with aggressive mode to ignore errors and continue.\n"); return false; } } if (result != 0 && result != DB_VERIFY_BAD) { - LogPrintf("CDBEnv::Salvage: Database salvage failed with result %d.\n", result); + LogPrintf("BerkeleyEnvironment::Salvage: Database salvage failed with result %d.\n", result); return false; } @@ -415,7 +414,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C break; getline(strDump, valueHex); if (valueHex == DATA_END) { - LogPrintf("CDBEnv::Salvage: WARNING: Number of keys in data does not match number of values.\n"); + LogPrintf("BerkeleyEnvironment::Salvage: WARNING: Number of keys in data does not match number of values.\n"); break; } vResult.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex))); @@ -423,7 +422,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C } if (keyHex != DATA_END) { - LogPrintf("CDBEnv::Salvage: WARNING: Unexpected end of file while reading salvage output.\n"); + LogPrintf("BerkeleyEnvironment::Salvage: WARNING: Unexpected end of file while reading salvage output.\n"); return false; } @@ -431,7 +430,7 @@ bool CDBEnv::Salvage(const std::string& strFile, bool fAggressive, std::vector<C } -void CDBEnv::CheckpointLSN(const std::string& strFile) +void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile) { dbenv->txn_checkpoint(0, 0, 0); if (fMockDb) @@ -440,15 +439,15 @@ void CDBEnv::CheckpointLSN(const std::string& strFile) } -CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr) +BerkeleyBatch::BerkeleyBatch(BerkeleyDatabase& database, const char* pszMode, bool fFlushOnCloseIn) : pdb(nullptr), activeTxn(nullptr) { fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fFlushOnClose = fFlushOnCloseIn; - env = dbw.env; - if (dbw.IsDummy()) { + env = database.env; + if (database.IsDummy()) { return; } - const std::string &strFilename = dbw.strFile; + const std::string &strFilename = database.strFile; bool fCreate = strchr(pszMode, 'c') != nullptr; unsigned int nFlags = DB_THREAD; @@ -458,7 +457,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb { LOCK(cs_db); if (!env->Open(false /* retry */)) - throw std::runtime_error("CDB: Failed to open database environment."); + throw std::runtime_error("BerkeleyBatch: Failed to open database environment."); pdb = env->mapDb[strFilename]; if (pdb == nullptr) { @@ -470,7 +469,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb DbMpoolFile* mpf = pdb_temp->get_mpf(); ret = mpf->set_flags(DB_MPOOL_NOFILE, 1); if (ret != 0) { - throw std::runtime_error(strprintf("CDB: Failed to configure for no temp file backing for database %s", strFilename)); + throw std::runtime_error(strprintf("BerkeleyBatch: Failed to configure for no temp file backing for database %s", strFilename)); } } @@ -482,7 +481,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb 0); if (ret != 0) { - throw std::runtime_error(strprintf("CDB: Error %d, can't open database %s", ret, strFilename)); + throw std::runtime_error(strprintf("BerkeleyBatch: Error %d, can't open database %s", ret, strFilename)); } // Call CheckUniqueFileid on the containing BDB environment to @@ -519,7 +518,7 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb } } -void CDB::Flush() +void BerkeleyBatch::Flush() { if (activeTxn) return; @@ -532,12 +531,12 @@ void CDB::Flush() env->dbenv->txn_checkpoint(nMinutes ? gArgs.GetArg("-dblogsize", DEFAULT_WALLET_DBLOGSIZE) * 1024 : 0, nMinutes, 0); } -void CWalletDBWrapper::IncrementUpdateCounter() +void BerkeleyDatabase::IncrementUpdateCounter() { ++nUpdateCounter; } -void CDB::Close() +void BerkeleyBatch::Close() { if (!pdb) return; @@ -555,7 +554,7 @@ void CDB::Close() } } -void CDBEnv::CloseDb(const std::string& strFile) +void BerkeleyEnvironment::CloseDb(const std::string& strFile) { { LOCK(cs_db); @@ -569,13 +568,13 @@ void CDBEnv::CloseDb(const std::string& strFile) } } -bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) +bool BerkeleyBatch::Rewrite(BerkeleyDatabase& database, const char* pszSkip) { - if (dbw.IsDummy()) { + if (database.IsDummy()) { return true; } - CDBEnv *env = dbw.env; - const std::string& strFile = dbw.strFile; + BerkeleyEnvironment *env = database.env; + const std::string& strFile = database.strFile; while (true) { { LOCK(cs_db); @@ -586,10 +585,10 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) env->mapFileUseCount.erase(strFile); bool fSuccess = true; - LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile); + LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); std::string strFileRes = strFile + ".rewrite"; { // surround usage of db with extra {} - CDB db(dbw, "r"); + BerkeleyBatch db(database, "r"); std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0); int ret = pdbCopy->open(nullptr, // Txn pointer @@ -599,7 +598,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) DB_CREATE, // Flags 0); if (ret > 0) { - LogPrintf("CDB::Rewrite: Can't create database file %s\n", strFileRes); + LogPrintf("BerkeleyBatch::Rewrite: Can't create database file %s\n", strFileRes); fSuccess = false; } @@ -649,7 +648,7 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) fSuccess = false; } if (!fSuccess) - LogPrintf("CDB::Rewrite: Failed to rewrite database file %s\n", strFileRes); + LogPrintf("BerkeleyBatch::Rewrite: Failed to rewrite database file %s\n", strFileRes); return fSuccess; } } @@ -658,11 +657,11 @@ bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) } -void CDBEnv::Flush(bool fShutdown) +void BerkeleyEnvironment::Flush(bool fShutdown) { int64_t nStart = GetTimeMillis(); // Flush log data to the actual data file on all files that are not in use - LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started"); + LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: Flush(%s)%s\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started"); if (!fDbEnvInit) return; { @@ -671,21 +670,21 @@ void CDBEnv::Flush(bool fShutdown) while (mi != mapFileUseCount.end()) { std::string strFile = (*mi).first; int nRefCount = (*mi).second; - LogPrint(BCLog::DB, "CDBEnv::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount); + LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: Flushing %s (refcount = %d)...\n", strFile, nRefCount); if (nRefCount == 0) { // Move log data to the dat file CloseDb(strFile); - LogPrint(BCLog::DB, "CDBEnv::Flush: %s checkpoint\n", strFile); + LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: %s checkpoint\n", strFile); dbenv->txn_checkpoint(0, 0, 0); - LogPrint(BCLog::DB, "CDBEnv::Flush: %s detach\n", strFile); + LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: %s detach\n", strFile); if (!fMockDb) dbenv->lsn_reset(strFile.c_str(), 0); - LogPrint(BCLog::DB, "CDBEnv::Flush: %s closed\n", strFile); + LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: %s closed\n", strFile); mapFileUseCount.erase(mi++); } else mi++; } - LogPrint(BCLog::DB, "CDBEnv::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); + LogPrint(BCLog::DB, "BerkeleyEnvironment::Flush: Flush(%s)%s took %15dms\n", fShutdown ? "true" : "false", fDbEnvInit ? "" : " database not started", GetTimeMillis() - nStart); if (fShutdown) { char** listp; if (mapFileUseCount.empty()) { @@ -698,14 +697,14 @@ void CDBEnv::Flush(bool fShutdown) } } -bool CDB::PeriodicFlush(CWalletDBWrapper& dbw) +bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase& database) { - if (dbw.IsDummy()) { + if (database.IsDummy()) { return true; } bool ret = false; - CDBEnv *env = dbw.env; - const std::string& strFile = dbw.strFile; + BerkeleyEnvironment *env = database.env; + const std::string& strFile = database.strFile; TRY_LOCK(cs_db, lockDb); if (lockDb) { @@ -741,12 +740,12 @@ bool CDB::PeriodicFlush(CWalletDBWrapper& dbw) return ret; } -bool CWalletDBWrapper::Rewrite(const char* pszSkip) +bool BerkeleyDatabase::Rewrite(const char* pszSkip) { - return CDB::Rewrite(*this, pszSkip); + return BerkeleyBatch::Rewrite(*this, pszSkip); } -bool CWalletDBWrapper::Backup(const std::string& strDest) +bool BerkeleyDatabase::Backup(const std::string& strDest) { if (IsDummy()) { return false; @@ -787,7 +786,7 @@ bool CWalletDBWrapper::Backup(const std::string& strDest) } } -void CWalletDBWrapper::Flush(bool shutdown) +void BerkeleyDatabase::Flush(bool shutdown) { if (!IsDummy()) { env->Flush(shutdown); |