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.
16 class CDiskBlockIndex;
23 class CAccountingEntry;
27 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);
43 std::vector<DbTxn*> vTxn;
46 explicit CDB(const char* pszFile, const char* pszMode="r+");
52 void operator=(const CDB&);
55 template<typename K, typename T>
56 bool Read(const K& key, T& value)
62 CDataStream ssKey(SER_DISK);
65 Dbt datKey(&ssKey[0], ssKey.size());
69 datValue.set_flags(DB_DBT_MALLOC);
70 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
71 memset(datKey.get_data(), 0, datKey.get_size());
72 if (datValue.get_data() == NULL)
76 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
79 // Clear and free memory
80 memset(datValue.get_data(), 0, datValue.get_size());
81 free(datValue.get_data());
85 template<typename K, typename T>
86 bool Write(const K& key, const T& value, bool fOverwrite=true)
91 assert(("Write called on database in read-only mode", false));
94 CDataStream ssKey(SER_DISK);
97 Dbt datKey(&ssKey[0], ssKey.size());
100 CDataStream ssValue(SER_DISK);
101 ssValue.reserve(10000);
103 Dbt datValue(&ssValue[0], ssValue.size());
106 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
108 // Clear memory in case it was a private key
109 memset(datKey.get_data(), 0, datKey.get_size());
110 memset(datValue.get_data(), 0, datValue.get_size());
115 bool Erase(const K& key)
120 assert(("Erase called on database in read-only mode", false));
123 CDataStream ssKey(SER_DISK);
126 Dbt datKey(&ssKey[0], ssKey.size());
129 int ret = pdb->del(GetTxn(), &datKey, 0);
132 memset(datKey.get_data(), 0, datKey.get_size());
133 return (ret == 0 || ret == DB_NOTFOUND);
137 bool Exists(const K& key)
143 CDataStream ssKey(SER_DISK);
146 Dbt datKey(&ssKey[0], ssKey.size());
149 int ret = pdb->exists(GetTxn(), &datKey, 0);
152 memset(datKey.get_data(), 0, datKey.get_size());
161 int ret = pdb->cursor(NULL, &pcursor, 0);
167 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
171 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
173 datKey.set_data(&ssKey[0]);
174 datKey.set_size(ssKey.size());
177 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
179 datValue.set_data(&ssValue[0]);
180 datValue.set_size(ssValue.size());
182 datKey.set_flags(DB_DBT_MALLOC);
183 datValue.set_flags(DB_DBT_MALLOC);
184 int ret = pcursor->get(&datKey, &datValue, fFlags);
187 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
190 // Convert to streams
191 ssKey.SetType(SER_DISK);
193 ssKey.write((char*)datKey.get_data(), datKey.get_size());
194 ssValue.SetType(SER_DISK);
196 ssValue.write((char*)datValue.get_data(), datValue.get_size());
198 // Clear and free memory
199 memset(datKey.get_data(), 0, datKey.get_size());
200 memset(datValue.get_data(), 0, datValue.get_size());
201 free(datKey.get_data());
202 free(datValue.get_data());
220 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
221 if (!ptxn || ret != 0)
223 vTxn.push_back(ptxn);
233 int ret = vTxn.back()->commit(0);
244 int ret = vTxn.back()->abort();
249 bool ReadVersion(int& nVersion)
252 return Read(std::string("version"), nVersion);
255 bool WriteVersion(int nVersion)
257 return Write(std::string("version"), nVersion);
268 class CTxDB : public CDB
271 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
274 void operator=(const CTxDB&);
276 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
277 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
278 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
279 bool EraseTxIndex(const CTransaction& tx);
280 bool ContainsTx(uint256 hash);
281 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
282 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
283 bool ReadDiskTx(uint256 hash, CTransaction& tx);
284 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
285 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
286 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
287 bool EraseBlockIndex(uint256 hash);
288 bool ReadHashBestChain(uint256& hashBestChain);
289 bool WriteHashBestChain(uint256 hashBestChain);
290 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
291 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
292 bool LoadBlockIndex();
299 class CAddrDB : public CDB
302 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
304 CAddrDB(const CAddrDB&);
305 void operator=(const CAddrDB&);
307 bool WriteAddress(const CAddress& addr);
308 bool EraseAddress(const CAddress& addr);
309 bool LoadAddresses();
312 bool LoadAddresses();
320 std::vector<unsigned char> vchPubKey;
327 CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
330 vchPubKey = vchPubKeyIn;
335 if (!(nType & SER_GETHASH))
338 READWRITE(vchPubKey);
345 class CWalletDB : public CDB
348 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
352 CWalletDB(const CWalletDB&);
353 void operator=(const CWalletDB&);
355 bool ReadName(const std::string& strAddress, std::string& strName)
358 return Read(std::make_pair(std::string("name"), strAddress), strName);
361 bool WriteName(const std::string& strAddress, const std::string& strName);
363 bool EraseName(const std::string& strAddress);
365 bool ReadTx(uint256 hash, CWalletTx& wtx)
367 return Read(std::make_pair(std::string("tx"), hash), wtx);
370 bool WriteTx(uint256 hash, const CWalletTx& wtx)
373 return Write(std::make_pair(std::string("tx"), hash), wtx);
376 bool EraseTx(uint256 hash)
379 return Erase(std::make_pair(std::string("tx"), hash));
382 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
385 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
388 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
391 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
394 bool WriteBestBlock(const CBlockLocator& locator)
397 return Write(std::string("bestblock"), locator);
400 bool ReadBestBlock(CBlockLocator& locator)
402 return Read(std::string("bestblock"), locator);
405 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
408 return Read(std::string("defaultkey"), vchPubKey);
411 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
414 return Write(std::string("defaultkey"), vchPubKey);
417 bool ReadPool(int64 nPool, CKeyPool& keypool)
419 return Read(std::make_pair(std::string("pool"), nPool), keypool);
422 bool WritePool(int64 nPool, const CKeyPool& keypool)
425 return Write(std::make_pair(std::string("pool"), nPool), keypool);
428 bool ErasePool(int64 nPool)
431 return Erase(std::make_pair(std::string("pool"), nPool));
435 bool ReadSetting(const std::string& strKey, T& value)
437 return Read(std::make_pair(std::string("setting"), strKey), value);
441 bool WriteSetting(const std::string& strKey, const T& value)
444 return Write(std::make_pair(std::string("setting"), strKey), value);
447 bool ReadAccount(const std::string& strAccount, CAccount& account);
448 bool WriteAccount(const std::string& strAccount, const CAccount& account);
449 bool WriteAccountingEntry(const CAccountingEntry& acentry);
450 int64 GetAccountCreditDebit(const std::string& strAccount);
451 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
453 bool LoadWallet(CWallet* pwallet);