Skip to content

Commit 3323281

Browse files
committed
wallet: CWalletDB CDB composition not inheritance
CWalletDB now contains a CDB instead of inheriting from it. This makes it easier to replace the internal transaction with a different database, without leaking through internals.
1 parent be9e1a9 commit 3323281

File tree

3 files changed

+84
-46
lines changed

3 files changed

+84
-46
lines changed

src/wallet/db.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,10 @@ class CDB
144144
bool fFlushOnClose;
145145
CDBEnv *env;
146146

147+
public:
147148
explicit CDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool fFlushOnCloseIn=true);
148149
~CDB() { Close(); }
149150

150-
public:
151151
void Flush();
152152
void Close();
153153
static bool Recover(const std::string& filename, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue));
@@ -164,7 +164,7 @@ class CDB
164164
CDB(const CDB&);
165165
void operator=(const CDB&);
166166

167-
protected:
167+
public:
168168
template <typename K, typename T>
169169
bool Read(const K& key, T& value)
170170
{

src/wallet/walletdb.cpp

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -33,46 +33,46 @@ static std::atomic<unsigned int> nWalletDBUpdateCounter;
3333
bool CWalletDB::WriteName(const std::string& strAddress, const std::string& strName)
3434
{
3535
nWalletDBUpdateCounter++;
36-
return Write(make_pair(std::string("name"), strAddress), strName);
36+
return batch.Write(std::make_pair(std::string("name"), strAddress), strName);
3737
}
3838

3939
bool CWalletDB::EraseName(const std::string& strAddress)
4040
{
4141
// This should only be used for sending addresses, never for receiving addresses,
4242
// receiving addresses must always have an address book entry if they're not change return.
4343
nWalletDBUpdateCounter++;
44-
return Erase(make_pair(std::string("name"), strAddress));
44+
return batch.Erase(std::make_pair(std::string("name"), strAddress));
4545
}
4646

4747
bool CWalletDB::WritePurpose(const std::string& strAddress, const std::string& strPurpose)
4848
{
4949
nWalletDBUpdateCounter++;
50-
return Write(make_pair(std::string("purpose"), strAddress), strPurpose);
50+
return batch.Write(std::make_pair(std::string("purpose"), strAddress), strPurpose);
5151
}
5252

5353
bool CWalletDB::ErasePurpose(const std::string& strPurpose)
5454
{
5555
nWalletDBUpdateCounter++;
56-
return Erase(make_pair(std::string("purpose"), strPurpose));
56+
return batch.Erase(std::make_pair(std::string("purpose"), strPurpose));
5757
}
5858

5959
bool CWalletDB::WriteTx(const CWalletTx& wtx)
6060
{
6161
nWalletDBUpdateCounter++;
62-
return Write(std::make_pair(std::string("tx"), wtx.GetHash()), wtx);
62+
return batch.Write(std::make_pair(std::string("tx"), wtx.GetHash()), wtx);
6363
}
6464

6565
bool CWalletDB::EraseTx(uint256 hash)
6666
{
6767
nWalletDBUpdateCounter++;
68-
return Erase(std::make_pair(std::string("tx"), hash));
68+
return batch.Erase(std::make_pair(std::string("tx"), hash));
6969
}
7070

7171
bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta)
7272
{
7373
nWalletDBUpdateCounter++;
7474

75-
if (!Write(std::make_pair(std::string("keymeta"), vchPubKey),
75+
if (!batch.Write(std::make_pair(std::string("keymeta"), vchPubKey),
7676
keyMeta, false))
7777
return false;
7878

@@ -82,7 +82,7 @@ bool CWalletDB::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, c
8282
vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
8383
vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
8484

85-
return Write(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
85+
return batch.Write(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
8686
}
8787

8888
bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
@@ -92,109 +92,109 @@ bool CWalletDB::WriteCryptedKey(const CPubKey& vchPubKey,
9292
const bool fEraseUnencryptedKey = true;
9393
nWalletDBUpdateCounter++;
9494

95-
if (!Write(std::make_pair(std::string("keymeta"), vchPubKey),
95+
if (!batch.Write(std::make_pair(std::string("keymeta"), vchPubKey),
9696
keyMeta))
9797
return false;
9898

99-
if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
99+
if (!batch.Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
100100
return false;
101101
if (fEraseUnencryptedKey)
102102
{
103-
Erase(std::make_pair(std::string("key"), vchPubKey));
104-
Erase(std::make_pair(std::string("wkey"), vchPubKey));
103+
batch.Erase(std::make_pair(std::string("key"), vchPubKey));
104+
batch.Erase(std::make_pair(std::string("wkey"), vchPubKey));
105105
}
106106
return true;
107107
}
108108

109109
bool CWalletDB::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
110110
{
111111
nWalletDBUpdateCounter++;
112-
return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
112+
return batch.Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
113113
}
114114

115115
bool CWalletDB::WriteCScript(const uint160& hash, const CScript& redeemScript)
116116
{
117117
nWalletDBUpdateCounter++;
118-
return Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false);
118+
return batch.Write(std::make_pair(std::string("cscript"), hash), *(const CScriptBase*)(&redeemScript), false);
119119
}
120120

121121
bool CWalletDB::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta)
122122
{
123123
nWalletDBUpdateCounter++;
124-
if (!Write(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)), keyMeta))
124+
if (!batch.Write(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest)), keyMeta))
125125
return false;
126-
return Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1');
126+
return batch.Write(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)), '1');
127127
}
128128

129129
bool CWalletDB::EraseWatchOnly(const CScript &dest)
130130
{
131131
nWalletDBUpdateCounter++;
132-
if (!Erase(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest))))
132+
if (!batch.Erase(std::make_pair(std::string("watchmeta"), *(const CScriptBase*)(&dest))))
133133
return false;
134-
return Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)));
134+
return batch.Erase(std::make_pair(std::string("watchs"), *(const CScriptBase*)(&dest)));
135135
}
136136

137137
bool CWalletDB::WriteBestBlock(const CBlockLocator& locator)
138138
{
139139
nWalletDBUpdateCounter++;
140-
Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
141-
return Write(std::string("bestblock_nomerkle"), locator);
140+
batch.Write(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
141+
return batch.Write(std::string("bestblock_nomerkle"), locator);
142142
}
143143

144144
bool CWalletDB::ReadBestBlock(CBlockLocator& locator)
145145
{
146-
if (Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
147-
return Read(std::string("bestblock_nomerkle"), locator);
146+
if (batch.Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
147+
return batch.Read(std::string("bestblock_nomerkle"), locator);
148148
}
149149

150150
bool CWalletDB::WriteOrderPosNext(int64_t nOrderPosNext)
151151
{
152152
nWalletDBUpdateCounter++;
153-
return Write(std::string("orderposnext"), nOrderPosNext);
153+
return batch.Write(std::string("orderposnext"), nOrderPosNext);
154154
}
155155

156156
bool CWalletDB::WriteDefaultKey(const CPubKey& vchPubKey)
157157
{
158158
nWalletDBUpdateCounter++;
159-
return Write(std::string("defaultkey"), vchPubKey);
159+
return batch.Write(std::string("defaultkey"), vchPubKey);
160160
}
161161

162162
bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool)
163163
{
164-
return Read(std::make_pair(std::string("pool"), nPool), keypool);
164+
return batch.Read(std::make_pair(std::string("pool"), nPool), keypool);
165165
}
166166

167167
bool CWalletDB::WritePool(int64_t nPool, const CKeyPool& keypool)
168168
{
169169
nWalletDBUpdateCounter++;
170-
return Write(std::make_pair(std::string("pool"), nPool), keypool);
170+
return batch.Write(std::make_pair(std::string("pool"), nPool), keypool);
171171
}
172172

173173
bool CWalletDB::ErasePool(int64_t nPool)
174174
{
175175
nWalletDBUpdateCounter++;
176-
return Erase(std::make_pair(std::string("pool"), nPool));
176+
return batch.Erase(std::make_pair(std::string("pool"), nPool));
177177
}
178178

179179
bool CWalletDB::WriteMinVersion(int nVersion)
180180
{
181-
return Write(std::string("minversion"), nVersion);
181+
return batch.Write(std::string("minversion"), nVersion);
182182
}
183183

184184
bool CWalletDB::ReadAccount(const std::string& strAccount, CAccount& account)
185185
{
186186
account.SetNull();
187-
return Read(make_pair(std::string("acc"), strAccount), account);
187+
return batch.Read(std::make_pair(std::string("acc"), strAccount), account);
188188
}
189189

190190
bool CWalletDB::WriteAccount(const std::string& strAccount, const CAccount& account)
191191
{
192-
return Write(make_pair(std::string("acc"), strAccount), account);
192+
return batch.Write(std::make_pair(std::string("acc"), strAccount), account);
193193
}
194194

195195
bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry)
196196
{
197-
return Write(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry);
197+
return batch.Write(std::make_pair(std::string("acentry"), std::make_pair(acentry.strAccount, nAccEntryNum)), acentry);
198198
}
199199

200200
bool CWalletDB::WriteAccountingEntry_Backend(const CAccountingEntry& acentry)
@@ -218,7 +218,7 @@ void CWalletDB::ListAccountCreditDebit(const std::string& strAccount, std::list<
218218
{
219219
bool fAllAccounts = (strAccount == "*");
220220

221-
Dbc* pcursor = GetCursor();
221+
Dbc* pcursor = batch.GetCursor();
222222
if (!pcursor)
223223
throw std::runtime_error(std::string(__func__) + ": cannot create DB cursor");
224224
bool setRange = true;
@@ -229,7 +229,7 @@ void CWalletDB::ListAccountCreditDebit(const std::string& strAccount, std::list<
229229
if (setRange)
230230
ssKey << std::make_pair(std::string("acentry"), std::make_pair((fAllAccounts ? std::string("") : strAccount), uint64_t(0)));
231231
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
232-
int ret = ReadAtCursor(pcursor, ssKey, ssValue, setRange);
232+
int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue, setRange);
233233
setRange = false;
234234
if (ret == DB_NOTFOUND)
235235
break;
@@ -560,15 +560,15 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
560560
LOCK(pwallet->cs_wallet);
561561
try {
562562
int nMinVersion = 0;
563-
if (Read((std::string)"minversion", nMinVersion))
563+
if (batch.Read((std::string)"minversion", nMinVersion))
564564
{
565565
if (nMinVersion > CLIENT_VERSION)
566566
return DB_TOO_NEW;
567567
pwallet->LoadMinVersion(nMinVersion);
568568
}
569569

570570
// Get cursor
571-
Dbc* pcursor = GetCursor();
571+
Dbc* pcursor = batch.GetCursor();
572572
if (!pcursor)
573573
{
574574
LogPrintf("Error getting wallet database cursor\n");
@@ -580,7 +580,7 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
580580
// Read next record
581581
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
582582
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
583-
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
583+
int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue);
584584
if (ret == DB_NOTFOUND)
585585
break;
586586
else if (ret != 0)
@@ -664,14 +664,14 @@ DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWal
664664

665665
try {
666666
int nMinVersion = 0;
667-
if (Read((std::string)"minversion", nMinVersion))
667+
if (batch.Read((std::string)"minversion", nMinVersion))
668668
{
669669
if (nMinVersion > CLIENT_VERSION)
670670
return DB_TOO_NEW;
671671
}
672672

673673
// Get cursor
674-
Dbc* pcursor = GetCursor();
674+
Dbc* pcursor = batch.GetCursor();
675675
if (!pcursor)
676676
{
677677
LogPrintf("Error getting wallet database cursor\n");
@@ -683,7 +683,7 @@ DBErrors CWalletDB::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWal
683683
// Read next record
684684
CDataStream ssKey(SER_DISK, CLIENT_VERSION);
685685
CDataStream ssValue(SER_DISK, CLIENT_VERSION);
686-
int ret = ReadAtCursor(pcursor, ssKey, ssValue);
686+
int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue);
687687
if (ret == DB_NOTFOUND)
688688
break;
689689
else if (ret != 0)
@@ -855,20 +855,20 @@ bool CWalletDB::VerifyDatabaseFile(const std::string& walletFile, const fs::path
855855
bool CWalletDB::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
856856
{
857857
nWalletDBUpdateCounter++;
858-
return Write(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
858+
return batch.Write(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
859859
}
860860

861861
bool CWalletDB::EraseDestData(const std::string &address, const std::string &key)
862862
{
863863
nWalletDBUpdateCounter++;
864-
return Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
864+
return batch.Erase(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
865865
}
866866

867867

868868
bool CWalletDB::WriteHDChain(const CHDChain& chain)
869869
{
870870
nWalletDBUpdateCounter++;
871-
return Write(std::string("hdchain"), chain);
871+
return batch.Write(std::string("hdchain"), chain);
872872
}
873873

874874
void CWalletDB::IncrementUpdateCounter()
@@ -881,3 +881,27 @@ unsigned int CWalletDB::GetUpdateCounter()
881881
return nWalletDBUpdateCounter;
882882
}
883883

884+
bool CWalletDB::TxnBegin()
885+
{
886+
return batch.TxnBegin();
887+
}
888+
889+
bool CWalletDB::TxnCommit()
890+
{
891+
return batch.TxnCommit();
892+
}
893+
894+
bool CWalletDB::TxnAbort()
895+
{
896+
return batch.TxnAbort();
897+
}
898+
899+
bool CWalletDB::ReadVersion(int& nVersion)
900+
{
901+
return batch.ReadVersion(nVersion);
902+
}
903+
904+
bool CWalletDB::WriteVersion(int nVersion)
905+
{
906+
return batch.WriteVersion(nVersion);
907+
}

src/wallet/walletdb.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,11 @@ class CKeyMetadata
123123
* database. It will be committed when the object goes out of scope.
124124
* Optionally (on by default) it will flush to disk as well.
125125
*/
126-
class CWalletDB : public CDB
126+
class CWalletDB
127127
{
128128
public:
129-
CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) : CDB(dbw, pszMode, _fFlushOnClose)
129+
CWalletDB(CWalletDBWrapper& dbw, const char* pszMode = "r+", bool _fFlushOnClose = true) :
130+
batch(dbw, pszMode, _fFlushOnClose)
130131
{
131132
}
132133

@@ -198,7 +199,20 @@ class CWalletDB : public CDB
198199

199200
static void IncrementUpdateCounter();
200201
static unsigned int GetUpdateCounter();
202+
203+
//! Begin a new transaction
204+
bool TxnBegin();
205+
//! Commit current transaction
206+
bool TxnCommit();
207+
//! Abort current transaction
208+
bool TxnAbort();
209+
//! Read wallet version
210+
bool ReadVersion(int& nVersion);
211+
//! Write wallet version
212+
bool WriteVersion(int nVersion);
201213
private:
214+
CDB batch;
215+
202216
CWalletDB(const CWalletDB&);
203217
void operator=(const CWalletDB&);
204218
};

0 commit comments

Comments
 (0)