]> Git Repo - VerusCoin.git/blame - src/db.h
Remove headers.h
[VerusCoin.git] / src / db.h
CommitLineData
0a61b0df 1// Copyright (c) 2009-2010 Satoshi Nakamoto
88216419 2// Copyright (c) 2009-2012 The Bitcoin developers
0a61b0df 3// Distributed under the MIT/X11 software license, see the accompanying
4// file license.txt or http://www.opensource.org/licenses/mit-license.php.
223b6f1b
WL
5#ifndef BITCOIN_DB_H
6#define BITCOIN_DB_H
7
8#include "key.h"
ed6d0b5f
PW
9#include "main.h"
10#include "wallet.h"
223b6f1b
WL
11
12#include <map>
13#include <string>
14#include <vector>
15
16#include <db_cxx.h>
0a61b0df 17
2a45a494
GA
18class CAccount;
19class CAccountingEntry;
20class CAddress;
5fee401f 21class CAddrMan;
2a45a494 22class CBlockLocator;
0a61b0df 23class CDiskBlockIndex;
24class CDiskTxPos;
2a45a494 25class CMasterKey;
0a61b0df 26class COutPoint;
2a45a494 27class CTxIndex;
64c7ee7e 28class CWallet;
2a45a494 29class CWalletTx;
0a61b0df 30
31extern unsigned int nWalletDBUpdated;
32extern DbEnv dbenv;
33
1c15f886 34extern void DBFlush(bool fShutdown);
64c7ee7e
PW
35void ThreadFlushWalletDB(void* parg);
36bool BackupWallet(const CWallet& wallet, const std::string& strDest);
0a61b0df 37
38
6b8de05d 39/** RAII class that provides access to a Berkeley database */
0a61b0df 40class CDB
41{
42protected:
43 Db* pdb;
223b6f1b
WL
44 std::string strFile;
45 std::vector<DbTxn*> vTxn;
0a61b0df 46 bool fReadOnly;
47
48 explicit CDB(const char* pszFile, const char* pszMode="r+");
49 ~CDB() { Close(); }
50public:
51 void Close();
52private:
53 CDB(const CDB&);
54 void operator=(const CDB&);
55
56protected:
57 template<typename K, typename T>
58 bool Read(const K& key, T& value)
59 {
60 if (!pdb)
61 return false;
62
63 // Key
64 CDataStream ssKey(SER_DISK);
65 ssKey.reserve(1000);
66 ssKey << key;
67 Dbt datKey(&ssKey[0], ssKey.size());
68
69 // Read
70 Dbt datValue;
71 datValue.set_flags(DB_DBT_MALLOC);
72 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
73 memset(datKey.get_data(), 0, datKey.get_size());
74 if (datValue.get_data() == NULL)
75 return false;
76
77 // Unserialize value
78 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
79 ssValue >> value;
80
81 // Clear and free memory
82 memset(datValue.get_data(), 0, datValue.get_size());
83 free(datValue.get_data());
84 return (ret == 0);
85 }
86
87 template<typename K, typename T>
88 bool Write(const K& key, const T& value, bool fOverwrite=true)
89 {
90 if (!pdb)
91 return false;
92 if (fReadOnly)
ecf1c79a 93 assert(!"Write called on database in read-only mode");
0a61b0df 94
95 // Key
96 CDataStream ssKey(SER_DISK);
97 ssKey.reserve(1000);
98 ssKey << key;
99 Dbt datKey(&ssKey[0], ssKey.size());
100
101 // Value
102 CDataStream ssValue(SER_DISK);
103 ssValue.reserve(10000);
104 ssValue << value;
105 Dbt datValue(&ssValue[0], ssValue.size());
106
107 // Write
108 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
109
110 // Clear memory in case it was a private key
111 memset(datKey.get_data(), 0, datKey.get_size());
112 memset(datValue.get_data(), 0, datValue.get_size());
113 return (ret == 0);
114 }
115
116 template<typename K>
117 bool Erase(const K& key)
118 {
119 if (!pdb)
120 return false;
121 if (fReadOnly)
ecf1c79a 122 assert(!"Erase called on database in read-only mode");
0a61b0df 123
124 // Key
125 CDataStream ssKey(SER_DISK);
126 ssKey.reserve(1000);
127 ssKey << key;
128 Dbt datKey(&ssKey[0], ssKey.size());
129
130 // Erase
131 int ret = pdb->del(GetTxn(), &datKey, 0);
132
133 // Clear memory
134 memset(datKey.get_data(), 0, datKey.get_size());
135 return (ret == 0 || ret == DB_NOTFOUND);
136 }
137
138 template<typename K>
139 bool Exists(const K& key)
140 {
141 if (!pdb)
142 return false;
143
144 // Key
145 CDataStream ssKey(SER_DISK);
146 ssKey.reserve(1000);
147 ssKey << key;
148 Dbt datKey(&ssKey[0], ssKey.size());
149
150 // Exists
151 int ret = pdb->exists(GetTxn(), &datKey, 0);
152
153 // Clear memory
154 memset(datKey.get_data(), 0, datKey.get_size());
155 return (ret == 0);
156 }
157
158 Dbc* GetCursor()
159 {
160 if (!pdb)
161 return NULL;
162 Dbc* pcursor = NULL;
163 int ret = pdb->cursor(NULL, &pcursor, 0);
164 if (ret != 0)
165 return NULL;
166 return pcursor;
167 }
168
169 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
170 {
171 // Read at cursor
172 Dbt datKey;
173 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
174 {
175 datKey.set_data(&ssKey[0]);
176 datKey.set_size(ssKey.size());
177 }
178 Dbt datValue;
179 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
180 {
181 datValue.set_data(&ssValue[0]);
182 datValue.set_size(ssValue.size());
183 }
184 datKey.set_flags(DB_DBT_MALLOC);
185 datValue.set_flags(DB_DBT_MALLOC);
186 int ret = pcursor->get(&datKey, &datValue, fFlags);
187 if (ret != 0)
188 return ret;
189 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
190 return 99999;
191
192 // Convert to streams
193 ssKey.SetType(SER_DISK);
194 ssKey.clear();
195 ssKey.write((char*)datKey.get_data(), datKey.get_size());
196 ssValue.SetType(SER_DISK);
197 ssValue.clear();
198 ssValue.write((char*)datValue.get_data(), datValue.get_size());
199
200 // Clear and free memory
201 memset(datKey.get_data(), 0, datKey.get_size());
202 memset(datValue.get_data(), 0, datValue.get_size());
203 free(datKey.get_data());
204 free(datValue.get_data());
205 return 0;
206 }
207
208 DbTxn* GetTxn()
209 {
210 if (!vTxn.empty())
211 return vTxn.back();
212 else
213 return NULL;
214 }
215
216public:
217 bool TxnBegin()
218 {
219 if (!pdb)
220 return false;
221 DbTxn* ptxn = NULL;
222 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
223 if (!ptxn || ret != 0)
224 return false;
225 vTxn.push_back(ptxn);
226 return true;
227 }
228
229 bool TxnCommit()
230 {
231 if (!pdb)
232 return false;
233 if (vTxn.empty())
234 return false;
235 int ret = vTxn.back()->commit(0);
236 vTxn.pop_back();
237 return (ret == 0);
238 }
239
240 bool TxnAbort()
241 {
242 if (!pdb)
243 return false;
244 if (vTxn.empty())
245 return false;
246 int ret = vTxn.back()->abort();
247 vTxn.pop_back();
248 return (ret == 0);
249 }
250
251 bool ReadVersion(int& nVersion)
252 {
253 nVersion = 0;
223b6f1b 254 return Read(std::string("version"), nVersion);
0a61b0df 255 }
256
257 bool WriteVersion(int nVersion)
258 {
223b6f1b 259 return Write(std::string("version"), nVersion);
0a61b0df 260 }
9e9869d0 261
d764d916 262 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
0a61b0df 263};
264
265
266
267
268
269
270
6b8de05d 271/** Access to the transaction database (blkindex.dat) */
0a61b0df 272class CTxDB : public CDB
273{
274public:
f03304a9 275 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
0a61b0df 276private:
277 CTxDB(const CTxDB&);
278 void operator=(const CTxDB&);
279public:
280 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
281 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
282 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
283 bool EraseTxIndex(const CTransaction& tx);
284 bool ContainsTx(uint256 hash);
223b6f1b 285 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
0a61b0df 286 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
287 bool ReadDiskTx(uint256 hash, CTransaction& tx);
288 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
289 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
290 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
291 bool EraseBlockIndex(uint256 hash);
292 bool ReadHashBestChain(uint256& hashBestChain);
293 bool WriteHashBestChain(uint256 hashBestChain);
294 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
295 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
296 bool LoadBlockIndex();
297};
298
299
300
301
6b8de05d 302/** Access to the (IP) address database (addr.dat) */
0a61b0df 303class CAddrDB : public CDB
304{
305public:
306 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
307private:
308 CAddrDB(const CAddrDB&);
309 void operator=(const CAddrDB&);
310public:
5fee401f 311 bool WriteAddrman(const CAddrMan& addr);
53cb1a49 312 bool LoadAddresses();
0a61b0df 313};
314
315bool LoadAddresses();
316
317
10384941 318
6b8de05d 319/** Error statuses for the wallet database */
7ec55267
MC
320enum DBErrors
321{
322 DB_LOAD_OK,
323 DB_CORRUPT,
116df55e
JG
324 DB_TOO_NEW,
325 DB_LOAD_FAIL,
d764d916 326 DB_NEED_REWRITE
7ec55267
MC
327};
328
6b8de05d 329/** Access to the wallet database (wallet.dat) */
0a61b0df 330class CWalletDB : public CDB
331{
332public:
64c7ee7e 333 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
e4ff4e68 334 {
335 }
0a61b0df 336private:
337 CWalletDB(const CWalletDB&);
338 void operator=(const CWalletDB&);
339public:
223b6f1b 340 bool ReadName(const std::string& strAddress, std::string& strName)
0a61b0df 341 {
342 strName = "";
223b6f1b 343 return Read(std::make_pair(std::string("name"), strAddress), strName);
0a61b0df 344 }
345
64c7ee7e 346 bool WriteName(const std::string& strAddress, const std::string& strName);
0a61b0df 347
64c7ee7e 348 bool EraseName(const std::string& strAddress);
0a61b0df 349
350 bool ReadTx(uint256 hash, CWalletTx& wtx)
351 {
223b6f1b 352 return Read(std::make_pair(std::string("tx"), hash), wtx);
0a61b0df 353 }
354
355 bool WriteTx(uint256 hash, const CWalletTx& wtx)
356 {
357 nWalletDBUpdated++;
223b6f1b 358 return Write(std::make_pair(std::string("tx"), hash), wtx);
0a61b0df 359 }
360
361 bool EraseTx(uint256 hash)
362 {
363 nWalletDBUpdated++;
223b6f1b 364 return Erase(std::make_pair(std::string("tx"), hash));
0a61b0df 365 }
366
223b6f1b 367 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
0a61b0df 368 {
369 vchPrivKey.clear();
223b6f1b 370 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
0a61b0df 371 }
372
223b6f1b 373 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
0a61b0df 374 {
375 nWalletDBUpdated++;
223b6f1b 376 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
0a61b0df 377 }
378
4e87d341
MC
379 bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
380 {
381 nWalletDBUpdated++;
382 if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
383 return false;
384 if (fEraseUnencryptedKey)
385 {
386 Erase(std::make_pair(std::string("key"), vchPubKey));
387 Erase(std::make_pair(std::string("wkey"), vchPubKey));
388 }
389 return true;
390 }
391
392 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
393 {
394 nWalletDBUpdated++;
395 return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
396 }
397
2a45a494
GA
398 // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
399 bool ReadCScript(const uint160 &hash, CScript& redeemScript)
e679ec96 400 {
2a45a494
GA
401 redeemScript.clear();
402 return Read(std::make_pair(std::string("cscript"), hash), redeemScript);
e679ec96
GA
403 }
404
2a45a494 405 bool WriteCScript(const uint160& hash, const CScript& redeemScript)
e679ec96
GA
406 {
407 nWalletDBUpdated++;
2a45a494 408 return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false);
e679ec96
GA
409 }
410
6a76c60e
PW
411 bool WriteBestBlock(const CBlockLocator& locator)
412 {
413 nWalletDBUpdated++;
223b6f1b 414 return Write(std::string("bestblock"), locator);
6a76c60e
PW
415 }
416
417 bool ReadBestBlock(CBlockLocator& locator)
418 {
223b6f1b 419 return Read(std::string("bestblock"), locator);
6a76c60e
PW
420 }
421
223b6f1b 422 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
0a61b0df 423 {
424 vchPubKey.clear();
223b6f1b 425 return Read(std::string("defaultkey"), vchPubKey);
0a61b0df 426 }
427
223b6f1b 428 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
0a61b0df 429 {
0a61b0df 430 nWalletDBUpdated++;
223b6f1b 431 return Write(std::string("defaultkey"), vchPubKey);
0a61b0df 432 }
433
bde280b9 434 bool ReadPool(int64 nPool, CKeyPool& keypool)
64c7ee7e
PW
435 {
436 return Read(std::make_pair(std::string("pool"), nPool), keypool);
437 }
438
bde280b9 439 bool WritePool(int64 nPool, const CKeyPool& keypool)
64c7ee7e
PW
440 {
441 nWalletDBUpdated++;
442 return Write(std::make_pair(std::string("pool"), nPool), keypool);
443 }
444
bde280b9 445 bool ErasePool(int64 nPool)
64c7ee7e
PW
446 {
447 nWalletDBUpdated++;
448 return Erase(std::make_pair(std::string("pool"), nPool));
449 }
450
972060ce
GA
451 // Settings are no longer stored in wallet.dat; these are
452 // used only for backwards compatibility:
0a61b0df 453 template<typename T>
223b6f1b 454 bool ReadSetting(const std::string& strKey, T& value)
0a61b0df 455 {
223b6f1b 456 return Read(std::make_pair(std::string("setting"), strKey), value);
0a61b0df 457 }
0a61b0df 458 template<typename T>
223b6f1b 459 bool WriteSetting(const std::string& strKey, const T& value)
0a61b0df 460 {
461 nWalletDBUpdated++;
223b6f1b 462 return Write(std::make_pair(std::string("setting"), strKey), value);
0a61b0df 463 }
972060ce
GA
464 bool EraseSetting(const std::string& strKey)
465 {
466 nWalletDBUpdated++;
467 return Erase(std::make_pair(std::string("setting"), strKey));
468 }
0a61b0df 469
0b807a41
PW
470 bool WriteMinVersion(int nVersion)
471 {
472 return Write(std::string("minversion"), nVersion);
473 }
474
223b6f1b
WL
475 bool ReadAccount(const std::string& strAccount, CAccount& account);
476 bool WriteAccount(const std::string& strAccount, const CAccount& account);
809ee795 477 bool WriteAccountingEntry(const CAccountingEntry& acentry);
bde280b9 478 int64 GetAccountCreditDebit(const std::string& strAccount);
223b6f1b 479 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
e4ff4e68 480
7ec55267 481 int LoadWallet(CWallet* pwallet);
10384941 482};
223b6f1b
WL
483
484#endif
This page took 0.11315 seconds and 4 git commands to generate.