]> Git Repo - VerusCoin.git/blame - db.h
gitian: strip binaries
[VerusCoin.git] / db.h
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
2// Distributed under the MIT/X11 software license, see the accompanying
3// file license.txt or http://www.opensource.org/licenses/mit-license.php.
4
5class CTransaction;
6class CTxIndex;
7class CDiskBlockIndex;
8class CDiskTxPos;
9class COutPoint;
10class CUser;
11class CReview;
12class CAddress;
13class CWalletTx;
e4ff4e68 14class CAccount;
15class CAccountingEntry;
6a76c60e 16class CBlockLocator;
0a61b0df 17
18extern map<string, string> mapAddressBook;
19extern CCriticalSection cs_mapAddressBook;
20extern vector<unsigned char> vchDefaultKey;
21extern bool fClient;
22extern int nBestHeight;
23
24
25extern unsigned int nWalletDBUpdated;
26extern DbEnv dbenv;
27
28
29extern void DBFlush(bool fShutdown);
776d0f34 30extern vector<unsigned char> GetKeyFromKeyPool();
31extern int64 GetOldestKeyPoolTime();
0a61b0df 32
33
34
35
36class CDB
37{
38protected:
39 Db* pdb;
40 string strFile;
41 vector<DbTxn*> vTxn;
42 bool fReadOnly;
43
44 explicit CDB(const char* pszFile, const char* pszMode="r+");
45 ~CDB() { Close(); }
46public:
47 void Close();
48private:
49 CDB(const CDB&);
50 void operator=(const CDB&);
51
52protected:
53 template<typename K, typename T>
54 bool Read(const K& key, T& value)
55 {
56 if (!pdb)
57 return false;
58
59 // Key
60 CDataStream ssKey(SER_DISK);
61 ssKey.reserve(1000);
62 ssKey << key;
63 Dbt datKey(&ssKey[0], ssKey.size());
64
65 // Read
66 Dbt datValue;
67 datValue.set_flags(DB_DBT_MALLOC);
68 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
69 memset(datKey.get_data(), 0, datKey.get_size());
70 if (datValue.get_data() == NULL)
71 return false;
72
73 // Unserialize value
74 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
75 ssValue >> value;
76
77 // Clear and free memory
78 memset(datValue.get_data(), 0, datValue.get_size());
79 free(datValue.get_data());
80 return (ret == 0);
81 }
82
83 template<typename K, typename T>
84 bool Write(const K& key, const T& value, bool fOverwrite=true)
85 {
86 if (!pdb)
87 return false;
88 if (fReadOnly)
89 assert(("Write called on database in read-only mode", false));
90
91 // Key
92 CDataStream ssKey(SER_DISK);
93 ssKey.reserve(1000);
94 ssKey << key;
95 Dbt datKey(&ssKey[0], ssKey.size());
96
97 // Value
98 CDataStream ssValue(SER_DISK);
99 ssValue.reserve(10000);
100 ssValue << value;
101 Dbt datValue(&ssValue[0], ssValue.size());
102
103 // Write
104 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
105
106 // Clear memory in case it was a private key
107 memset(datKey.get_data(), 0, datKey.get_size());
108 memset(datValue.get_data(), 0, datValue.get_size());
109 return (ret == 0);
110 }
111
112 template<typename K>
113 bool Erase(const K& key)
114 {
115 if (!pdb)
116 return false;
117 if (fReadOnly)
118 assert(("Erase called on database in read-only mode", false));
119
120 // Key
121 CDataStream ssKey(SER_DISK);
122 ssKey.reserve(1000);
123 ssKey << key;
124 Dbt datKey(&ssKey[0], ssKey.size());
125
126 // Erase
127 int ret = pdb->del(GetTxn(), &datKey, 0);
128
129 // Clear memory
130 memset(datKey.get_data(), 0, datKey.get_size());
131 return (ret == 0 || ret == DB_NOTFOUND);
132 }
133
134 template<typename K>
135 bool Exists(const K& key)
136 {
137 if (!pdb)
138 return false;
139
140 // Key
141 CDataStream ssKey(SER_DISK);
142 ssKey.reserve(1000);
143 ssKey << key;
144 Dbt datKey(&ssKey[0], ssKey.size());
145
146 // Exists
147 int ret = pdb->exists(GetTxn(), &datKey, 0);
148
149 // Clear memory
150 memset(datKey.get_data(), 0, datKey.get_size());
151 return (ret == 0);
152 }
153
154 Dbc* GetCursor()
155 {
156 if (!pdb)
157 return NULL;
158 Dbc* pcursor = NULL;
159 int ret = pdb->cursor(NULL, &pcursor, 0);
160 if (ret != 0)
161 return NULL;
162 return pcursor;
163 }
164
165 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
166 {
167 // Read at cursor
168 Dbt datKey;
169 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
170 {
171 datKey.set_data(&ssKey[0]);
172 datKey.set_size(ssKey.size());
173 }
174 Dbt datValue;
175 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
176 {
177 datValue.set_data(&ssValue[0]);
178 datValue.set_size(ssValue.size());
179 }
180 datKey.set_flags(DB_DBT_MALLOC);
181 datValue.set_flags(DB_DBT_MALLOC);
182 int ret = pcursor->get(&datKey, &datValue, fFlags);
183 if (ret != 0)
184 return ret;
185 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
186 return 99999;
187
188 // Convert to streams
189 ssKey.SetType(SER_DISK);
190 ssKey.clear();
191 ssKey.write((char*)datKey.get_data(), datKey.get_size());
192 ssValue.SetType(SER_DISK);
193 ssValue.clear();
194 ssValue.write((char*)datValue.get_data(), datValue.get_size());
195
196 // Clear and free memory
197 memset(datKey.get_data(), 0, datKey.get_size());
198 memset(datValue.get_data(), 0, datValue.get_size());
199 free(datKey.get_data());
200 free(datValue.get_data());
201 return 0;
202 }
203
204 DbTxn* GetTxn()
205 {
206 if (!vTxn.empty())
207 return vTxn.back();
208 else
209 return NULL;
210 }
211
212public:
213 bool TxnBegin()
214 {
215 if (!pdb)
216 return false;
217 DbTxn* ptxn = NULL;
218 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
219 if (!ptxn || ret != 0)
220 return false;
221 vTxn.push_back(ptxn);
222 return true;
223 }
224
225 bool TxnCommit()
226 {
227 if (!pdb)
228 return false;
229 if (vTxn.empty())
230 return false;
231 int ret = vTxn.back()->commit(0);
232 vTxn.pop_back();
233 return (ret == 0);
234 }
235
236 bool TxnAbort()
237 {
238 if (!pdb)
239 return false;
240 if (vTxn.empty())
241 return false;
242 int ret = vTxn.back()->abort();
243 vTxn.pop_back();
244 return (ret == 0);
245 }
246
247 bool ReadVersion(int& nVersion)
248 {
249 nVersion = 0;
250 return Read(string("version"), nVersion);
251 }
252
253 bool WriteVersion(int nVersion)
254 {
255 return Write(string("version"), nVersion);
256 }
257};
258
259
260
261
262
263
264
265
266class CTxDB : public CDB
267{
268public:
f03304a9 269 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
0a61b0df 270private:
271 CTxDB(const CTxDB&);
272 void operator=(const CTxDB&);
273public:
274 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
275 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
276 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
277 bool EraseTxIndex(const CTransaction& tx);
278 bool ContainsTx(uint256 hash);
279 bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
280 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
281 bool ReadDiskTx(uint256 hash, CTransaction& tx);
282 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
283 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
284 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
285 bool EraseBlockIndex(uint256 hash);
286 bool ReadHashBestChain(uint256& hashBestChain);
287 bool WriteHashBestChain(uint256 hashBestChain);
288 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
289 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
290 bool LoadBlockIndex();
291};
292
293
294
295
296
297class CAddrDB : public CDB
298{
299public:
300 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
301private:
302 CAddrDB(const CAddrDB&);
303 void operator=(const CAddrDB&);
304public:
305 bool WriteAddress(const CAddress& addr);
c891967b 306 bool EraseAddress(const CAddress& addr);
0a61b0df 307 bool LoadAddresses();
308};
309
310bool LoadAddresses();
311
312
313
314
315
316
10384941 317class CKeyPool
318{
319public:
320 int64 nTime;
321 vector<unsigned char> vchPubKey;
322
323 CKeyPool()
324 {
325 nTime = GetTime();
326 }
327
328 CKeyPool(const vector<unsigned char>& vchPubKeyIn)
329 {
330 nTime = GetTime();
331 vchPubKey = vchPubKeyIn;
332 }
333
334 IMPLEMENT_SERIALIZE
335 (
336 if (!(nType & SER_GETHASH))
337 READWRITE(nVersion);
338 READWRITE(nTime);
339 READWRITE(vchPubKey);
340 )
341};
342
343
344
345
0a61b0df 346class CWalletDB : public CDB
347{
348public:
e4ff4e68 349 CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode)
350 {
351 }
0a61b0df 352private:
353 CWalletDB(const CWalletDB&);
354 void operator=(const CWalletDB&);
355public:
356 bool ReadName(const string& strAddress, string& strName)
357 {
358 strName = "";
359 return Read(make_pair(string("name"), strAddress), strName);
360 }
361
362 bool WriteName(const string& strAddress, const string& strName)
363 {
364 CRITICAL_BLOCK(cs_mapAddressBook)
365 mapAddressBook[strAddress] = strName;
366 nWalletDBUpdated++;
367 return Write(make_pair(string("name"), strAddress), strName);
368 }
369
370 bool EraseName(const string& strAddress)
371 {
372 // This should only be used for sending addresses, never for receiving addresses,
373 // receiving addresses must always have an address book entry if they're not change return.
374 CRITICAL_BLOCK(cs_mapAddressBook)
375 mapAddressBook.erase(strAddress);
376 nWalletDBUpdated++;
377 return Erase(make_pair(string("name"), strAddress));
378 }
379
380 bool ReadTx(uint256 hash, CWalletTx& wtx)
381 {
382 return Read(make_pair(string("tx"), hash), wtx);
383 }
384
385 bool WriteTx(uint256 hash, const CWalletTx& wtx)
386 {
387 nWalletDBUpdated++;
388 return Write(make_pair(string("tx"), hash), wtx);
389 }
390
391 bool EraseTx(uint256 hash)
392 {
393 nWalletDBUpdated++;
394 return Erase(make_pair(string("tx"), hash));
395 }
396
397 bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
398 {
399 vchPrivKey.clear();
400 return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
401 }
402
403 bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
404 {
405 nWalletDBUpdated++;
406 return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
407 }
408
6a76c60e
PW
409 bool WriteBestBlock(const CBlockLocator& locator)
410 {
411 nWalletDBUpdated++;
412 return Write(string("bestblock"), locator);
413 }
414
415 bool ReadBestBlock(CBlockLocator& locator)
416 {
417 return Read(string("bestblock"), locator);
418 }
419
0a61b0df 420 bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
421 {
422 vchPubKey.clear();
423 return Read(string("defaultkey"), vchPubKey);
424 }
425
426 bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
427 {
428 vchDefaultKey = vchPubKey;
429 nWalletDBUpdated++;
430 return Write(string("defaultkey"), vchPubKey);
431 }
432
433 template<typename T>
434 bool ReadSetting(const string& strKey, T& value)
435 {
436 return Read(make_pair(string("setting"), strKey), value);
437 }
438
439 template<typename T>
440 bool WriteSetting(const string& strKey, const T& value)
441 {
442 nWalletDBUpdated++;
443 return Write(make_pair(string("setting"), strKey), value);
444 }
445
e4ff4e68 446 bool ReadAccount(const string& strAccount, CAccount& account);
447 bool WriteAccount(const string& strAccount, const CAccount& account);
809ee795 448 bool WriteAccountingEntry(const CAccountingEntry& acentry);
e4ff4e68 449 int64 GetAccountCreditDebit(const string& strAccount);
bfd471f5 450 void ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& acentries);
e4ff4e68 451
0a61b0df 452 bool LoadWallet();
10384941 453protected:
454 void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
455 void KeepKey(int64 nIndex);
456 static void ReturnKey(int64 nIndex);
457 friend class CReserveKey;
776d0f34 458 friend vector<unsigned char> GetKeyFromKeyPool();
459 friend int64 GetOldestKeyPoolTime();
0a61b0df 460};
461
462bool LoadWallet(bool& fFirstRunRet);
d743f035 463void BackupWallet(const string& strDest);
0a61b0df 464
465inline bool SetAddressBookName(const string& strAddress, const string& strName)
466{
467 return CWalletDB().WriteName(strAddress, strName);
468}
10384941 469
470class CReserveKey
471{
472protected:
473 int64 nIndex;
474 vector<unsigned char> vchPubKey;
475public:
476 CReserveKey()
477 {
478 nIndex = -1;
479 }
480
481 ~CReserveKey()
482 {
5cbf7532 483 if (!fShutdown)
484 ReturnKey();
10384941 485 }
486
487 vector<unsigned char> GetReservedKey()
488 {
489 if (nIndex == -1)
490 {
491 CKeyPool keypool;
492 CWalletDB().ReserveKeyFromKeyPool(nIndex, keypool);
493 vchPubKey = keypool.vchPubKey;
494 }
495 assert(!vchPubKey.empty());
496 return vchPubKey;
497 }
498
499 void KeepKey()
500 {
501 if (nIndex != -1)
502 CWalletDB().KeepKey(nIndex);
503 nIndex = -1;
504 vchPubKey.clear();
505 }
506
507 void ReturnKey()
508 {
509 if (nIndex != -1)
510 CWalletDB::ReturnKey(nIndex);
511 nIndex = -1;
512 vchPubKey.clear();
513 }
514};
This page took 0.090411 seconds and 4 git commands to generate.