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 COPYING or http://www.opensource.org/licenses/mit-license.php.
19 class CDiskBlockIndex;
27 extern unsigned int nWalletDBUpdated;
28 extern bool fDetachDB;
31 extern void DBFlush(bool fShutdown);
32 void ThreadFlushWalletDB(void* parg);
33 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
36 /** RAII class that provides access to a Berkeley database */
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, CLIENT_VERSION);
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)
75 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
78 // Clear and free memory
79 memset(datValue.get_data(), 0, datValue.get_size());
80 free(datValue.get_data());
84 template<typename K, typename T>
85 bool Write(const K& key, const T& value, bool fOverwrite=true)
90 assert(!"Write called on database in read-only mode");
93 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
96 Dbt datKey(&ssKey[0], ssKey.size());
99 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
100 ssValue.reserve(10000);
102 Dbt datValue(&ssValue[0], ssValue.size());
105 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
107 // Clear memory in case it was a private key
108 memset(datKey.get_data(), 0, datKey.get_size());
109 memset(datValue.get_data(), 0, datValue.get_size());
114 bool Erase(const K& key)
119 assert(!"Erase called on database in read-only mode");
122 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
125 Dbt datKey(&ssKey[0], ssKey.size());
128 int ret = pdb->del(GetTxn(), &datKey, 0);
131 memset(datKey.get_data(), 0, datKey.get_size());
132 return (ret == 0 || ret == DB_NOTFOUND);
136 bool Exists(const K& key)
142 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
145 Dbt datKey(&ssKey[0], ssKey.size());
148 int ret = pdb->exists(GetTxn(), &datKey, 0);
151 memset(datKey.get_data(), 0, datKey.get_size());
160 int ret = pdb->cursor(NULL, &pcursor, 0);
166 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
170 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
172 datKey.set_data(&ssKey[0]);
173 datKey.set_size(ssKey.size());
176 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
178 datValue.set_data(&ssValue[0]);
179 datValue.set_size(ssValue.size());
181 datKey.set_flags(DB_DBT_MALLOC);
182 datValue.set_flags(DB_DBT_MALLOC);
183 int ret = pcursor->get(&datKey, &datValue, fFlags);
186 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
189 // Convert to streams
190 ssKey.SetType(SER_DISK);
192 ssKey.write((char*)datKey.get_data(), datKey.get_size());
193 ssValue.SetType(SER_DISK);
195 ssValue.write((char*)datValue.get_data(), datValue.get_size());
197 // Clear and free memory
198 memset(datKey.get_data(), 0, datKey.get_size());
199 memset(datValue.get_data(), 0, datValue.get_size());
200 free(datKey.get_data());
201 free(datValue.get_data());
219 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
220 if (!ptxn || ret != 0)
222 vTxn.push_back(ptxn);
232 int ret = vTxn.back()->commit(0);
243 int ret = vTxn.back()->abort();
248 bool ReadVersion(int& nVersion)
251 return Read(std::string("version"), nVersion);
254 bool WriteVersion(int nVersion)
256 return Write(std::string("version"), nVersion);
259 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
268 /** Access to the transaction database (blkindex.dat) */
269 class CTxDB : public CDB
272 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
275 void operator=(const CTxDB&);
277 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
278 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
279 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
280 bool EraseTxIndex(const CTransaction& tx);
281 bool ContainsTx(uint256 hash);
282 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
283 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
284 bool ReadDiskTx(uint256 hash, CTransaction& tx);
285 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
286 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
287 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
288 bool ReadHashBestChain(uint256& hashBestChain);
289 bool WriteHashBestChain(uint256 hashBestChain);
290 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
291 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
292 bool LoadBlockIndex();
298 /** Access to the (IP) address database (peers.dat) */
302 boost::filesystem::path pathAddr;
305 bool Write(const CAddrMan& addr);
306 bool Read(CAddrMan& addr);
309 #endif // BITCOIN_DB_H