1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2012 The Bitcoin developers
3 // Copyright (c) 2011-2012 The PPCoin developers
4 // Copyright (c) 2012-2013 The NovaCoin developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
21 class CDiskBlockIndex;
29 extern unsigned int nWalletDBUpdated;
30 extern bool fDetachDB;
33 extern void DBFlush(bool fShutdown);
34 void ThreadFlushWalletDB(void* parg);
35 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
38 /** RAII class that provides access to a Berkeley database */
44 std::vector<DbTxn*> vTxn;
47 explicit CDB(const char* pszFile, const char* pszMode="r+");
53 void operator=(const CDB&);
56 template<typename K, typename T>
57 bool Read(const K& key, T& value)
63 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
66 Dbt datKey(&ssKey[0], ssKey.size());
70 datValue.set_flags(DB_DBT_MALLOC);
71 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
72 memset(datKey.get_data(), 0, datKey.get_size());
73 if (datValue.get_data() == NULL)
78 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
81 catch (std::exception &e) {
85 // Clear and free memory
86 memset(datValue.get_data(), 0, datValue.get_size());
87 free(datValue.get_data());
91 template<typename K, typename T>
92 bool Write(const K& key, const T& value, bool fOverwrite=true)
97 assert(!"Write called on database in read-only mode");
100 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
103 Dbt datKey(&ssKey[0], ssKey.size());
106 CDataStream ssValue(SER_DISK, CLIENT_VERSION);
107 ssValue.reserve(10000);
109 Dbt datValue(&ssValue[0], ssValue.size());
112 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
114 // Clear memory in case it was a private key
115 memset(datKey.get_data(), 0, datKey.get_size());
116 memset(datValue.get_data(), 0, datValue.get_size());
121 bool Erase(const K& key)
126 assert(!"Erase called on database in read-only mode");
129 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
132 Dbt datKey(&ssKey[0], ssKey.size());
135 int ret = pdb->del(GetTxn(), &datKey, 0);
138 memset(datKey.get_data(), 0, datKey.get_size());
139 return (ret == 0 || ret == DB_NOTFOUND);
143 bool Exists(const K& key)
149 CDataStream ssKey(SER_DISK, CLIENT_VERSION);
152 Dbt datKey(&ssKey[0], ssKey.size());
155 int ret = pdb->exists(GetTxn(), &datKey, 0);
158 memset(datKey.get_data(), 0, datKey.get_size());
167 int ret = pdb->cursor(NULL, &pcursor, 0);
173 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
177 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
179 datKey.set_data(&ssKey[0]);
180 datKey.set_size(ssKey.size());
183 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
185 datValue.set_data(&ssValue[0]);
186 datValue.set_size(ssValue.size());
188 datKey.set_flags(DB_DBT_MALLOC);
189 datValue.set_flags(DB_DBT_MALLOC);
190 int ret = pcursor->get(&datKey, &datValue, fFlags);
193 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
196 // Convert to streams
197 ssKey.SetType(SER_DISK);
199 ssKey.write((char*)datKey.get_data(), datKey.get_size());
200 ssValue.SetType(SER_DISK);
202 ssValue.write((char*)datValue.get_data(), datValue.get_size());
204 // Clear and free memory
205 memset(datKey.get_data(), 0, datKey.get_size());
206 memset(datValue.get_data(), 0, datValue.get_size());
207 free(datKey.get_data());
208 free(datValue.get_data());
226 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC);
227 if (!ptxn || ret != 0)
229 vTxn.push_back(ptxn);
239 int ret = vTxn.back()->commit(0);
250 int ret = vTxn.back()->abort();
255 bool ReadVersion(int& nVersion)
258 return Read(std::string("version"), nVersion);
261 bool WriteVersion(int nVersion)
263 return Write(std::string("version"), nVersion);
266 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
275 /** Access to the transaction database (blkindex.dat) */
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 ReadBestInvalidTrust(CBigNum& bnBestInvalidTrust);
299 bool WriteBestInvalidTrust(CBigNum bnBestInvalidTrust);
300 bool ReadSyncCheckpoint(uint256& hashCheckpoint);
301 bool WriteSyncCheckpoint(uint256 hashCheckpoint);
302 bool ReadCheckpointPubKey(std::string& strPubKey);
303 bool WriteCheckpointPubKey(const std::string& strPubKey);
304 bool LoadBlockIndex();
310 /** Access to the (IP) address database (addr.dat) */
311 class CAddrDB : public CDB
314 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
316 CAddrDB(const CAddrDB&);
317 void operator=(const CAddrDB&);
319 bool WriteAddrman(const CAddrMan& addr);
320 bool LoadAddresses();
323 bool LoadAddresses();
326 #endif // BITCOIN_DB_H