Browse Source

wallet: Get rid of fFileBacked

Instead, CWalletDB() with a dummy handle will just give you a no-op
database in which writes always succeeds and reads always fail. CDB
already had functionality for this, so just use that.
0.15
Wladimir J. van der Laan 8 years ago
parent
commit
071c95570b
  1. 12
      src/wallet/db.cpp
  2. 14
      src/wallet/db.h
  3. 43
      src/wallet/wallet.cpp
  4. 12
      src/wallet/wallet.h

12
src/wallet/db.cpp

@ -364,7 +364,10 @@ CDB::CDB(CWalletDBWrapper& dbw, const char* pszMode, bool fFlushOnCloseIn) : pdb
int ret; int ret;
fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w')); fReadOnly = (!strchr(pszMode, '+') && !strchr(pszMode, 'w'));
fFlushOnClose = fFlushOnCloseIn; fFlushOnClose = fFlushOnCloseIn;
const std::string& strFilename = dbw.strFile; if (dbw.IsDummy()) {
return;
}
const std::string &strFilename = dbw.strFile;
bool fCreate = strchr(pszMode, 'c') != NULL; bool fCreate = strchr(pszMode, 'c') != NULL;
unsigned int nFlags = DB_THREAD; unsigned int nFlags = DB_THREAD;
@ -473,7 +476,7 @@ bool CDBEnv::RemoveDb(const std::string& strFile)
bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip) bool CDB::Rewrite(CWalletDBWrapper& dbw, const char* pszSkip)
{ {
if (!dbw.env) { if (dbw.IsDummy()) {
return true; return true;
} }
const std::string& strFile = dbw.strFile; const std::string& strFile = dbw.strFile;
@ -601,6 +604,9 @@ void CDBEnv::Flush(bool fShutdown)
bool CDB::PeriodicFlush(CWalletDBWrapper& dbw) bool CDB::PeriodicFlush(CWalletDBWrapper& dbw)
{ {
if (dbw.IsDummy()) {
return true;
}
bool ret = false; bool ret = false;
const std::string& strFile = dbw.strFile; const std::string& strFile = dbw.strFile;
TRY_LOCK(bitdb.cs_db,lockDb); TRY_LOCK(bitdb.cs_db,lockDb);
@ -645,7 +651,7 @@ bool CWalletDBWrapper::Rewrite(const char* pszSkip)
bool CWalletDBWrapper::Backup(const std::string& strDest) bool CWalletDBWrapper::Backup(const std::string& strDest)
{ {
if (!env) { if (IsDummy()) {
return false; return false;
} }
while (true) while (true)

14
src/wallet/db.h

@ -93,6 +93,12 @@ class CWalletDBWrapper
{ {
friend class CDB; friend class CDB;
public: public:
/** Create dummy DB handle */
CWalletDBWrapper(): env(nullptr)
{
}
/** Create DB handle to real database */
CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in): CWalletDBWrapper(CDBEnv *env_in, const std::string &strFile_in):
env(env_in), strFile(strFile_in) env(env_in), strFile(strFile_in)
{ {
@ -110,6 +116,12 @@ public:
*/ */
std::string GetName() const { return strFile; } std::string GetName() const { return strFile; }
/** Return whether this database handle is a dummy for testing.
* Only to be used at a low level, application should ideally not care
* about this.
*/
bool IsDummy() { return env == nullptr; }
private: private:
/** BerkeleyDB specific */ /** BerkeleyDB specific */
CDBEnv *env; CDBEnv *env;
@ -186,7 +198,7 @@ protected:
bool Write(const K& key, const T& value, bool fOverwrite = true) bool Write(const K& key, const T& value, bool fOverwrite = true)
{ {
if (!pdb) if (!pdb)
return false; return true;
if (fReadOnly) if (fReadOnly)
assert(!"Write called on database in read-only mode"); assert(!"Write called on database in read-only mode");

43
src/wallet/wallet.cpp

@ -180,8 +180,6 @@ bool CWallet::AddKeyPubKey(const CKey& secret, const CPubKey &pubkey)
if (HaveWatchOnly(script)) if (HaveWatchOnly(script))
RemoveWatchOnly(script); RemoveWatchOnly(script);
if (!fFileBacked)
return true;
if (!IsCrypted()) { if (!IsCrypted()) {
return CWalletDB(*dbw).WriteKey(pubkey, return CWalletDB(*dbw).WriteKey(pubkey,
secret.GetPrivKey(), secret.GetPrivKey(),
@ -195,8 +193,6 @@ bool CWallet::AddCryptedKey(const CPubKey &vchPubKey,
{ {
if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret)) if (!CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret))
return false; return false;
if (!fFileBacked)
return true;
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
if (pwalletdbEncryption) if (pwalletdbEncryption)
@ -240,8 +236,6 @@ bool CWallet::AddCScript(const CScript& redeemScript)
{ {
if (!CCryptoKeyStore::AddCScript(redeemScript)) if (!CCryptoKeyStore::AddCScript(redeemScript))
return false; return false;
if (!fFileBacked)
return true;
return CWalletDB(*dbw).WriteCScript(Hash160(redeemScript), redeemScript); return CWalletDB(*dbw).WriteCScript(Hash160(redeemScript), redeemScript);
} }
@ -268,8 +262,6 @@ bool CWallet::AddWatchOnly(const CScript& dest)
const CKeyMetadata& meta = mapKeyMetadata[CScriptID(dest)]; const CKeyMetadata& meta = mapKeyMetadata[CScriptID(dest)];
UpdateTimeFirstKey(meta.nCreateTime); UpdateTimeFirstKey(meta.nCreateTime);
NotifyWatchonlyChanged(true); NotifyWatchonlyChanged(true);
if (!fFileBacked)
return true;
return CWalletDB(*dbw).WriteWatchOnly(dest, meta); return CWalletDB(*dbw).WriteWatchOnly(dest, meta);
} }
@ -286,7 +278,6 @@ bool CWallet::RemoveWatchOnly(const CScript &dest)
return false; return false;
if (!HaveWatchOnly()) if (!HaveWatchOnly())
NotifyWatchonlyChanged(false); NotifyWatchonlyChanged(false);
if (fFileBacked)
if (!CWalletDB(*dbw).EraseWatchOnly(dest)) if (!CWalletDB(*dbw).EraseWatchOnly(dest))
return false; return false;
@ -385,7 +376,6 @@ bool CWallet::SetMinVersion(enum WalletFeature nVersion, CWalletDB* pwalletdbIn,
if (nVersion > nWalletMaxVersion) if (nVersion > nWalletMaxVersion)
nWalletMaxVersion = nVersion; nWalletMaxVersion = nVersion;
if (fFileBacked)
{ {
CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(*dbw); CWalletDB* pwalletdb = pwalletdbIn ? pwalletdbIn : new CWalletDB(*dbw);
if (nWalletVersion > 40000) if (nWalletVersion > 40000)
@ -594,8 +584,6 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
{ {
LOCK(cs_wallet); LOCK(cs_wallet);
mapMasterKeys[++nMasterKeyMaxID] = kMasterKey; mapMasterKeys[++nMasterKeyMaxID] = kMasterKey;
if (fFileBacked)
{
assert(!pwalletdbEncryption); assert(!pwalletdbEncryption);
pwalletdbEncryption = new CWalletDB(*dbw); pwalletdbEncryption = new CWalletDB(*dbw);
if (!pwalletdbEncryption->TxnBegin()) { if (!pwalletdbEncryption->TxnBegin()) {
@ -604,14 +592,11 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
return false; return false;
} }
pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey); pwalletdbEncryption->WriteMasterKey(nMasterKeyMaxID, kMasterKey);
}
if (!EncryptKeys(_vMasterKey)) if (!EncryptKeys(_vMasterKey))
{ {
if (fFileBacked) {
pwalletdbEncryption->TxnAbort(); pwalletdbEncryption->TxnAbort();
delete pwalletdbEncryption; delete pwalletdbEncryption;
}
// We now probably have half of our keys encrypted in memory, and half not... // We now probably have half of our keys encrypted in memory, and half not...
// die and let the user reload the unencrypted wallet. // die and let the user reload the unencrypted wallet.
assert(false); assert(false);
@ -620,8 +605,6 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
// Encryption was introduced in version 0.4.0 // Encryption was introduced in version 0.4.0
SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true); SetMinVersion(FEATURE_WALLETCRYPT, pwalletdbEncryption, true);
if (fFileBacked)
{
if (!pwalletdbEncryption->TxnCommit()) { if (!pwalletdbEncryption->TxnCommit()) {
delete pwalletdbEncryption; delete pwalletdbEncryption;
// We now have keys encrypted in memory, but not on disk... // We now have keys encrypted in memory, but not on disk...
@ -631,7 +614,6 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
delete pwalletdbEncryption; delete pwalletdbEncryption;
pwalletdbEncryption = NULL; pwalletdbEncryption = NULL;
}
Lock(); Lock();
Unlock(strWalletPassphrase); Unlock(strWalletPassphrase);
@ -2816,8 +2798,6 @@ CAmount CWallet::GetMinimumFee(unsigned int nTxBytes, unsigned int nConfirmTarge
DBErrors CWallet::LoadWallet(bool& fFirstRunRet) DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
{ {
if (!fFileBacked)
return DB_LOAD_OK;
fFirstRunRet = false; fFirstRunRet = false;
DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this); DBErrors nLoadWalletRet = CWalletDB(*dbw,"cr+").LoadWallet(this);
if (nLoadWalletRet == DB_NEED_REWRITE) if (nLoadWalletRet == DB_NEED_REWRITE)
@ -2843,8 +2823,6 @@ DBErrors CWallet::LoadWallet(bool& fFirstRunRet)
DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut) DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
{ {
if (!fFileBacked)
return DB_LOAD_OK;
AssertLockHeld(cs_wallet); // mapWallet AssertLockHeld(cs_wallet); // mapWallet
vchDefaultKey = CPubKey(); vchDefaultKey = CPubKey();
DBErrors nZapSelectTxRet = CWalletDB(*dbw,"cr+").ZapSelectTx(vHashIn, vHashOut); DBErrors nZapSelectTxRet = CWalletDB(*dbw,"cr+").ZapSelectTx(vHashIn, vHashOut);
@ -2873,8 +2851,6 @@ DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256
DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx) DBErrors CWallet::ZapWalletTx(std::vector<CWalletTx>& vWtx)
{ {
if (!fFileBacked)
return DB_LOAD_OK;
vchDefaultKey = CPubKey(); vchDefaultKey = CPubKey();
DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx); DBErrors nZapWalletTxRet = CWalletDB(*dbw,"cr+").ZapWalletTx(vWtx);
if (nZapWalletTxRet == DB_NEED_REWRITE) if (nZapWalletTxRet == DB_NEED_REWRITE)
@ -2909,8 +2885,6 @@ bool CWallet::SetAddressBook(const CTxDestination& address, const std::string& s
} }
NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO, NotifyAddressBookChanged(this, address, strName, ::IsMine(*this, address) != ISMINE_NO,
strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) ); strPurpose, (fUpdated ? CT_UPDATED : CT_NEW) );
if (!fFileBacked)
return false;
if (!strPurpose.empty() && !CWalletDB(*dbw).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose)) if (!strPurpose.empty() && !CWalletDB(*dbw).WritePurpose(CBitcoinAddress(address).ToString(), strPurpose))
return false; return false;
return CWalletDB(*dbw).WriteName(CBitcoinAddress(address).ToString(), strName); return CWalletDB(*dbw).WriteName(CBitcoinAddress(address).ToString(), strName);
@ -2921,33 +2895,25 @@ bool CWallet::DelAddressBook(const CTxDestination& address)
{ {
LOCK(cs_wallet); // mapAddressBook LOCK(cs_wallet); // mapAddressBook
if(fFileBacked)
{
// Delete destdata tuples associated with address // Delete destdata tuples associated with address
std::string strAddress = CBitcoinAddress(address).ToString(); std::string strAddress = CBitcoinAddress(address).ToString();
BOOST_FOREACH(const PAIRTYPE(std::string, std::string) &item, mapAddressBook[address].destdata) BOOST_FOREACH(const PAIRTYPE(std::string, std::string) &item, mapAddressBook[address].destdata)
{ {
CWalletDB(*dbw).EraseDestData(strAddress, item.first); CWalletDB(*dbw).EraseDestData(strAddress, item.first);
} }
}
mapAddressBook.erase(address); mapAddressBook.erase(address);
} }
NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED); NotifyAddressBookChanged(this, address, "", ::IsMine(*this, address) != ISMINE_NO, "", CT_DELETED);
if (!fFileBacked)
return false;
CWalletDB(*dbw).ErasePurpose(CBitcoinAddress(address).ToString()); CWalletDB(*dbw).ErasePurpose(CBitcoinAddress(address).ToString());
return CWalletDB(*dbw).EraseName(CBitcoinAddress(address).ToString()); return CWalletDB(*dbw).EraseName(CBitcoinAddress(address).ToString());
} }
bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) bool CWallet::SetDefaultKey(const CPubKey &vchPubKey)
{ {
if (fFileBacked)
{
if (!CWalletDB(*dbw).WriteDefaultKey(vchPubKey)) if (!CWalletDB(*dbw).WriteDefaultKey(vchPubKey))
return false; return false;
}
vchDefaultKey = vchPubKey; vchDefaultKey = vchPubKey;
return true; return true;
} }
@ -3081,11 +3047,8 @@ void CWallet::ReserveKeyFromKeyPool(int64_t& nIndex, CKeyPool& keypool, bool int
void CWallet::KeepKey(int64_t nIndex) void CWallet::KeepKey(int64_t nIndex)
{ {
// Remove from key pool // Remove from key pool
if (fFileBacked)
{
CWalletDB walletdb(*dbw); CWalletDB walletdb(*dbw);
walletdb.ErasePool(nIndex); walletdb.ErasePool(nIndex);
}
LogPrintf("keypool keep %d\n", nIndex); LogPrintf("keypool keep %d\n", nIndex);
} }
@ -3597,8 +3560,6 @@ bool CWallet::AddDestData(const CTxDestination &dest, const std::string &key, co
return false; return false;
mapAddressBook[dest].destdata.insert(std::make_pair(key, value)); mapAddressBook[dest].destdata.insert(std::make_pair(key, value));
if (!fFileBacked)
return true;
return CWalletDB(*dbw).WriteDestData(CBitcoinAddress(dest).ToString(), key, value); return CWalletDB(*dbw).WriteDestData(CBitcoinAddress(dest).ToString(), key, value);
} }
@ -3606,8 +3567,6 @@ bool CWallet::EraseDestData(const CTxDestination &dest, const std::string &key)
{ {
if (!mapAddressBook[dest].destdata.erase(key)) if (!mapAddressBook[dest].destdata.erase(key))
return false; return false;
if (!fFileBacked)
return true;
return CWalletDB(*dbw).EraseDestData(CBitcoinAddress(dest).ToString(), key); return CWalletDB(*dbw).EraseDestData(CBitcoinAddress(dest).ToString(), key);
} }
@ -3979,8 +3938,6 @@ bool CWallet::ParameterInteraction()
bool CWallet::BackupWallet(const std::string& strDest) bool CWallet::BackupWallet(const std::string& strDest)
{ {
if (!fFileBacked)
return false;
return dbw->Backup(strDest); return dbw->Backup(strDest);
} }

12
src/wallet/wallet.h

@ -698,8 +698,6 @@ private:
/* HD derive new child key (on internal or external chain) */ /* HD derive new child key (on internal or external chain) */
void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret, bool internal = false); void DeriveNewChildKey(CKeyMetadata& metadata, CKey& secret, bool internal = false);
bool fFileBacked;
std::set<int64_t> setKeyPool; std::set<int64_t> setKeyPool;
int64_t nTimeFirstKey; int64_t nTimeFirstKey;
@ -720,9 +718,7 @@ private:
public: public:
/* /*
* Main wallet lock. * Main wallet lock.
* This lock protects all the fields added by CWallet * This lock protects all the fields added by CWallet.
* except for:
* fFileBacked (immutable after instantiation)
*/ */
mutable CCriticalSection cs_wallet; mutable CCriticalSection cs_wallet;
@ -765,15 +761,16 @@ public:
MasterKeyMap mapMasterKeys; MasterKeyMap mapMasterKeys;
unsigned int nMasterKeyMaxID; unsigned int nMasterKeyMaxID;
CWallet() // Create wallet with dummy database handle
CWallet(): dbw(new CWalletDBWrapper())
{ {
SetNull(); SetNull();
} }
// Create wallet with passed-in database handle
CWallet(std::unique_ptr<CWalletDBWrapper> dbw_in) : dbw(std::move(dbw_in)) CWallet(std::unique_ptr<CWalletDBWrapper> dbw_in) : dbw(std::move(dbw_in))
{ {
SetNull(); SetNull();
fFileBacked = true;
} }
~CWallet() ~CWallet()
@ -786,7 +783,6 @@ public:
{ {
nWalletVersion = FEATURE_BASE; nWalletVersion = FEATURE_BASE;
nWalletMaxVersion = FEATURE_BASE; nWalletMaxVersion = FEATURE_BASE;
fFileBacked = false;
nMasterKeyMaxID = 0; nMasterKeyMaxID = 0;
pwalletdbEncryption = NULL; pwalletdbEncryption = NULL;
nOrderPosNext = 0; nOrderPosNext = 0;

Loading…
Cancel
Save