-
+ 1A4B9BD666180ACF944D189FFD5B89DA0F1C0D7B60223FE7F16F73A7D90BDD2A75B7D46805738EA3DA36AE766B0AA4A5D29283B5F4EF8A77AAE991CF990AE0CC
bitcoin/src/db.h
(0 . 0)(1 . 485)
4921 // Copyright (c) 2009-2010 Satoshi Nakamoto
4922 // Copyright (c) 2011 The Bitcoin developers
4923 // Distributed under the MIT/X11 software license, see the accompanying
4924 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
4925 #ifndef BITCOIN_DB_H
4926 #define BITCOIN_DB_H
4927
4928 #include "key.h"
4929
4930 #include <map>
4931 #include <string>
4932 #include <vector>
4933
4934 #include <db_cxx.h>
4935
4936 class CTxIndex;
4937 class CDiskBlockIndex;
4938 class CDiskTxPos;
4939 class COutPoint;
4940 class CAddress;
4941 class CWalletTx;
4942 class CWallet;
4943 class CAccount;
4944 class CAccountingEntry;
4945 class CBlockLocator;
4946
4947
4948 extern unsigned int nWalletDBUpdated;
4949 extern DbEnv dbenv;
4950
4951 extern void DBFlush(bool fShutdown);
4952 void ThreadFlushWalletDB(void* parg);
4953 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
4954
4955
4956
4957 class CDB
4958 {
4959 protected:
4960 Db* pdb;
4961 std::string strFile;
4962 std::vector<DbTxn*> vTxn;
4963 bool fReadOnly;
4964
4965 explicit CDB(const char* pszFile, const char* pszMode="r+");
4966 ~CDB() { Close(); }
4967 public:
4968 void Close();
4969 private:
4970 CDB(const CDB&);
4971 void operator=(const CDB&);
4972
4973 protected:
4974 template<typename K, typename T>
4975 bool Read(const K& key, T& value)
4976 {
4977 if (!pdb)
4978 return false;
4979
4980 // Key
4981 CDataStream ssKey(SER_DISK);
4982 ssKey.reserve(1000);
4983 ssKey << key;
4984 Dbt datKey(&ssKey[0], ssKey.size());
4985
4986 // Read
4987 Dbt datValue;
4988 datValue.set_flags(DB_DBT_MALLOC);
4989 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
4990 memset(datKey.get_data(), 0, datKey.get_size());
4991 if (datValue.get_data() == NULL)
4992 return false;
4993
4994 // Unserialize value
4995 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
4996 ssValue >> value;
4997
4998 // Clear and free memory
4999 memset(datValue.get_data(), 0, datValue.get_size());
5000 free(datValue.get_data());
5001 return (ret == 0);
5002 }
5003
5004 template<typename K, typename T>
5005 bool Write(const K& key, const T& value, bool fOverwrite=true)
5006 {
5007 if (!pdb)
5008 return false;
5009 if (fReadOnly)
5010 assert(!"Write called on database in read-only mode");
5011
5012 // Key
5013 CDataStream ssKey(SER_DISK);
5014 ssKey.reserve(1000);
5015 ssKey << key;
5016 Dbt datKey(&ssKey[0], ssKey.size());
5017
5018 // Value
5019 CDataStream ssValue(SER_DISK);
5020 ssValue.reserve(10000);
5021 ssValue << value;
5022 Dbt datValue(&ssValue[0], ssValue.size());
5023
5024 // Write
5025 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
5026
5027 // Clear memory in case it was a private key
5028 memset(datKey.get_data(), 0, datKey.get_size());
5029 memset(datValue.get_data(), 0, datValue.get_size());
5030 return (ret == 0);
5031 }
5032
5033 template<typename K>
5034 bool Erase(const K& key)
5035 {
5036 if (!pdb)
5037 return false;
5038 if (fReadOnly)
5039 assert(!"Erase called on database in read-only mode");
5040
5041 // Key
5042 CDataStream ssKey(SER_DISK);
5043 ssKey.reserve(1000);
5044 ssKey << key;
5045 Dbt datKey(&ssKey[0], ssKey.size());
5046
5047 // Erase
5048 int ret = pdb->del(GetTxn(), &datKey, 0);
5049
5050 // Clear memory
5051 memset(datKey.get_data(), 0, datKey.get_size());
5052 return (ret == 0 || ret == DB_NOTFOUND);
5053 }
5054
5055 template<typename K>
5056 bool Exists(const K& key)
5057 {
5058 if (!pdb)
5059 return false;
5060
5061 // Key
5062 CDataStream ssKey(SER_DISK);
5063 ssKey.reserve(1000);
5064 ssKey << key;
5065 Dbt datKey(&ssKey[0], ssKey.size());
5066
5067 // Exists
5068 int ret = pdb->exists(GetTxn(), &datKey, 0);
5069
5070 // Clear memory
5071 memset(datKey.get_data(), 0, datKey.get_size());
5072 return (ret == 0);
5073 }
5074
5075 Dbc* GetCursor()
5076 {
5077 if (!pdb)
5078 return NULL;
5079 Dbc* pcursor = NULL;
5080 int ret = pdb->cursor(NULL, &pcursor, 0);
5081 if (ret != 0)
5082 return NULL;
5083 return pcursor;
5084 }
5085
5086 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
5087 {
5088 // Read at cursor
5089 Dbt datKey;
5090 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
5091 {
5092 datKey.set_data(&ssKey[0]);
5093 datKey.set_size(ssKey.size());
5094 }
5095 Dbt datValue;
5096 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
5097 {
5098 datValue.set_data(&ssValue[0]);
5099 datValue.set_size(ssValue.size());
5100 }
5101 datKey.set_flags(DB_DBT_MALLOC);
5102 datValue.set_flags(DB_DBT_MALLOC);
5103 int ret = pcursor->get(&datKey, &datValue, fFlags);
5104 if (ret != 0)
5105 return ret;
5106 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
5107 return 99999;
5108
5109 // Convert to streams
5110 ssKey.SetType(SER_DISK);
5111 ssKey.clear();
5112 ssKey.write((char*)datKey.get_data(), datKey.get_size());
5113 ssValue.SetType(SER_DISK);
5114 ssValue.clear();
5115 ssValue.write((char*)datValue.get_data(), datValue.get_size());
5116
5117 // Clear and free memory
5118 memset(datKey.get_data(), 0, datKey.get_size());
5119 memset(datValue.get_data(), 0, datValue.get_size());
5120 free(datKey.get_data());
5121 free(datValue.get_data());
5122 return 0;
5123 }
5124
5125 DbTxn* GetTxn()
5126 {
5127 if (!vTxn.empty())
5128 return vTxn.back();
5129 else
5130 return NULL;
5131 }
5132
5133 public:
5134 bool TxnBegin()
5135 {
5136 if (!pdb)
5137 return false;
5138 DbTxn* ptxn = NULL;
5139 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
5140 if (!ptxn || ret != 0)
5141 return false;
5142 vTxn.push_back(ptxn);
5143 return true;
5144 }
5145
5146 bool TxnCommit()
5147 {
5148 if (!pdb)
5149 return false;
5150 if (vTxn.empty())
5151 return false;
5152 int ret = vTxn.back()->commit(0);
5153 vTxn.pop_back();
5154 return (ret == 0);
5155 }
5156
5157 bool TxnAbort()
5158 {
5159 if (!pdb)
5160 return false;
5161 if (vTxn.empty())
5162 return false;
5163 int ret = vTxn.back()->abort();
5164 vTxn.pop_back();
5165 return (ret == 0);
5166 }
5167
5168 bool ReadVersion(int& nVersion)
5169 {
5170 nVersion = 0;
5171 return Read(std::string("version"), nVersion);
5172 }
5173
5174 bool WriteVersion(int nVersion)
5175 {
5176 return Write(std::string("version"), nVersion);
5177 }
5178
5179 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
5180 };
5181
5182
5183
5184
5185
5186
5187
5188
5189 class CTxDB : public CDB
5190 {
5191 public:
5192 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
5193 private:
5194 CTxDB(const CTxDB&);
5195 void operator=(const CTxDB&);
5196 public:
5197 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
5198 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
5199 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
5200 bool EraseTxIndex(const CTransaction& tx);
5201 bool ContainsTx(uint256 hash);
5202 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
5203 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
5204 bool ReadDiskTx(uint256 hash, CTransaction& tx);
5205 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
5206 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
5207 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
5208 bool EraseBlockIndex(uint256 hash);
5209 bool ReadHashBestChain(uint256& hashBestChain);
5210 bool WriteHashBestChain(uint256 hashBestChain);
5211 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
5212 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
5213 bool LoadBlockIndex();
5214 };
5215
5216
5217
5218
5219
5220 class CAddrDB : public CDB
5221 {
5222 public:
5223 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
5224 private:
5225 CAddrDB(const CAddrDB&);
5226 void operator=(const CAddrDB&);
5227 public:
5228 bool WriteAddress(const CAddress& addr);
5229 bool EraseAddress(const CAddress& addr);
5230 bool LoadAddresses();
5231 };
5232
5233 bool LoadAddresses();
5234
5235
5236
5237 class CKeyPool
5238 {
5239 public:
5240 int64 nTime;
5241 std::vector<unsigned char> vchPubKey;
5242
5243 CKeyPool()
5244 {
5245 nTime = GetTime();
5246 }
5247
5248 CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
5249 {
5250 nTime = GetTime();
5251 vchPubKey = vchPubKeyIn;
5252 }
5253
5254 IMPLEMENT_SERIALIZE
5255 (
5256 if (!(nType & SER_GETHASH))
5257 READWRITE(nVersion);
5258 READWRITE(nTime);
5259 READWRITE(vchPubKey);
5260 )
5261 };
5262
5263
5264
5265
5266 enum DBErrors
5267 {
5268 DB_LOAD_OK,
5269 DB_CORRUPT,
5270 DB_TOO_NEW,
5271 DB_LOAD_FAIL,
5272 DB_NEED_REWRITE
5273 };
5274
5275 class CWalletDB : public CDB
5276 {
5277 public:
5278 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
5279 {
5280 }
5281 private:
5282 CWalletDB(const CWalletDB&);
5283 void operator=(const CWalletDB&);
5284 public:
5285 bool ReadName(const std::string& strAddress, std::string& strName)
5286 {
5287 strName = "";
5288 return Read(std::make_pair(std::string("name"), strAddress), strName);
5289 }
5290
5291 bool WriteName(const std::string& strAddress, const std::string& strName);
5292
5293 bool EraseName(const std::string& strAddress);
5294
5295 bool ReadTx(uint256 hash, CWalletTx& wtx)
5296 {
5297 return Read(std::make_pair(std::string("tx"), hash), wtx);
5298 }
5299
5300 bool WriteTx(uint256 hash, const CWalletTx& wtx)
5301 {
5302 nWalletDBUpdated++;
5303 return Write(std::make_pair(std::string("tx"), hash), wtx);
5304 }
5305
5306 bool EraseTx(uint256 hash)
5307 {
5308 nWalletDBUpdated++;
5309 return Erase(std::make_pair(std::string("tx"), hash));
5310 }
5311
5312 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
5313 {
5314 vchPrivKey.clear();
5315 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
5316 }
5317
5318 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
5319 {
5320 nWalletDBUpdated++;
5321 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
5322 }
5323
5324 bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
5325 {
5326 nWalletDBUpdated++;
5327 if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
5328 return false;
5329 if (fEraseUnencryptedKey)
5330 {
5331 Erase(std::make_pair(std::string("key"), vchPubKey));
5332 Erase(std::make_pair(std::string("wkey"), vchPubKey));
5333 }
5334 return true;
5335 }
5336
5337 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
5338 {
5339 nWalletDBUpdated++;
5340 return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
5341 }
5342
5343 bool WriteBestBlock(const CBlockLocator& locator)
5344 {
5345 nWalletDBUpdated++;
5346 return Write(std::string("bestblock"), locator);
5347 }
5348
5349 bool ReadBestBlock(CBlockLocator& locator)
5350 {
5351 return Read(std::string("bestblock"), locator);
5352 }
5353
5354 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
5355 {
5356 vchPubKey.clear();
5357 return Read(std::string("defaultkey"), vchPubKey);
5358 }
5359
5360 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
5361 {
5362 nWalletDBUpdated++;
5363 return Write(std::string("defaultkey"), vchPubKey);
5364 }
5365
5366 bool ReadPool(int64 nPool, CKeyPool& keypool)
5367 {
5368 return Read(std::make_pair(std::string("pool"), nPool), keypool);
5369 }
5370
5371 bool WritePool(int64 nPool, const CKeyPool& keypool)
5372 {
5373 nWalletDBUpdated++;
5374 return Write(std::make_pair(std::string("pool"), nPool), keypool);
5375 }
5376
5377 bool ErasePool(int64 nPool)
5378 {
5379 nWalletDBUpdated++;
5380 return Erase(std::make_pair(std::string("pool"), nPool));
5381 }
5382
5383 template<typename T>
5384 bool ReadSetting(const std::string& strKey, T& value)
5385 {
5386 return Read(std::make_pair(std::string("setting"), strKey), value);
5387 }
5388
5389 template<typename T>
5390 bool WriteSetting(const std::string& strKey, const T& value)
5391 {
5392 nWalletDBUpdated++;
5393 return Write(std::make_pair(std::string("setting"), strKey), value);
5394 }
5395
5396 bool ReadAccount(const std::string& strAccount, CAccount& account);
5397 bool WriteAccount(const std::string& strAccount, const CAccount& account);
5398 bool WriteAccountingEntry(const CAccountingEntry& acentry);
5399 int64 GetAccountCreditDebit(const std::string& strAccount);
5400 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
5401
5402 int LoadWallet(CWallet* pwallet);
5403 };
5404
5405 #endif