1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
19 class CAccountingEntry;
23 class CDiskBlockIndex;
31 extern unsigned int nWalletDBUpdated;
34 extern void DBFlush(bool fShutdown);
35 void ThreadFlushWalletDB(void* parg);
36 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
39 /** RAII class that provides access to a Berkeley database */
45 std::vector<DbTxn*> vTxn;
48 explicit CDB(const char* pszFile, const char* pszMode="r+");
54 void operator=(const CDB&);
57 template<typename K, typename T>
58 bool Read(const K& key, T& value)
64 CDataStream ssKey(SER_DISK);
67 Dbt datKey(&ssKey[0], ssKey.size());
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)
78 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
81 // Clear and free memory
82 memset(datValue.get_data(), 0, datValue.get_size());
83 free(datValue.get_data());
87 template<typename K, typename T>
88 bool Write(const K& key, const T& value, bool fOverwrite=true)
93 assert(!"Write called on database in read-only mode");
96 CDataStream ssKey(SER_DISK);
99 Dbt datKey(&ssKey[0], ssKey.size());
102 CDataStream ssValue(SER_DISK);
103 ssValue.reserve(10000);
105 Dbt datValue(&ssValue[0], ssValue.size());
108 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
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());
117 bool Erase(const K& key)
122 assert(!"Erase called on database in read-only mode");
125 CDataStream ssKey(SER_DISK);
128 Dbt datKey(&ssKey[0], ssKey.size());
131 int ret = pdb->del(GetTxn(), &datKey, 0);
134 memset(datKey.get_data(), 0, datKey.get_size());
135 return (ret == 0 || ret == DB_NOTFOUND);
139 bool Exists(const K& key)
145 CDataStream ssKey(SER_DISK);
148 Dbt datKey(&ssKey[0], ssKey.size());
151 int ret = pdb->exists(GetTxn(), &datKey, 0);
154 memset(datKey.get_data(), 0, datKey.get_size());
163 int ret = pdb->cursor(NULL, &pcursor, 0);
169 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
173 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
175 datKey.set_data(&ssKey[0]);
176 datKey.set_size(ssKey.size());
179 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
181 datValue.set_data(&ssValue[0]);
182 datValue.set_size(ssValue.size());
184 datKey.set_flags(DB_DBT_MALLOC);
185 datValue.set_flags(DB_DBT_MALLOC);
186 int ret = pcursor->get(&datKey, &datValue, fFlags);
189 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
192 // Convert to streams
193 ssKey.SetType(SER_DISK);
195 ssKey.write((char*)datKey.get_data(), datKey.get_size());
196 ssValue.SetType(SER_DISK);
198 ssValue.write((char*)datValue.get_data(), datValue.get_size());
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());
222 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
223 if (!ptxn || ret != 0)
225 vTxn.push_back(ptxn);
235 int ret = vTxn.back()->commit(0);
246 int ret = vTxn.back()->abort();
251 bool ReadVersion(int& nVersion)
254 return Read(std::string("version"), nVersion);
257 bool WriteVersion(int nVersion)
259 return Write(std::string("version"), nVersion);
262 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
271 /** Access to the transaction database (blkindex.dat) */
272 class CTxDB : public CDB
275 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
278 void operator=(const CTxDB&);
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);
285 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
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();
302 /** Access to the (IP) address database (addr.dat) */
303 class CAddrDB : public CDB
306 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
308 CAddrDB(const CAddrDB&);
309 void operator=(const CAddrDB&);
311 bool WriteAddrman(const CAddrMan& addr);
312 bool LoadAddresses();
315 bool LoadAddresses();
319 /** Error statuses for the wallet database */
329 /** Access to the wallet database (wallet.dat) */
330 class CWalletDB : public CDB
333 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
337 CWalletDB(const CWalletDB&);
338 void operator=(const CWalletDB&);
340 bool ReadName(const std::string& strAddress, std::string& strName)
343 return Read(std::make_pair(std::string("name"), strAddress), strName);
346 bool WriteName(const std::string& strAddress, const std::string& strName);
348 bool EraseName(const std::string& strAddress);
350 bool ReadTx(uint256 hash, CWalletTx& wtx)
352 return Read(std::make_pair(std::string("tx"), hash), wtx);
355 bool WriteTx(uint256 hash, const CWalletTx& wtx)
358 return Write(std::make_pair(std::string("tx"), hash), wtx);
361 bool EraseTx(uint256 hash)
364 return Erase(std::make_pair(std::string("tx"), hash));
367 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
370 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
373 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
376 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
379 bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
382 if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
384 if (fEraseUnencryptedKey)
386 Erase(std::make_pair(std::string("key"), vchPubKey));
387 Erase(std::make_pair(std::string("wkey"), vchPubKey));
392 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
395 return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
398 // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
399 bool ReadCScript(const uint160 &hash, CScript& redeemScript)
401 redeemScript.clear();
402 return Read(std::make_pair(std::string("cscript"), hash), redeemScript);
405 bool WriteCScript(const uint160& hash, const CScript& redeemScript)
408 return Write(std::make_pair(std::string("cscript"), hash), redeemScript, false);
411 bool WriteBestBlock(const CBlockLocator& locator)
414 return Write(std::string("bestblock"), locator);
417 bool ReadBestBlock(CBlockLocator& locator)
419 return Read(std::string("bestblock"), locator);
422 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
425 return Read(std::string("defaultkey"), vchPubKey);
428 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
431 return Write(std::string("defaultkey"), vchPubKey);
434 bool ReadPool(int64 nPool, CKeyPool& keypool)
436 return Read(std::make_pair(std::string("pool"), nPool), keypool);
439 bool WritePool(int64 nPool, const CKeyPool& keypool)
442 return Write(std::make_pair(std::string("pool"), nPool), keypool);
445 bool ErasePool(int64 nPool)
448 return Erase(std::make_pair(std::string("pool"), nPool));
451 // Settings are no longer stored in wallet.dat; these are
452 // used only for backwards compatibility:
454 bool ReadSetting(const std::string& strKey, T& value)
456 return Read(std::make_pair(std::string("setting"), strKey), value);
459 bool WriteSetting(const std::string& strKey, const T& value)
462 return Write(std::make_pair(std::string("setting"), strKey), value);
464 bool EraseSetting(const std::string& strKey)
467 return Erase(std::make_pair(std::string("setting"), strKey));
470 bool WriteMinVersion(int nVersion)
472 return Write(std::string("minversion"), nVersion);
475 bool ReadAccount(const std::string& strAccount, CAccount& account);
476 bool WriteAccount(const std::string& strAccount, const CAccount& account);
477 bool WriteAccountingEntry(const CAccountingEntry& acentry);
478 int64 GetAccountCreditDebit(const std::string& strAccount);
479 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
481 int LoadWallet(CWallet* pwallet);