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.
17 class CDiskBlockIndex;
25 class CAccountingEntry;
28 extern std::vector<unsigned char> vchDefaultKey;
30 extern int nBestHeight;
33 extern unsigned int nWalletDBUpdated;
37 extern void DBFlush(bool fShutdown);
38 extern std::vector<unsigned char> GetKeyFromKeyPool();
39 extern int64 GetOldestKeyPoolTime();
40 extern void ThreadFlushWalletDB(void* parg);
51 std::vector<DbTxn*> vTxn;
54 explicit CDB(const char* pszFile, const char* pszMode="r+");
60 void operator=(const CDB&);
63 template<typename K, typename T>
64 bool Read(const K& key, T& value)
70 CDataStream ssKey(SER_DISK);
73 Dbt datKey(&ssKey[0], ssKey.size());
77 datValue.set_flags(DB_DBT_MALLOC);
78 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
79 memset(datKey.get_data(), 0, datKey.get_size());
80 if (datValue.get_data() == NULL)
84 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
87 // Clear and free memory
88 memset(datValue.get_data(), 0, datValue.get_size());
89 free(datValue.get_data());
93 template<typename K, typename T>
94 bool Write(const K& key, const T& value, bool fOverwrite=true)
99 assert(("Write called on database in read-only mode", false));
102 CDataStream ssKey(SER_DISK);
105 Dbt datKey(&ssKey[0], ssKey.size());
108 CDataStream ssValue(SER_DISK);
109 ssValue.reserve(10000);
111 Dbt datValue(&ssValue[0], ssValue.size());
114 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
116 // Clear memory in case it was a private key
117 memset(datKey.get_data(), 0, datKey.get_size());
118 memset(datValue.get_data(), 0, datValue.get_size());
123 bool Erase(const K& key)
128 assert(("Erase called on database in read-only mode", false));
131 CDataStream ssKey(SER_DISK);
134 Dbt datKey(&ssKey[0], ssKey.size());
137 int ret = pdb->del(GetTxn(), &datKey, 0);
140 memset(datKey.get_data(), 0, datKey.get_size());
141 return (ret == 0 || ret == DB_NOTFOUND);
145 bool Exists(const K& key)
151 CDataStream ssKey(SER_DISK);
154 Dbt datKey(&ssKey[0], ssKey.size());
157 int ret = pdb->exists(GetTxn(), &datKey, 0);
160 memset(datKey.get_data(), 0, datKey.get_size());
169 int ret = pdb->cursor(NULL, &pcursor, 0);
175 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
179 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
181 datKey.set_data(&ssKey[0]);
182 datKey.set_size(ssKey.size());
185 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
187 datValue.set_data(&ssValue[0]);
188 datValue.set_size(ssValue.size());
190 datKey.set_flags(DB_DBT_MALLOC);
191 datValue.set_flags(DB_DBT_MALLOC);
192 int ret = pcursor->get(&datKey, &datValue, fFlags);
195 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
198 // Convert to streams
199 ssKey.SetType(SER_DISK);
201 ssKey.write((char*)datKey.get_data(), datKey.get_size());
202 ssValue.SetType(SER_DISK);
204 ssValue.write((char*)datValue.get_data(), datValue.get_size());
206 // Clear and free memory
207 memset(datKey.get_data(), 0, datKey.get_size());
208 memset(datValue.get_data(), 0, datValue.get_size());
209 free(datKey.get_data());
210 free(datValue.get_data());
228 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
229 if (!ptxn || ret != 0)
231 vTxn.push_back(ptxn);
241 int ret = vTxn.back()->commit(0);
252 int ret = vTxn.back()->abort();
257 bool ReadVersion(int& nVersion)
260 return Read(std::string("version"), nVersion);
263 bool WriteVersion(int nVersion)
265 return Write(std::string("version"), nVersion);
276 class CTxDB : public CDB
279 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
282 void operator=(const CTxDB&);
284 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
285 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
286 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
287 bool EraseTxIndex(const CTransaction& tx);
288 bool ContainsTx(uint256 hash);
289 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
290 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
291 bool ReadDiskTx(uint256 hash, CTransaction& tx);
292 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
293 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
294 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
295 bool EraseBlockIndex(uint256 hash);
296 bool ReadHashBestChain(uint256& hashBestChain);
297 bool WriteHashBestChain(uint256 hashBestChain);
298 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
299 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
300 bool LoadBlockIndex();
307 class CAddrDB : public CDB
310 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
312 CAddrDB(const CAddrDB&);
313 void operator=(const CAddrDB&);
315 bool WriteAddress(const CAddress& addr);
316 bool EraseAddress(const CAddress& addr);
317 bool LoadAddresses();
320 bool LoadAddresses();
331 std::vector<unsigned char> vchPubKey;
338 CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
341 vchPubKey = vchPubKeyIn;
346 if (!(nType & SER_GETHASH))
349 READWRITE(vchPubKey);
356 class CWalletDB : public CDB
359 CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode)
363 CWalletDB(const CWalletDB&);
364 void operator=(const CWalletDB&);
366 bool ReadName(const std::string& strAddress, std::string& strName)
369 return Read(std::make_pair(std::string("name"), strAddress), strName);
372 bool WriteName(const std::string& strAddress, const std::string& strName)
374 CRITICAL_BLOCK(cs_mapAddressBook)
375 mapAddressBook[strAddress] = strName;
377 return Write(std::make_pair(std::string("name"), strAddress), strName);
380 bool EraseName(const std::string& strAddress)
382 // This should only be used for sending addresses, never for receiving addresses,
383 // receiving addresses must always have an address book entry if they're not change return.
384 CRITICAL_BLOCK(cs_mapAddressBook)
385 mapAddressBook.erase(strAddress);
387 return Erase(std::make_pair(std::string("name"), strAddress));
390 bool ReadTx(uint256 hash, CWalletTx& wtx)
392 return Read(std::make_pair(std::string("tx"), hash), wtx);
395 bool WriteTx(uint256 hash, const CWalletTx& wtx)
398 return Write(std::make_pair(std::string("tx"), hash), wtx);
401 bool EraseTx(uint256 hash)
404 return Erase(std::make_pair(std::string("tx"), hash));
407 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
410 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
413 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
416 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
419 bool WriteBestBlock(const CBlockLocator& locator)
422 return Write(std::string("bestblock"), locator);
425 bool ReadBestBlock(CBlockLocator& locator)
427 return Read(std::string("bestblock"), locator);
430 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
433 return Read(std::string("defaultkey"), vchPubKey);
436 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
438 vchDefaultKey = vchPubKey;
440 return Write(std::string("defaultkey"), vchPubKey);
444 bool ReadSetting(const std::string& strKey, T& value)
446 return Read(std::make_pair(std::string("setting"), strKey), value);
450 bool WriteSetting(const std::string& strKey, const T& value)
453 return Write(std::make_pair(std::string("setting"), strKey), value);
456 bool ReadAccount(const std::string& strAccount, CAccount& account);
457 bool WriteAccount(const std::string& strAccount, const CAccount& account);
458 bool WriteAccountingEntry(const CAccountingEntry& acentry);
459 int64 GetAccountCreditDebit(const std::string& strAccount);
460 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
464 void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
465 void KeepKey(int64 nIndex);
466 static void ReturnKey(int64 nIndex);
467 friend class CReserveKey;
468 friend std::vector<unsigned char> GetKeyFromKeyPool();
469 friend int64 GetOldestKeyPoolTime();
472 bool LoadWallet(bool& fFirstRunRet);
473 void BackupWallet(const std::string& strDest);
475 inline bool SetAddressBookName(const std::string& strAddress, const std::string& strName)
477 return CWalletDB().WriteName(strAddress, strName);
484 std::vector<unsigned char> vchPubKey;
497 std::vector<unsigned char> GetReservedKey();