Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/bdb.cpp
Show First 20 Lines • Show All 307 Lines • ▼ Show 20 Lines | |||||
u_int32_t BerkeleyBatch::SafeDbt::get_size() const { | u_int32_t BerkeleyBatch::SafeDbt::get_size() const { | ||||
return m_dbt.get_size(); | return m_dbt.get_size(); | ||||
} | } | ||||
BerkeleyBatch::SafeDbt::operator Dbt *() { | BerkeleyBatch::SafeDbt::operator Dbt *() { | ||||
return &m_dbt; | return &m_dbt; | ||||
} | } | ||||
bool BerkeleyBatch::VerifyEnvironment(const fs::path &file_path, | bool BerkeleyDatabase::Verify(bilingual_str &errorStr) { | ||||
bilingual_str &errorStr) { | |||||
std::string walletFile; | |||||
std::shared_ptr<BerkeleyEnvironment> env = | |||||
GetWalletEnv(file_path, walletFile); | |||||
fs::path walletDir = env->Directory(); | fs::path walletDir = env->Directory(); | ||||
fs::path file_path = walletDir / strFile; | |||||
LogPrintf("Using BerkeleyDB version %s\n", | LogPrintf("Using BerkeleyDB version %s\n", | ||||
DbEnv::version(nullptr, nullptr, nullptr)); | DbEnv::version(nullptr, nullptr, nullptr)); | ||||
LogPrintf("Using wallet %s\n", file_path.string()); | LogPrintf("Using wallet %s\n", file_path.string()); | ||||
if (!env->Open(true /* retry */)) { | if (!env->Open(true /* retry */)) { | ||||
errorStr = strprintf( | errorStr = strprintf( | ||||
_("Error initializing wallet database environment %s!"), walletDir); | _("Error initializing wallet database environment %s!"), walletDir); | ||||
return false; | return false; | ||||
} | } | ||||
return true; | if (fs::exists(file_path)) { | ||||
} | if (!env->Verify(strFile)) { | ||||
bool BerkeleyBatch::VerifyDatabaseFile(const fs::path &file_path, | |||||
bilingual_str &errorStr) { | |||||
std::string walletFile; | |||||
std::shared_ptr<BerkeleyEnvironment> env = | |||||
GetWalletEnv(file_path, walletFile); | |||||
fs::path walletDir = env->Directory(); | |||||
if (fs::exists(walletDir / walletFile)) { | |||||
if (!env->Verify(walletFile)) { | |||||
errorStr = | errorStr = | ||||
strprintf(_("%s corrupt. Try using the wallet tool " | strprintf(_("%s corrupt. Try using the wallet tool " | ||||
"bitcoin-wallet to salvage or restoring a backup."), | "bitcoin-wallet to salvage or restoring a backup."), | ||||
walletFile); | file_path); | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
// also return true if files does not exists | // also return true if files does not exists | ||||
return true; | return true; | ||||
} | } | ||||
void BerkeleyEnvironment::CheckpointLSN(const std::string &strFile) { | void BerkeleyEnvironment::CheckpointLSN(const std::string &strFile) { | ||||
▲ Show 20 Lines • Show All 178 Lines • ▼ Show 20 Lines | void BerkeleyEnvironment::ReloadDbEnv() { | ||||
} | } | ||||
// Reset the environment | // Reset the environment | ||||
// This will flush and close the environment | // This will flush and close the environment | ||||
Flush(true); | Flush(true); | ||||
Reset(); | Reset(); | ||||
Open(true); | Open(true); | ||||
} | } | ||||
bool BerkeleyBatch::Rewrite(BerkeleyDatabase &database, const char *pszSkip) { | bool BerkeleyDatabase::Rewrite(const char *pszSkip) { | ||||
if (database.IsDummy()) { | if (IsDummy()) { | ||||
return true; | return true; | ||||
} | } | ||||
BerkeleyEnvironment *env = database.env.get(); | |||||
const std::string &strFile = database.strFile; | |||||
while (true) { | while (true) { | ||||
{ | { | ||||
LOCK(cs_db); | LOCK(cs_db); | ||||
if (!env->mapFileUseCount.count(strFile) || | if (!env->mapFileUseCount.count(strFile) || | ||||
env->mapFileUseCount[strFile] == 0) { | env->mapFileUseCount[strFile] == 0) { | ||||
// Flush log data to the dat file | // Flush log data to the dat file | ||||
env->CloseDb(strFile); | env->CloseDb(strFile); | ||||
env->CheckpointLSN(strFile); | env->CheckpointLSN(strFile); | ||||
env->mapFileUseCount.erase(strFile); | env->mapFileUseCount.erase(strFile); | ||||
bool fSuccess = true; | bool fSuccess = true; | ||||
LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); | LogPrintf("BerkeleyBatch::Rewrite: Rewriting %s...\n", strFile); | ||||
std::string strFileRes = strFile + ".rewrite"; | std::string strFileRes = strFile + ".rewrite"; | ||||
{ | { // surround usage of db with extra {} | ||||
// surround usage of db with extra {} | BerkeleyBatch db(*this, "r"); | ||||
BerkeleyBatch db(database, "r"); | |||||
std::unique_ptr<Db> pdbCopy = | std::unique_ptr<Db> pdbCopy = | ||||
std::make_unique<Db>(env->dbenv.get(), 0); | std::make_unique<Db>(env->dbenv.get(), 0); | ||||
int ret = pdbCopy->open(nullptr, // Txn pointer | int ret = pdbCopy->open(nullptr, // Txn pointer | ||||
strFileRes.c_str(), // Filename | strFileRes.c_str(), // Filename | ||||
"main", // Logical db name | "main", // Logical db name | ||||
DB_BTREE, // Database type | DB_BTREE, // Database type | ||||
DB_CREATE, // Flags | DB_CREATE, // Flags | ||||
▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | if (!fDbEnvInit) { | ||||
if (!fMockDb) { | if (!fMockDb) { | ||||
fs::remove_all(fs::path(strPath) / "database"); | fs::remove_all(fs::path(strPath) / "database"); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
} | } | ||||
bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase &database) { | bool BerkeleyDatabase::PeriodicFlush() { | ||||
if (database.IsDummy()) { | if (IsDummy()) { | ||||
return true; | return true; | ||||
} | } | ||||
bool ret = false; | bool ret = false; | ||||
BerkeleyEnvironment *env = database.env.get(); | |||||
const std::string &strFile = database.strFile; | |||||
TRY_LOCK(cs_db, lockDb); | TRY_LOCK(cs_db, lockDb); | ||||
if (lockDb) { | if (lockDb) { | ||||
// Don't do this if any databases are in use | // Don't do this if any databases are in use | ||||
int nRefCount = 0; | int nRefCount = 0; | ||||
std::map<std::string, int>::iterator mit = env->mapFileUseCount.begin(); | std::map<std::string, int>::iterator mit = env->mapFileUseCount.begin(); | ||||
while (mit != env->mapFileUseCount.end()) { | while (mit != env->mapFileUseCount.end()) { | ||||
nRefCount += (*mit).second; | nRefCount += (*mit).second; | ||||
mit++; | mit++; | ||||
Show All 16 Lines | if (lockDb) { | ||||
ret = true; | ret = true; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
return ret; | return ret; | ||||
} | } | ||||
bool BerkeleyDatabase::Rewrite(const char *pszSkip) { | |||||
return BerkeleyBatch::Rewrite(*this, pszSkip); | |||||
} | |||||
bool BerkeleyDatabase::Backup(const std::string &strDest) const { | bool BerkeleyDatabase::Backup(const std::string &strDest) const { | ||||
if (IsDummy()) { | if (IsDummy()) { | ||||
return false; | return false; | ||||
} | } | ||||
while (true) { | while (true) { | ||||
{ | { | ||||
LOCK(cs_db); | LOCK(cs_db); | ||||
if (!env->mapFileUseCount.count(strFile) || | if (!env->mapFileUseCount.count(strFile) || | ||||
▲ Show 20 Lines • Show All 124 Lines • Show Last 20 Lines |