mirror of
https://github.com/dashpay/dash.git
synced 2024-12-26 04:22:55 +01:00
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.
This commit is contained in:
parent
987a6c0956
commit
71afe3c099
@ -86,7 +86,8 @@ void WalletTests::walletTests()
|
||||
TestChain100Setup test;
|
||||
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
|
||||
bitdb.MakeMock();
|
||||
CWallet wallet("wallet_test.dat");
|
||||
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
|
||||
CWallet wallet(std::move(dbw));
|
||||
bool firstRun;
|
||||
wallet.LoadWallet(firstRun);
|
||||
{
|
||||
|
@ -359,13 +359,12 @@ void CDBEnv::CheckpointLSN(const std::string& strFile)
|
||||
}
|
||||
|
||||
|
||||
CDB::CDB(const std::string& strFilename, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
|
||||
CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb(NULL), activeTxn(NULL)
|
||||
{
|
||||
int ret;
|
||||
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
|
||||
fFlushOnClose = fFlushOnCloseIn;
|
||||
if (strFilename.empty())
|
||||
return;
|
||||
const std::string& strFilename = dbw.strFile;
|
||||
|
||||
bool fCreate = strchr(pszMode, 'c') != NULL;
|
||||
unsigned int nFlags = DB_THREAD;
|
||||
@ -472,8 +471,12 @@ bool CDBEnv::RemoveDb(const std::string& strFile)
|
||||
return (rc == 0);
|
||||
}
|
||||
|
||||
bool CDB::Rewrite(const std::string& strFile, const char* pszSkip)
|
||||
bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
|
||||
{
|
||||
if (!dbw.env) {
|
||||
return true;
|
||||
}
|
||||
const std::string& strFile = dbw.strFile;
|
||||
while (true) {
|
||||
{
|
||||
LOCK(bitdb.cs_db);
|
||||
@ -487,7 +490,7 @@ bool CDB::Rewrite(const std::string& strFile, const char* pszSkip)
|
||||
LogPrintf("CDB::Rewrite: Rewriting %s...\n", strFile);
|
||||
std::string strFileRes = strFile + ".rewrite";
|
||||
{ // surround usage of db with extra {}
|
||||
CDB db(strFile.c_str(), "r");
|
||||
CDB db(dbw, "r");
|
||||
Db* pdbCopy = new Db(bitdb.dbenv, 0);
|
||||
|
||||
int ret = pdbCopy->open(NULL, // Txn pointer
|
||||
@ -596,9 +599,10 @@ void CDBEnv::Flush(bool fShutdown)
|
||||
}
|
||||
}
|
||||
|
||||
bool CDB::PeriodicFlush(std::string strFile)
|
||||
bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
|
||||
{
|
||||
bool ret = false;
|
||||
const std::string& strFile = dbw.strFile;
|
||||
TRY_LOCK(bitdb.cs_db,lockDb);
|
||||
if (lockDb)
|
||||
{
|
||||
@ -633,3 +637,45 @@ bool CDB::PeriodicFlush(std::string strFile)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CWalletDBWrapper::Rewrite(const char* pszSkip)
|
||||
{
|
||||
return CDB::Rewrite(*this, pszSkip);
|
||||
}
|
||||
|
||||
bool CWalletDBWrapper::Backup(const std::string& strDest)
|
||||
{
|
||||
if (!env) {
|
||||
return false;
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
LOCK(bitdb.cs_db);
|
||||
if (!bitdb.mapFileUseCount.count(strFile) || bitdb.mapFileUseCount[strFile] == 0)
|
||||
{
|
||||
// Flush log data to the dat file
|
||||
bitdb.CloseDb(strFile);
|
||||
bitdb.CheckpointLSN(strFile);
|
||||
bitdb.mapFileUseCount.erase(strFile);
|
||||
|
||||
// Copy wallet file
|
||||
fs::path pathSrc = GetDataDir() / strFile;
|
||||
fs::path pathDest(strDest);
|
||||
if (fs::is_directory(pathDest))
|
||||
pathDest /= strFile;
|
||||
|
||||
try {
|
||||
fs::copy_file(pathSrc, pathDest, fs::copy_option::overwrite_if_exists);
|
||||
LogPrintf("copied %s to %s\n", strFile, pathDest.string());
|
||||
return true;
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
LogPrintf("error copying %s to %s - %s\n", strFile, pathDest.string(), e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
MilliSleep(100);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -86,6 +86,36 @@ public:
|
||||
|
||||
extern CDBEnv bitdb;
|
||||
|
||||
/** An instance of this class represents one database.
|
||||
* For BerkeleyDB this is just a (env, strFile) tuple.
|
||||
**/
|
||||
class CWalletDBWrapper
|
||||
{
|
||||
friend class CDB;
|
||||
public:
|
||||
CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in):
|
||||
env(env_in), strFile(strFile_in)
|
||||
{
|
||||
}
|
||||
|
||||
/** Rewrite the entire database on disk, with the exception of key pszSkip if non-zero
|
||||
*/
|
||||
bool Rewrite(const char* pszSkip=nullptr);
|
||||
|
||||
/** Back up the entire database to a file.
|
||||
*/
|
||||
bool Backup(const std::string& strDest);
|
||||
|
||||
/** Get a name for this database, for debugging etc.
|
||||
*/
|
||||
std::string GetName() const { return strFile; }
|
||||
|
||||
private:
|
||||
/** BerkeleyDB specific */
|
||||
CDBEnv *env;
|
||||
std::string strFile;
|
||||
};
|
||||
|
||||
|
||||
/** RAII class that provides access to a Berkeley database */
|
||||
class CDB
|
||||
@ -97,7 +127,7 @@ protected:
|
||||
bool fReadOnly;
|
||||
bool fFlushOnClose;
|
||||
|
||||
explicit CDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
|
||||
explicit CDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
|
||||
~CDB() { Close(); }
|
||||
|
||||
public:
|
||||
@ -107,7 +137,7 @@ public:
|
||||
|
||||
/* flush the wallet passively (TRY_LOCK)
|
||||
ideal to be called periodically */
|
||||
static bool PeriodicFlush(std::string strFile);
|
||||
static bool PeriodicFlush(CWalletDBWrapper& dbw);
|
||||
/* verifies the database environment */
|
||||
static bool VerifyEnvironment(const std::string& walletFile, const fs::path& dataDir, std::string& errorStr);
|
||||
/* verifies the database file */
|
||||
@ -310,7 +340,7 @@ public:
|
||||
return Write(std::string("version"), nVersion);
|
||||
}
|
||||
|
||||
bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
|
||||
bool static Rewrite(CWalletDBWrapper& dbw, const char* pszSkip = NULL);
|
||||
};
|
||||
|
||||
#endif // BITCOIN_WALLET_DB_H
|
||||
|
@ -2076,7 +2076,7 @@ UniValue walletpassphrase(const JSONRPCRequest& request)
|
||||
|
||||
int64_t nSleepTime = request.params[1].get_int64();
|
||||
pwallet->nRelockTime = GetTime() + nSleepTime;
|
||||
RPCRunLater(strprintf("lockwallet(%s)", pwallet->strWalletFile), boost::bind(LockWallet, pwallet), nSleepTime);
|
||||
RPCRunLater(strprintf("lockwallet(%s)", pwallet->GetName()), boost::bind(LockWallet, pwallet), nSleepTime);
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
@ -14,7 +14,8 @@ WalletTestingSetup::WalletTestingSetup(const std::string& chainName):
|
||||
bitdb.MakeMock();
|
||||
|
||||
bool fFirstRun;
|
||||
pwalletMain = new CWallet("wallet_test.dat");
|
||||
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, "wallet_test.dat"));
|
||||
pwalletMain = new CWallet(std::move(dbw));
|
||||
pwalletMain->LoadWallet(fFirstRun);
|
||||
RegisterValidationInterface(pwalletMain);
|
||||
|
||||
|
@ -161,7 +161,7 @@ void CWallet::DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret, bool inter
|
||||
secret = childKey.key;
|
||||
metadata.hdMasterKeyID = hdChain.masterKeyID;
|
||||
// update the chain model in the database
|
||||
if (!CWalletDB(strWalletFile).WriteHDChain(hdChain))
|
||||
if (!CWalletDB(*dbw).WriteHDChain(hdChain))
|
||||
throw std::runtime_error(std::string(__func__) + ": Writing HD chain model failed");
|
||||
}
|
||||
|
||||
@ -183,7 +183,7 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
if (!IsCrypted()) {
|
||||
return CWalletDB(strWalletFile).WriteKey(pubkey,
|
||||
return CWalletDB(*dbw).WriteKey(pubkey,
|
||||
secret.GetPrivKey(),
|
||||
mapKeyMetadata[pubkey.GetID()]);
|
||||
}
|
||||
@ -204,7 +204,7 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
|
||||
vchCryptedSecret,
|
||||
mapKeyMetadata[vchPubKey.GetID()]);
|
||||
else
|
||||
return CWalletDB(strWalletFile).WriteCryptedKey(vchPubKey,
|
||||
return CWalletDB(*dbw).WriteCryptedKey(vchPubKey,
|
||||
vchCryptedSecret,
|
||||
mapKeyMetadata[vchPubKey.GetID()]);
|
||||
}
|
||||
@ -242,7 +242,7 @@ bool CWallet::AddCScript(const CScript& redeemScript)
|
||||
return false;
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).WriteCScript(Hash160(redeemScript), redeemScript);
|
||||
return CWalletDB(*dbw).WriteCScript(Hash160(redeemScript), redeemScript);
|
||||
}
|
||||
|
||||
bool CWallet::LoadCScript(const CScript& redeemScript)
|
||||
@ -270,7 +270,7 @@ bool CWallet::AddWatchOnly(const CScript& dest)
|
||||
NotifyWatchonlyChanged(true);
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).WriteWatchOnly(dest, meta);
|
||||
return CWalletDB(*dbw).WriteWatchOnly(dest, meta);
|
||||
}
|
||||
|
||||
bool CWallet::AddWatchOnly(const CScript& dest, int64_t nCreateTime)
|
||||
@ -287,7 +287,7 @@ bool CWallet::RemoveWatchOnly(const CScript &dest)
|
||||
if (!HaveWatchOnly())
|
||||
NotifyWatchonlyChanged(false);
|
||||
if (fFileBacked)
|
||||
if (!CWalletDB(strWalletFile).EraseWatchOnly(dest))
|
||||
if (!CWalletDB(*dbw).EraseWatchOnly(dest))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -353,7 +353,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||
return false;
|
||||
if (!crypter.Encrypt(_vMasterKey, pMasterKey.second.vchCryptedKey))
|
||||
return false;
|
||||
CWalletDB(strWalletFile).WriteMasterKey(pMasterKey.first, pMasterKey.second);
|
||||
CWalletDB(*dbw).WriteMasterKey(pMasterKey.first, pMasterKey.second);
|
||||
if (fWasLocked)
|
||||
Lock();
|
||||
return true;
|
||||
@ -366,7 +366,7 @@ bool CWallet::ChangeWalletPassphrase(const SecureString& strOldWalletPassphrase,
|
||||
|
||||
void CWallet::SetBestChain(const CBlockLocator& loc)
|
||||
{
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
walletdb.WriteBestBlock(loc);
|
||||
}
|
||||
|
||||
@ -387,7 +387,7 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn,
|
||||
|
||||
if (fFileBacked)
|
||||
{
|
||||
CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(strWalletFile);
|
||||
CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(*dbw);
|
||||
if (nWalletVersion > 40000)
|
||||
pwalletdb->WriteMinVersion(nWalletVersion);
|
||||
if (!pwalletdbIn)
|
||||
@ -597,7 +597,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
if (fFileBacked)
|
||||
{
|
||||
assert(!pwalletdbEncryption);
|
||||
pwalletdbEncryption = new CWalletDB(strWalletFile);
|
||||
pwalletdbEncryption = new CWalletDB(*dbw);
|
||||
if (!pwalletdbEncryption->TxnBegin()) {
|
||||
delete pwalletdbEncryption;
|
||||
pwalletdbEncryption = NULL;
|
||||
@ -651,7 +651,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
|
||||
// Need to completely rewrite the wallet file; if we don't, bdb might keep
|
||||
// bits of the unencrypted private key in slack space in the database file.
|
||||
CDB::Rewrite(strWalletFile);
|
||||
dbw->Rewrite();
|
||||
|
||||
}
|
||||
NotifyStatusChanged(this);
|
||||
@ -662,7 +662,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
|
||||
DBErrors CWallet::ReorderTransactions()
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
// Old wallets didn't have any defined order for transactions
|
||||
// Probably a bad idea to change the output of this
|
||||
@ -743,14 +743,14 @@ int64_t CWallet::IncOrderPosNext(CWalletDB *pwalletdb)
|
||||
if (pwalletdb) {
|
||||
pwalletdb->WriteOrderPosNext(nOrderPosNext);
|
||||
} else {
|
||||
CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext);
|
||||
CWalletDB(*dbw).WriteOrderPosNext(nOrderPosNext);
|
||||
}
|
||||
return nRet;
|
||||
}
|
||||
|
||||
bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmount, std::string strComment)
|
||||
{
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
if (!walletdb.TxnBegin())
|
||||
return false;
|
||||
|
||||
@ -784,7 +784,7 @@ bool CWallet::AccountMove(std::string strFrom, std::string strTo, CAmount nAmoun
|
||||
|
||||
bool CWallet::GetAccountPubkey(CPubKey &pubKey, std::string strAccount, bool bForceNew)
|
||||
{
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
CAccount account;
|
||||
walletdb.ReadAccount(strAccount, account);
|
||||
@ -845,7 +845,7 @@ bool CWallet::MarkReplaced(const uint256& originalHash, const uint256& newHash)
|
||||
|
||||
wtx.mapValue["replaced_by_txid"] = newHash.ToString();
|
||||
|
||||
CWalletDB walletdb(strWalletFile, "r+");
|
||||
CWalletDB walletdb(*dbw, "r+");
|
||||
|
||||
bool success = true;
|
||||
if (!walletdb.WriteTx(wtx)) {
|
||||
@ -862,7 +862,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFlushOnClose)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
|
||||
CWalletDB walletdb(strWalletFile, "r+", fFlushOnClose);
|
||||
CWalletDB walletdb(*dbw, "r+", fFlushOnClose);
|
||||
|
||||
uint256 hash = wtxIn.GetHash();
|
||||
|
||||
@ -1006,7 +1006,7 @@ bool CWallet::AbandonTransaction(const uint256& hashTx)
|
||||
{
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
|
||||
CWalletDB walletdb(strWalletFile, "r+");
|
||||
CWalletDB walletdb(*dbw, "r+");
|
||||
|
||||
std::set<uint256> todo;
|
||||
std::set<uint256> done;
|
||||
@ -1078,7 +1078,7 @@ void CWallet::MarkConflicted(const uint256& hashBlock, const uint256& hashTx)
|
||||
return;
|
||||
|
||||
// Do not flush the wallet here for performance reasons
|
||||
CWalletDB walletdb(strWalletFile, "r+", false);
|
||||
CWalletDB walletdb(*dbw, "r+", false);
|
||||
|
||||
std::set<uint256> todo;
|
||||
std::set<uint256> done;
|
||||
@ -1361,7 +1361,7 @@ bool CWallet::SetHDMasterKey(const CPubKey& pubkey, CHDChain *possibleOldChain)
|
||||
bool CWallet::SetHDChain(const CHDChain& chain, bool memonly)
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
if (!memonly && !CWalletDB(strWalletFile).WriteHDChain(chain))
|
||||
if (!memonly && !CWalletDB(*dbw).WriteHDChain(chain))
|
||||
throw std::runtime_error(std::string(__func__) + ": writing chain failed");
|
||||
|
||||
hdChain = chain;
|
||||
@ -2758,13 +2758,13 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon
|
||||
}
|
||||
|
||||
void CWallet::ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& entries) {
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
return walletdb.ListAccountCreditDebit(strAccount, entries);
|
||||
}
|
||||
|
||||
bool CWallet::AddAccountingEntry(const CAccountingEntry& acentry)
|
||||
{
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
return AddAccountingEntry(acentry, &walletdb);
|
||||
}
|
||||
@ -2819,10 +2819,10 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
|
||||
if (!fFileBacked)
|
||||
return DB_LOAD_OK;
|
||||
fFirstRunRet = false;
|
||||
DBErrors nLoadWalletRet = CWalletDB(strWalletFile,"cr+").LoadWallet(this);
|
||||
DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this);
|
||||
if (nLoadWalletRet == DB_NEED_REWRITE)
|
||||
{
|
||||
if (CDB::Rewrite(strWalletFile, "\x04pool"))
|
||||
if (dbw->Rewrite("\x04pool"))
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
setKeyPool.clear();
|
||||
@ -2847,13 +2847,13 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
|
||||
return DB_LOAD_OK;
|
||||
AssertLockHeld(cs_wallet); // mapWallet
|
||||
vchDefaultKey = CPubKey();
|
||||
DBErrors nZapSelectTxRet = CWalletDB(strWalletFile,"cr+").ZapSelectTx(vHashIn, vHashOut);
|
||||
DBErrors nZapSelectTxRet = CWalletDB(*dbw,"cr+").ZapSelectTx(vHashIn, vHashOut);
|
||||
for (uint256 hash : vHashOut)
|
||||
mapWallet.erase(hash);
|
||||
|
||||
if (nZapSelectTxRet == DB_NEED_REWRITE)
|
||||
{
|
||||
if (CDB::Rewrite(strWalletFile, "\x04pool"))
|
||||
if (dbw->Rewrite("\x04pool"))
|
||||
{
|
||||
setKeyPool.clear();
|
||||
// Note: can't top-up keypool here, because wallet is locked.
|
||||
@ -2876,10 +2876,10 @@ DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
|
||||
if (!fFileBacked)
|
||||
return DB_LOAD_OK;
|
||||
vchDefaultKey = CPubKey();
|
||||
DBErrors nZapWalletTxRet = CWalletDB(strWalletFile,"cr+").ZapWalletTx(vWtx);
|
||||
DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx);
|
||||
if (nZapWalletTxRet == DB_NEED_REWRITE)
|
||||
{
|
||||
if (CDB::Rewrite(strWalletFile, "\x04pool"))
|
||||
if (dbw->Rewrite("\x04pool"))
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
setKeyPool.clear();
|
||||
@ -2911,9 +2911,9 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
|
||||
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
if (!strPurpose.empty() && !CWalletDB(strWalletFile).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
|
||||
if (!strPurpose.empty() && !CWalletDB(*dbw).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
|
||||
return false;
|
||||
return CWalletDB(strWalletFile).WriteName(CBitcoinAddress(address).ToString(), strName);
|
||||
return CWalletDB(*dbw).WriteName(CBitcoinAddress(address).ToString(), strName);
|
||||
}
|
||||
|
||||
bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||
@ -2927,7 +2927,7 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||
std::string strAddress = CBitcoinAddress(address).ToString();
|
||||
BOOST_FOREACH(const PAIRTYPE(std::string, std::string) &item, mapAddressBook[address].destdata)
|
||||
{
|
||||
CWalletDB(strWalletFile).EraseDestData(strAddress, item.first);
|
||||
CWalletDB(*dbw).EraseDestData(strAddress, item.first);
|
||||
}
|
||||
}
|
||||
mapAddressBook.erase(address);
|
||||
@ -2937,15 +2937,15 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
|
||||
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
CWalletDB(strWalletFile).ErasePurpose(CBitcoinAddress(address).ToString());
|
||||
return CWalletDB(strWalletFile).EraseName(CBitcoinAddress(address).ToString());
|
||||
CWalletDB(*dbw).ErasePurpose(CBitcoinAddress(address).ToString());
|
||||
return CWalletDB(*dbw).EraseName(CBitcoinAddress(address).ToString());
|
||||
}
|
||||
|
||||
bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
|
||||
{
|
||||
if (fFileBacked)
|
||||
{
|
||||
if (!CWalletDB(strWalletFile).WriteDefaultKey(vchPubKey))
|
||||
if (!CWalletDB(*dbw).WriteDefaultKey(vchPubKey))
|
||||
return false;
|
||||
}
|
||||
vchDefaultKey = vchPubKey;
|
||||
@ -2960,7 +2960,7 @@ bool CWallet::NewKeyPool()
|
||||
{
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
BOOST_FOREACH(int64_t nIndex, setKeyPool)
|
||||
walletdb.ErasePool(nIndex);
|
||||
setKeyPool.clear();
|
||||
@ -2981,7 +2981,7 @@ size_t CWallet::KeypoolCountExternalKeys()
|
||||
if (!IsHDEnabled() || !CanSupportFeature(FEATURE_HD_SPLIT))
|
||||
return setKeyPool.size();
|
||||
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
// count amount of external keys
|
||||
size_t amountE = 0;
|
||||
@ -3024,7 +3024,7 @@ bool CWallet::TopUpKeyPool(unsigned int kpSize)
|
||||
missingInternal = 0;
|
||||
}
|
||||
bool internal = false;
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
for (int64_t i = missingInternal + missingExternal; i--;)
|
||||
{
|
||||
int64_t nEnd = 1;
|
||||
@ -3055,7 +3055,7 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool int
|
||||
if(setKeyPool.empty())
|
||||
return;
|
||||
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
// try to find a key that matches the internal/external filter
|
||||
for(const int64_t& id : setKeyPool)
|
||||
@ -3083,7 +3083,7 @@ void CWallet::KeepKey(int64_t nIndex)
|
||||
// Remove from key pool
|
||||
if (fFileBacked)
|
||||
{
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
walletdb.ErasePool(nIndex);
|
||||
}
|
||||
LogPrintf("keypool keep %d\n", nIndex);
|
||||
@ -3127,7 +3127,7 @@ int64_t CWallet::GetOldestKeyPoolTime()
|
||||
return GetTime();
|
||||
|
||||
CKeyPool keypool;
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
if (IsHDEnabled() && CanSupportFeature(FEATURE_HD_SPLIT))
|
||||
{
|
||||
@ -3295,7 +3295,7 @@ std::set< std::set<CTxDestination> > CWallet::GetAddressGroupings()
|
||||
|
||||
CAmount CWallet::GetAccountBalance(const std::string& strAccount, int nMinDepth, const isminefilter& filter)
|
||||
{
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
return GetAccountBalance(walletdb, strAccount, nMinDepth, filter);
|
||||
}
|
||||
|
||||
@ -3375,7 +3375,7 @@ void CWallet::GetAllReserveKeys(std::set<CKeyID>& setAddress) const
|
||||
{
|
||||
setAddress.clear();
|
||||
|
||||
CWalletDB walletdb(strWalletFile);
|
||||
CWalletDB walletdb(*dbw);
|
||||
|
||||
LOCK2(cs_main, cs_wallet);
|
||||
BOOST_FOREACH(const int64_t& id, setKeyPool)
|
||||
@ -3599,7 +3599,7 @@ bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, co
|
||||
mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
|
||||
return CWalletDB(*dbw).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
|
||||
}
|
||||
|
||||
bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
|
||||
@ -3608,7 +3608,7 @@ bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
|
||||
return false;
|
||||
if (!fFileBacked)
|
||||
return true;
|
||||
return CWalletDB(strWalletFile).EraseDestData(CBitcoinAddress(dest).ToString(), key);
|
||||
return CWalletDB(*dbw).EraseDestData(CBitcoinAddress(dest).ToString(), key);
|
||||
}
|
||||
|
||||
bool CWallet::LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
|
||||
@ -3678,7 +3678,8 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
|
||||
if (GetBoolArg("-zapwallettxes", false)) {
|
||||
uiInterface.InitMessage(_("Zapping all transactions from wallet..."));
|
||||
|
||||
CWallet *tempWallet = new CWallet(walletFile);
|
||||
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
|
||||
CWallet *tempWallet = new CWallet(std::move(dbw));
|
||||
DBErrors nZapWalletRet = tempWallet->ZapWalletTx(vWtx);
|
||||
if (nZapWalletRet != DB_LOAD_OK) {
|
||||
InitError(strprintf(_("Error loading %s: Wallet corrupted"), walletFile));
|
||||
@ -3693,7 +3694,8 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
|
||||
|
||||
int64_t nStart = GetTimeMillis();
|
||||
bool fFirstRun = true;
|
||||
CWallet *walletInstance = new CWallet(walletFile);
|
||||
std::unique_ptr<CWalletDBWrapper> dbw(new CWalletDBWrapper(&bitdb, walletFile));
|
||||
CWallet *walletInstance = new CWallet(std::move(dbw));
|
||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet(fFirstRun);
|
||||
if (nLoadWalletRet != DB_LOAD_OK)
|
||||
{
|
||||
@ -3784,7 +3786,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
|
||||
CBlockIndex *pindexRescan = chainActive.Genesis();
|
||||
if (!GetBoolArg("-rescan", false))
|
||||
{
|
||||
CWalletDB walletdb(walletFile);
|
||||
CWalletDB walletdb(*walletInstance->dbw);
|
||||
CBlockLocator locator;
|
||||
if (walletdb.ReadBestBlock(locator))
|
||||
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
|
||||
@ -3817,7 +3819,7 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile)
|
||||
// Restore wallet transaction metadata after -zapwallettxes=1
|
||||
if (GetBoolArg("-zapwallettxes", false) && GetArg("-zapwallettxes", "1") != "2")
|
||||
{
|
||||
CWalletDB walletdb(walletFile);
|
||||
CWalletDB walletdb(*walletInstance->dbw);
|
||||
|
||||
BOOST_FOREACH(const CWalletTx& wtxOld, vWtx)
|
||||
{
|
||||
@ -3979,36 +3981,7 @@ bool CWallet::BackupWallet(const std::string& strDest)
|
||||
{
|
||||
if (!fFileBacked)
|
||||
return false;
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
LOCK(bitdb.cs_db);
|
||||
if (!bitdb.mapFileUseCount.count(strWalletFile) || bitdb.mapFileUseCount[strWalletFile] == 0)
|
||||
{
|
||||
// Flush log data to the dat file
|
||||
bitdb.CloseDb(strWalletFile);
|
||||
bitdb.CheckpointLSN(strWalletFile);
|
||||
bitdb.mapFileUseCount.erase(strWalletFile);
|
||||
|
||||
// Copy wallet file
|
||||
fs::path pathSrc = GetDataDir() / strWalletFile;
|
||||
fs::path pathDest(strDest);
|
||||
if (fs::is_directory(pathDest))
|
||||
pathDest /= strWalletFile;
|
||||
|
||||
try {
|
||||
fs::copy_file(pathSrc, pathDest, fs::copy_option::overwrite_if_exists);
|
||||
LogPrintf("copied %s to %s\n", strWalletFile, pathDest.string());
|
||||
return true;
|
||||
} catch (const fs::filesystem_error& e) {
|
||||
LogPrintf("error copying %s to %s - %s\n", strWalletFile, pathDest.string(), e.what());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
MilliSleep(100);
|
||||
}
|
||||
return false;
|
||||
return dbw->Backup(strDest);
|
||||
}
|
||||
|
||||
CKeyPool::CKeyPool()
|
||||
|
@ -715,17 +715,35 @@ private:
|
||||
*/
|
||||
bool AddWatchOnly(const CScript& dest) override;
|
||||
|
||||
std::unique_ptr<CWalletDBWrapper> dbw;
|
||||
|
||||
public:
|
||||
/*
|
||||
* Main wallet lock.
|
||||
* This lock protects all the fields added by CWallet
|
||||
* except for:
|
||||
* fFileBacked (immutable after instantiation)
|
||||
* strWalletFile (immutable after instantiation)
|
||||
*/
|
||||
mutable CCriticalSection cs_wallet;
|
||||
|
||||
const std::string strWalletFile;
|
||||
/** Get database handle used by this wallet. Ideally this function would
|
||||
* not be necessary.
|
||||
*/
|
||||
CWalletDBWrapper& GetDBHandle()
|
||||
{
|
||||
return *dbw;
|
||||
}
|
||||
|
||||
/** Get a name for this wallet for logging/debugging purposes.
|
||||
*/
|
||||
std::string GetName() const
|
||||
{
|
||||
if (dbw) {
|
||||
return dbw->GetName();
|
||||
} else {
|
||||
return "dummy";
|
||||
}
|
||||
}
|
||||
|
||||
void LoadKeyPool(int nIndex, const CKeyPool &keypool)
|
||||
{
|
||||
@ -752,7 +770,7 @@ public:
|
||||
SetNull();
|
||||
}
|
||||
|
||||
CWallet(const std::string& strWalletFileIn) : strWalletFile(strWalletFileIn)
|
||||
CWallet(std::unique_ptr<CWalletDBWrapper> dbw_in) : dbw(std::move(dbw_in))
|
||||
{
|
||||
SetNull();
|
||||
fFileBacked = true;
|
||||
|
@ -797,9 +797,9 @@ void MaybeCompactWalletDB()
|
||||
|
||||
if (nLastFlushed != CWalletDB::GetUpdateCounter() && GetTime() - nLastWalletUpdate >= 2)
|
||||
{
|
||||
const std::string& strFile = pwalletMain->strWalletFile;
|
||||
if (CDB::PeriodicFlush(strFile))
|
||||
if (CDB::PeriodicFlush(pwalletMain->GetDBHandle())) {
|
||||
nLastFlushed = CWalletDB::GetUpdateCounter();
|
||||
}
|
||||
}
|
||||
fOneThread = false;
|
||||
}
|
||||
@ -880,3 +880,4 @@ unsigned int CWalletDB::GetUpdateCounter()
|
||||
{
|
||||
return nWalletDBUpdateCounter;
|
||||
}
|
||||
|
||||
|
@ -118,11 +118,15 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** Access to the wallet database */
|
||||
/** Access to the wallet database.
|
||||
* This should really be named CWalletDBBatch, as it represents a single transaction at the
|
||||
* database. It will be committed when the object goes out of scope.
|
||||
* Optionally (on by default) it will flush to disk as well.
|
||||
*/
|
||||
class CWalletDB : public CDB
|
||||
{
|
||||
public:
|
||||
CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool _fFlushOnClose = true) : CDB(strFilename, pszMode, _fFlushOnClose)
|
||||
CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : CDB(dbw, pszMode, _fFlushOnClose)
|
||||
{
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user