1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2011 The Bitcoin developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
17 class CDiskBlockIndex;
24 class CAccountingEntry;
28 extern unsigned int nWalletDBUpdated;
31 extern void DBFlush(bool fShutdown);
32 void ThreadFlushWalletDB(void* parg);
33 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
42 std::vector<DbTxn*> vTxn;
45 explicit CDB(const char* pszFile, const char* pszMode="r+");
51 void operator=(const CDB&);
54 template<typename K, typename T>
55 bool Read(const K& key, T& value)
61 CDataStream ssKey(SER_DISK);
64 Dbt datKey(&ssKey[0], ssKey.size());
68 datValue.set_flags(DB_DBT_MALLOC);
69 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
70 memset(datKey.get_data(), 0, datKey.get_size());
71 if (datValue.get_data() == NULL)
76 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
79 catch (std::exception &e) {
83 // Clear and free memory
84 memset(datValue.get_data(), 0, datValue.get_size());
85 free(datValue.get_data());
89 template<typename K, typename T>
90 bool Write(const K& key, const T& value, bool fOverwrite=true)
95 assert(!"Write called on database in read-only mode");
98 CDataStream ssKey(SER_DISK);
101 Dbt datKey(&ssKey[0], ssKey.size());
104 CDataStream ssValue(SER_DISK);
105 ssValue.reserve(10000);
107 Dbt datValue(&ssValue[0], ssValue.size());
110 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
112 // Clear memory in case it was a private key
113 memset(datKey.get_data(), 0, datKey.get_size());
114 memset(datValue.get_data(), 0, datValue.get_size());
119 bool Erase(const K& key)
124 assert(!"Erase called on database in read-only mode");
127 CDataStream ssKey(SER_DISK);
130 Dbt datKey(&ssKey[0], ssKey.size());
133 int ret = pdb->del(GetTxn(), &datKey, 0);
136 memset(datKey.get_data(), 0, datKey.get_size());
137 return (ret == 0 || ret == DB_NOTFOUND);
141 bool Exists(const K& key)
147 CDataStream ssKey(SER_DISK);
150 Dbt datKey(&ssKey[0], ssKey.size());
153 int ret = pdb->exists(GetTxn(), &datKey, 0);
156 memset(datKey.get_data(), 0, datKey.get_size());
165 int ret = pdb->cursor(NULL, &pcursor, 0);
171 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
175 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
177 datKey.set_data(&ssKey[0]);
178 datKey.set_size(ssKey.size());
181 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
183 datValue.set_data(&ssValue[0]);
184 datValue.set_size(ssValue.size());
186 datKey.set_flags(DB_DBT_MALLOC);
187 datValue.set_flags(DB_DBT_MALLOC);
188 int ret = pcursor->get(&datKey, &datValue, fFlags);
191 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
194 // Convert to streams
195 ssKey.SetType(SER_DISK);
197 ssKey.write((char*)datKey.get_data(), datKey.get_size());
198 ssValue.SetType(SER_DISK);
200 ssValue.write((char*)datValue.get_data(), datValue.get_size());
202 // Clear and free memory
203 memset(datKey.get_data(), 0, datKey.get_size());
204 memset(datValue.get_data(), 0, datValue.get_size());
205 free(datKey.get_data());
206 free(datValue.get_data());
224 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
225 if (!ptxn || ret != 0)
227 vTxn.push_back(ptxn);
237 int ret = vTxn.back()->commit(0);
248 int ret = vTxn.back()->abort();
253 bool ReadVersion(int& nVersion)
256 return Read(std::string("version"), nVersion);
259 bool WriteVersion(int nVersion)
261 return Write(std::string("version"), nVersion);
264 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
274 class CTxDB : public CDB
277 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
280 void operator=(const CTxDB&);
282 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
283 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
284 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
285 bool EraseTxIndex(const CTransaction& tx);
286 bool ContainsTx(uint256 hash);
287 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
288 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
289 bool ReadDiskTx(uint256 hash, CTransaction& tx);
290 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
291 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
292 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
293 bool EraseBlockIndex(uint256 hash);
294 bool ReadHashBestChain(uint256& hashBestChain);
295 bool WriteHashBestChain(uint256 hashBestChain);
296 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
297 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
298 bool LoadBlockIndex();
305 class CAddrDB : public CDB
308 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
310 CAddrDB(const CAddrDB&);
311 void operator=(const CAddrDB&);
313 bool WriteAddress(const CAddress& addr);
314 bool EraseAddress(const CAddress& addr);
315 bool LoadAddresses();
318 bool LoadAddresses();
326 std::vector<unsigned char> vchPubKey;
333 CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
336 vchPubKey = vchPubKeyIn;
341 if (!(nType & SER_GETHASH))
344 READWRITE(vchPubKey);
360 class CWalletDB : public CDB
363 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
367 CWalletDB(const CWalletDB&);
368 void operator=(const CWalletDB&);
370 bool ReadName(const std::string& strAddress, std::string& strName)
373 return Read(std::make_pair(std::string("name"), strAddress), strName);
376 bool WriteName(const std::string& strAddress, const std::string& strName);
378 bool EraseName(const std::string& strAddress);
380 bool ReadTx(uint256 hash, CWalletTx& wtx)
382 return Read(std::make_pair(std::string("tx"), hash), wtx);
385 bool WriteTx(uint256 hash, const CWalletTx& wtx)
388 return Write(std::make_pair(std::string("tx"), hash), wtx);
391 bool EraseTx(uint256 hash)
394 return Erase(std::make_pair(std::string("tx"), hash));
397 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
400 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
403 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
406 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
409 bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
412 if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
414 if (fEraseUnencryptedKey)
416 Erase(std::make_pair(std::string("key"), vchPubKey));
417 Erase(std::make_pair(std::string("wkey"), vchPubKey));
422 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
425 return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
428 bool WriteBestBlock(const CBlockLocator& locator)
431 return Write(std::string("bestblock"), locator);
434 bool ReadBestBlock(CBlockLocator& locator)
436 return Read(std::string("bestblock"), locator);
439 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
442 return Read(std::string("defaultkey"), vchPubKey);
445 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
448 return Write(std::string("defaultkey"), vchPubKey);
451 bool ReadPool(int64 nPool, CKeyPool& keypool)
453 return Read(std::make_pair(std::string("pool"), nPool), keypool);
456 bool WritePool(int64 nPool, const CKeyPool& keypool)
459 return Write(std::make_pair(std::string("pool"), nPool), keypool);
462 bool ErasePool(int64 nPool)
465 return Erase(std::make_pair(std::string("pool"), nPool));
469 bool ReadSetting(const std::string& strKey, T& value)
471 return Read(std::make_pair(std::string("setting"), strKey), value);
475 bool WriteSetting(const std::string& strKey, const T& value)
478 return Write(std::make_pair(std::string("setting"), strKey), value);
481 bool ReadAccount(const std::string& strAccount, CAccount& account);
482 bool WriteAccount(const std::string& strAccount, const CAccount& account);
483 bool WriteAccountingEntry(const CAccountingEntry& acentry);
484 int64 GetAccountCreditDebit(const std::string& strAccount);
485 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
487 int LoadWallet(CWallet* pwallet);