Skip to content

Commit 71afe3c

Browse files
committed
wallet: Introduce database handle wrapper
Abstract database handle from explicit strFilename into CWalletDBWrapper. Also move CWallet::Backup to db.cpp - as it deals with representation details this is a database specific operation.
1 parent 987a6c0 commit 71afe3c

File tree

9 files changed

+171
-97
lines changed

9 files changed

+171
-97
lines changed

src/qt/test/wallettests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ void WalletTests::walletTests()
8686
TestChain100Setup test;
8787
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
8888
bitdb.MakeMock();
89-
CWallet wallet("wallet_test.dat");
89+
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
90+
CWallet wallet(std::move(dbw));
9091
bool firstRun;
9192
wallet.LoadWallet(firstRun);
9293
{

src/wallet/db.cpp

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -359,13 +359,12 @@ void CDBEnv::CheckpointLSN(const std::string& strFile)
359359
}
360360

361361

362-
CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
362+
CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
363363
{
364364
int ret;
365365
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
366366
fFlushOnClose = fFlushOnCloseIn;
367-
if (strFilename.empty())
368-
return;
367+
const std::string& strFilename = dbw.strFile;
369368

370369
bool fCreate = strchr(pszMode, 'c') != NULL;
371370
unsigned int nFlags = DB_THREAD;
@@ -472,8 +471,12 @@ bool CDBEnv::RemoveDb(const std::string& strFile)
472471
return (rc == 0);
473472
}
474473

475-
bool CDB::Rewrite(const std::string& strFile, const char* pszSkip)
474+
bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
476475
{
476+
if (!dbw.env) {
477+
return true;
478+
}
479+
const std::string& strFile = dbw.strFile;
477480
while (true) {
478481
{
479482
LOCK(bitdb.cs_db);
@@ -487,7 +490,7 @@ bool CDB::Rewrite(const std::string& strFile, const char* pszSkip)
487490
LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
488491
std::string strFileRes = strFile + ".rewrite";
489492
{ // surround usage of db with extra {}
490-
CDB db(strFile.c_str(), "r");
493+
CDB db(dbw, "r");
491494
Db* pdbCopy = new Db(bitdb.dbenv, 0);
492495

493496
int ret = pdbCopy->open(NULL, // Txn pointer
@@ -596,9 +599,10 @@ void CDBEnv::Flush(bool fShutdown)
596599
}
597600
}
598601

599-
bool CDB::PeriodicFlush(std::string strFile)
602+
bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
600603
{
601604
bool ret = false;
605+
const std::string& strFile = dbw.strFile;
602606
TRY_LOCK(bitdb.cs_db,lockDb);
603607
if (lockDb)
604608
{
@@ -633,3 +637,45 @@ bool CDB::PeriodicFlush(std::string strFile)
633637

634638
return ret;
635639
}
640+
641+
bool CWalletDBWrapper::Rewrite(const char* pszSkip)
642+
{
643+
return CDB::Rewrite(*this, pszSkip);
644+
}
645+
646+
bool CWalletDBWrapper::Backup(const std::string& strDest)
647+
{
648+
if (!env) {
649+
return false;
650+
}
651+
while (true)
652+
{
653+
{
654+
LOCK(bitdb.cs_db);
655+
if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0)
656+
{
657+
// Flush log data to the dat file
658+
bitdb.CloseDb(strFile);
659+
bitdb.CheckpointLSN(strFile);
660+
bitdb.mapFileUseCount.erase(strFile);
661+
662+
// Copy wallet file
663+
fs::path pathSrc = GetDataDir() / strFile;
664+
fs::path pathDest(strDest);
665+
if (fs::is_directory(pathDest))
666+
pathDest /= strFile;
667+
668+
try {
669+
fs::copy_file(pathSrc, pathDest, fs::copy_option::overwrite_if_exists);
670+
LogPrintf("copied %s to %s\n", strFile, pathDest.string());
671+
return true;
672+
} catch (const fs::filesystem_error& e) {
673+
LogPrintf("error copying %s to %s - %s\n", strFile, pathDest.string(), e.what());
674+
return false;
675+
}
676+
}
677+
}
678+
MilliSleep(100);
679+
}
680+
return false;
681+
}

src/wallet/db.h

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,36 @@ class CDBEnv
8686

8787
extern CDBEnv bitdb;
8888

89+
/** An instance of this class represents one database.
90+
* For BerkeleyDB this is just a (env, strFile) tuple.
91+
**/
92+
class CWalletDBWrapper
93+
{
94+
friend class CDB;
95+
public:
96+
CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in):
97+
env(env_in), strFile(strFile_in)
98+
{
99+
}
100+
101+
/** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero
102+
*/
103+
bool Rewrite(const char* pszSkip=nullptr);
104+
105+
/** Back up the entire database to a file.
106+
*/
107+
bool Backup(const std::string& strDest);
108+
109+
/** Get a name for this database, for debugging etc.
110+
*/
111+
std::string GetName() const { return strFile; }
112+
113+
private:
114+
/** BerkeleyDB specific */
115+
CDBEnv *env;
116+
std::string strFile;
117+
};
118+
89119

90120
/** RAII class that provides access to a Berkeley database */
91121
class CDB
@@ -97,7 +127,7 @@ class CDB
97127
bool fReadOnly;
98128
bool fFlushOnClose;
99129

100-
explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
130+
explicit CDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
101131
~CDB() { Close(); }
102132

103133
public:
@@ -107,7 +137,7 @@ class CDB
107137

108138
/* flush the wallet passively (TRY_LOCK)
109139
ideal to be called periodically */
110-
static bool PeriodicFlush(std::string strFile);
140+
static bool PeriodicFlush(CWalletDBWrapper& dbw);
111141
/* verifies the database environment */
112142
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr);
113143
/* verifies the database file */
@@ -310,7 +340,7 @@ class CDB
310340
return Write(std::string("version"), nVersion);
311341
}
312342

313-
bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
343+
bool static Rewrite(CWalletDBWrapper& dbw, const char* pszSkip = NULL);
314344
};
315345

316346
#endif // BITCOIN_WALLET_DB_H

src/wallet/rpcwallet.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2076,7 +2076,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
20762076

20772077
int64_t nSleepTime = request.params[1].get_int64();
20782078
pwallet->nRelockTime = GetTime() + nSleepTime;
2079-
RPCRunLater(strprintf("lockwallet(%s)", pwallet->strWalletFile), boost::bind(LockWallet, pwallet), nSleepTime);
2079+
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
20802080

20812081
return NullUniValue;
20822082
}

src/wallet/test/wallet_test_fixture.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
1414
bitdb.MakeMock();
1515

1616
bool fFirstRun;
17-
pwalletMain = new CWallet("wallet_test.dat");
17+
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
18+
pwalletMain = new CWallet(std::move(dbw));
1819
pwalletMain->LoadWallet(fFirstRun);
1920
RegisterValidationInterface(pwalletMain);
2021

0 commit comments

Comments
 (0)