X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=blobdiff_plain;f=src%2Fdb.h;h=07bb2b0115f052f28bb4350692669f07c601cfaf;hp=48e10a95a7d1be16e8ea6525ab8e59d6a3845d22;hb=8982b69aabfefd65e8f3d859018228998f523cae;hpb=6b6aaa1698838278a547f16a15e635bd58ec867d diff --git a/src/db.h b/src/db.h index 48e10a9..07bb2b0 100644 --- a/src/db.h +++ b/src/db.h @@ -1,7 +1,7 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2012 The Bitcoin 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 @@ -25,11 +25,73 @@ class CWallet; class CWalletTx; extern unsigned int nWalletDBUpdated; -extern DbEnv dbenv; -extern void DBFlush(bool fShutdown); void ThreadFlushWalletDB(void* parg); bool BackupWallet(const CWallet& wallet, const std::string& strDest); +bool DumpWallet(CWallet* pwallet, const std::string& strDest); +bool ImportWallet(CWallet* pwallet, const std::string& strLocation); + +class CDBEnv +{ +private: + bool fDetachDB; + bool fDbEnvInit; + bool fMockDb; + boost::filesystem::path pathEnv; + std::string strPath; + + void EnvShutdown(); + +public: + mutable CCriticalSection cs_db; + DbEnv dbenv; + std::map mapFileUseCount; + std::map mapDb; + + CDBEnv(); + ~CDBEnv(); + void MakeMock(); + bool IsMock() { return fMockDb; }; + + /* + * Verify that database file strFile is OK. If it is not, + * call the callback to try to recover. + * This must be called BEFORE strFile is opened. + * Returns true if strFile is OK. + */ + enum VerifyResult { VERIFY_OK, RECOVER_OK, RECOVER_FAIL }; + VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); + /* + * Salvage data from a file that Verify says is bad. + * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). + * Appends binary key/value pairs to vResult, returns true if successful. + * NOTE: reads the entire database into memory, so cannot be used + * for huge databases. + */ + typedef std::pair, std::vector > KeyValPair; + bool Salvage(std::string strFile, bool fAggressive, std::vector& vResult); + + bool Open(boost::filesystem::path pathEnv_); + void Close(); + void Flush(bool fShutdown); + void CheckpointLSN(std::string strFile); + void SetDetach(bool fDetachDB_) { fDetachDB = fDetachDB_; } + bool GetDetach() { return fDetachDB; } + + void CloseDb(const std::string& strFile); + bool RemoveDb(const std::string& strFile); + + DbTxn *TxnBegin(int flags=DB_TXN_WRITE_NOSYNC) + { + DbTxn* ptxn = NULL; + int ret = dbenv.txn_begin(NULL, &ptxn, flags); + if (!ptxn || ret != 0) + return NULL; + return ptxn; + } +}; + +extern CDBEnv bitdb; /** RAII class that provides access to a Berkeley database */ @@ -38,7 +100,7 @@ class CDB protected: Db* pdb; std::string strFile; - std::vector vTxn; + DbTxn *activeTxn; bool fReadOnly; explicit CDB(const char* pszFile, const char* pszMode="r+"); @@ -60,19 +122,24 @@ protected: CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; - Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datKey(&ssKey[0], (uint32_t)ssKey.size()); // Read Dbt datValue; datValue.set_flags(DB_DBT_MALLOC); - int ret = pdb->get(GetTxn(), &datKey, &datValue, 0); + int ret = pdb->get(activeTxn, &datKey, &datValue, 0); memset(datKey.get_data(), 0, datKey.get_size()); if (datValue.get_data() == NULL) return false; // Unserialize value - CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); - ssValue >> value; + try { + CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK, CLIENT_VERSION); + ssValue >> value; + } + catch (const std::exception&) { + return false; + } // Clear and free memory memset(datValue.get_data(), 0, datValue.get_size()); @@ -92,16 +159,16 @@ protected: CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; - Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datKey(&ssKey[0], (uint32_t)ssKey.size()); // Value CDataStream ssValue(SER_DISK, CLIENT_VERSION); ssValue.reserve(10000); ssValue << value; - Dbt datValue(&ssValue[0], ssValue.size()); + Dbt datValue(&ssValue[0], (uint32_t)ssValue.size()); // Write - int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); + int ret = pdb->put(activeTxn, &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE)); // Clear memory in case it was a private key memset(datKey.get_data(), 0, datKey.get_size()); @@ -121,10 +188,10 @@ protected: CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; - Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datKey(&ssKey[0], (uint32_t)ssKey.size()); // Erase - int ret = pdb->del(GetTxn(), &datKey, 0); + int ret = pdb->del(activeTxn, &datKey, 0); // Clear memory memset(datKey.get_data(), 0, datKey.get_size()); @@ -141,10 +208,10 @@ protected: CDataStream ssKey(SER_DISK, CLIENT_VERSION); ssKey.reserve(1000); ssKey << key; - Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datKey(&ssKey[0], (uint32_t)ssKey.size()); // Exists - int ret = pdb->exists(GetTxn(), &datKey, 0); + int ret = pdb->exists(activeTxn, &datKey, 0); // Clear memory memset(datKey.get_data(), 0, datKey.get_size()); @@ -169,13 +236,13 @@ protected: if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) { datKey.set_data(&ssKey[0]); - datKey.set_size(ssKey.size()); + datKey.set_size((uint32_t)ssKey.size()); } Dbt datValue; if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE) { datValue.set_data(&ssValue[0]); - datValue.set_size(ssValue.size()); + datValue.set_size((uint32_t)ssValue.size()); } datKey.set_flags(DB_DBT_MALLOC); datValue.set_flags(DB_DBT_MALLOC); @@ -201,46 +268,33 @@ protected: return 0; } - DbTxn* GetTxn() - { - if (!vTxn.empty()) - return vTxn.back(); - else - return NULL; - } - public: bool TxnBegin() { - if (!pdb) + if (!pdb || activeTxn) return false; - DbTxn* ptxn = NULL; - int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC); - if (!ptxn || ret != 0) + DbTxn* ptxn = bitdb.TxnBegin(); + if (!ptxn) return false; - vTxn.push_back(ptxn); + activeTxn = ptxn; return true; } bool TxnCommit() { - if (!pdb) + if (!pdb || !activeTxn) return false; - if (vTxn.empty()) - return false; - int ret = vTxn.back()->commit(0); - vTxn.pop_back(); + int ret = activeTxn->commit(0); + activeTxn = NULL; return (ret == 0); } bool TxnAbort() { - if (!pdb) - return false; - if (vTxn.empty()) + if (!pdb || !activeTxn) return false; - int ret = vTxn.back()->abort(); - vTxn.pop_back(); + int ret = activeTxn->abort(); + activeTxn = NULL; return (ret == 0); } @@ -259,56 +313,15 @@ public: }; - - - - - -/** Access to the transaction database (blkindex.dat) */ -class CTxDB : public CDB +/** Access to the (IP) address database (peers.dat) */ +class CAddrDB { -public: - CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { } private: - CTxDB(const CTxDB&); - void operator=(const CTxDB&); + boost::filesystem::path pathAddr; public: - bool ReadTxIndex(uint256 hash, CTxIndex& txindex); - bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex); - 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, std::vector& vtx); - bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex); - bool ReadDiskTx(uint256 hash, CTransaction& tx); - bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex); - bool ReadDiskTx(COutPoint outpoint, CTransaction& tx); - bool WriteBlockIndex(const CDiskBlockIndex& blockindex); - bool EraseBlockIndex(uint256 hash); - bool ReadHashBestChain(uint256& hashBestChain); - bool WriteHashBestChain(uint256 hashBestChain); - bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork); - bool WriteBestInvalidWork(CBigNum bnBestInvalidWork); - bool LoadBlockIndex(); + CAddrDB(); + bool Write(const CAddrMan& addr); + bool Read(CAddrMan& addr); }; - - - -/** Access to the (IP) address database (addr.dat) */ -class CAddrDB : public CDB -{ -public: - CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { } -private: - CAddrDB(const CAddrDB&); - void operator=(const CAddrDB&); -public: - bool WriteAddrman(const CAddrMan& addr); - bool LoadAddresses(); -}; - -bool LoadAddresses(); - - #endif // BITCOIN_DB_H