// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2012 The Bitcoin developers
+// Copyright (c) 2011-2012 The PPCoin developers
// Distributed under the MIT/X11 software license, see the accompanying
-// file license.txt or http://www.opensource.org/licenses/mit-license.php.
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+#ifndef BITCOIN_DB_H
+#define BITCOIN_DB_H
-class CTransaction;
-class CTxIndex;
+#include "main.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <db_cxx.h>
+
+class CAddress;
+class CAddrMan;
+class CBlockLocator;
class CDiskBlockIndex;
class CDiskTxPos;
+class CMasterKey;
class COutPoint;
-class CUser;
-class CReview;
-class CAddress;
+class CTxIndex;
+class CWallet;
class CWalletTx;
-class CAccount;
-class CAccountingEntry;
-class CBlockLocator;
-
-extern map<string, string> mapAddressBook;
-extern CCriticalSection cs_mapAddressBook;
-extern vector<unsigned char> vchDefaultKey;
-extern bool fClient;
-extern int nBestHeight;
-
extern unsigned int nWalletDBUpdated;
+extern bool fDetachDB;
extern DbEnv dbenv;
-
extern void DBFlush(bool fShutdown);
-extern vector<unsigned char> GetKeyFromKeyPool();
-extern int64 GetOldestKeyPoolTime();
-
-
+void ThreadFlushWalletDB(void* parg);
+bool BackupWallet(const CWallet& wallet, const std::string& strDest);
+/** RAII class that provides access to a Berkeley database */
class CDB
{
protected:
Db* pdb;
- string strFile;
- vector<DbTxn*> vTxn;
+ std::string strFile;
+ std::vector<DbTxn*> vTxn;
bool fReadOnly;
explicit CDB(const char* pszFile, const char* pszMode="r+");
return false;
// Key
- CDataStream ssKey(SER_DISK);
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
return false;
// Unserialize value
- CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
- ssValue >> value;
+ try {
+ CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION);
+ ssValue >> value;
+ }
+ catch (std::exception &e) {
+ return false;
+ }
// Clear and free memory
memset(datValue.get_data(), 0, datValue.get_size());
if (!pdb)
return false;
if (fReadOnly)
- assert(("Write called on database in read-only mode", false));
+ assert(!"Write called on database in read-only mode");
// Key
- CDataStream ssKey(SER_DISK);
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
// Value
- CDataStream ssValue(SER_DISK);
+ CDataStream ssValue(SER_DISK, CLIENT_VERSION);
ssValue.reserve(10000);
ssValue << value;
Dbt datValue(&ssValue[0], ssValue.size());
if (!pdb)
return false;
if (fReadOnly)
- assert(("Erase called on database in read-only mode", false));
+ assert(!"Erase called on database in read-only mode");
// Key
- CDataStream ssKey(SER_DISK);
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
return false;
// Key
- CDataStream ssKey(SER_DISK);
+ CDataStream ssKey(SER_DISK, CLIENT_VERSION);
ssKey.reserve(1000);
ssKey << key;
Dbt datKey(&ssKey[0], ssKey.size());
if (!pdb)
return false;
DbTxn* ptxn = NULL;
- int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
+ int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_WRITE_NOSYNC);
if (!ptxn || ret != 0)
return false;
vTxn.push_back(ptxn);
bool ReadVersion(int& nVersion)
{
nVersion = 0;
- return Read(string("version"), nVersion);
+ return Read(std::string("version"), nVersion);
}
bool WriteVersion(int nVersion)
{
- return Write(string("version"), nVersion);
+ return Write(std::string("version"), nVersion);
}
-};
+ bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
+};
+/** Access to the transaction database (blkindex.dat) */
class CTxDB : public CDB
{
public:
bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
bool EraseTxIndex(const CTransaction& tx);
bool ContainsTx(uint256 hash);
- bool ReadOwnerTxes(uint160 hash160, int nHeight, vector<CTransaction>& vtx);
+ bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
bool ReadDiskTx(uint256 hash, CTransaction& tx);
bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
bool EraseBlockIndex(uint256 hash);
bool ReadHashBestChain(uint256& hashBestChain);
bool WriteHashBestChain(uint256 hashBestChain);
- bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
- bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
+ bool ReadBestInvalidTrust(uint64& nBestInvalidTrust);
+ bool WriteBestInvalidTrust(uint64 nBestInvalidTrust);
+ bool ReadSyncCheckpoint(uint256& hashCheckpoint);
+ bool WriteSyncCheckpoint(uint256 hashCheckpoint);
+ bool ReadCheckpointPubKey(std::string& strPubKey);
+ bool WriteCheckpointPubKey(const std::string& strPubKey);
bool LoadBlockIndex();
};
-
+/** Access to the (IP) address database (addr.dat) */
class CAddrDB : public CDB
{
public:
CAddrDB(const CAddrDB&);
void operator=(const CAddrDB&);
public:
- bool WriteAddress(const CAddress& addr);
- bool EraseAddress(const CAddress& addr);
+ bool WriteAddrman(const CAddrMan& addr);
bool LoadAddresses();
};
bool LoadAddresses();
-
-
-
-
-class CKeyPool
-{
-public:
- int64 nTime;
- vector<unsigned char> vchPubKey;
-
- CKeyPool()
- {
- nTime = GetTime();
- }
-
- CKeyPool(const vector<unsigned char>& vchPubKeyIn)
- {
- nTime = GetTime();
- vchPubKey = vchPubKeyIn;
- }
-
- IMPLEMENT_SERIALIZE
- (
- if (!(nType & SER_GETHASH))
- READWRITE(nVersion);
- READWRITE(nTime);
- READWRITE(vchPubKey);
- )
-};
-
-
-
-
-class CWalletDB : public CDB
-{
-public:
- CWalletDB(const char* pszMode="r+") : CDB("wallet.dat", pszMode)
- {
- }
-private:
- CWalletDB(const CWalletDB&);
- void operator=(const CWalletDB&);
-public:
- bool ReadName(const string& strAddress, string& strName)
- {
- strName = "";
- return Read(make_pair(string("name"), strAddress), strName);
- }
-
- bool WriteName(const string& strAddress, const string& strName)
- {
- CRITICAL_BLOCK(cs_mapAddressBook)
- mapAddressBook[strAddress] = strName;
- nWalletDBUpdated++;
- return Write(make_pair(string("name"), strAddress), strName);
- }
-
- bool EraseName(const string& strAddress)
- {
- // This should only be used for sending addresses, never for receiving addresses,
- // receiving addresses must always have an address book entry if they're not change return.
- CRITICAL_BLOCK(cs_mapAddressBook)
- mapAddressBook.erase(strAddress);
- nWalletDBUpdated++;
- return Erase(make_pair(string("name"), strAddress));
- }
-
- bool ReadTx(uint256 hash, CWalletTx& wtx)
- {
- return Read(make_pair(string("tx"), hash), wtx);
- }
-
- bool WriteTx(uint256 hash, const CWalletTx& wtx)
- {
- nWalletDBUpdated++;
- return Write(make_pair(string("tx"), hash), wtx);
- }
-
- bool EraseTx(uint256 hash)
- {
- nWalletDBUpdated++;
- return Erase(make_pair(string("tx"), hash));
- }
-
- bool ReadKey(const vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
- {
- vchPrivKey.clear();
- return Read(make_pair(string("key"), vchPubKey), vchPrivKey);
- }
-
- bool WriteKey(const vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
- {
- nWalletDBUpdated++;
- return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
- }
-
- bool WriteBestBlock(const CBlockLocator& locator)
- {
- nWalletDBUpdated++;
- return Write(string("bestblock"), locator);
- }
-
- bool ReadBestBlock(CBlockLocator& locator)
- {
- return Read(string("bestblock"), locator);
- }
-
- bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
- {
- vchPubKey.clear();
- return Read(string("defaultkey"), vchPubKey);
- }
-
- bool WriteDefaultKey(const vector<unsigned char>& vchPubKey)
- {
- vchDefaultKey = vchPubKey;
- nWalletDBUpdated++;
- return Write(string("defaultkey"), vchPubKey);
- }
-
- template<typename T>
- bool ReadSetting(const string& strKey, T& value)
- {
- return Read(make_pair(string("setting"), strKey), value);
- }
-
- template<typename T>
- bool WriteSetting(const string& strKey, const T& value)
- {
- nWalletDBUpdated++;
- return Write(make_pair(string("setting"), strKey), value);
- }
-
- bool ReadAccount(const string& strAccount, CAccount& account);
- bool WriteAccount(const string& strAccount, const CAccount& account);
- bool WriteAccountingEntry(const CAccountingEntry& acentry);
- int64 GetAccountCreditDebit(const string& strAccount);
- void ListAccountCreditDebit(const string& strAccount, list<CAccountingEntry>& acentries);
-
- bool LoadWallet();
-protected:
- void ReserveKeyFromKeyPool(int64& nIndex, CKeyPool& keypool);
- void KeepKey(int64 nIndex);
- static void ReturnKey(int64 nIndex);
- friend class CReserveKey;
- friend vector<unsigned char> GetKeyFromKeyPool();
- friend int64 GetOldestKeyPoolTime();
-};
-
-bool LoadWallet(bool& fFirstRunRet);
-void BackupWallet(const string& strDest);
-
-inline bool SetAddressBookName(const string& strAddress, const string& strName)
-{
- return CWalletDB().WriteName(strAddress, strName);
-}
-
-class CReserveKey
-{
-protected:
- int64 nIndex;
- vector<unsigned char> vchPubKey;
-public:
- CReserveKey()
- {
- nIndex = -1;
- }
-
- ~CReserveKey()
- {
- if (!fShutdown)
- ReturnKey();
- }
-
- vector<unsigned char> GetReservedKey()
- {
- if (nIndex == -1)
- {
- CKeyPool keypool;
- CWalletDB().ReserveKeyFromKeyPool(nIndex, keypool);
- vchPubKey = keypool.vchPubKey;
- }
- assert(!vchPubKey.empty());
- return vchPubKey;
- }
-
- void KeepKey()
- {
- if (nIndex != -1)
- CWalletDB().KeepKey(nIndex);
- nIndex = -1;
- vchPubKey.clear();
- }
-
- void ReturnKey()
- {
- if (nIndex != -1)
- CWalletDB::ReturnKey(nIndex);
- nIndex = -1;
- vchPubKey.clear();
- }
-};
+#endif // BITCOIN_DB_H