-
+ F524EDC3DF4CA4138F1D67BC56781A739539FF466B381B82C517C5B3DD4176EAD8436A3910E7D338B384694398B83EB95179465998B7345ADADAE1EF0158D516
bitcoin/src/db.h
(0 . 0)(1 . 516)
5262 // /****************************\
5263 // * EXPERIMENTAL BRANCH. *
5264 // * FOR LABORATORY USE ONLY. *
5265 // ********************************
5266 // ************
5267 // **************
5268 // ****************
5269 // **** **** ****
5270 // *** *** ***
5271 // *** *** ***
5272 // *** * * **
5273 // ******** ********
5274 // ******* ******
5275 // *** **
5276 // * ******* **
5277 // ** * * * * *
5278 // ** * * ***
5279 // **** * * * * ****
5280 // **** *** * * ** ***
5281 // **** ********* ******
5282 // ******* ***** *******
5283 // ********* ****** **
5284 // ** ****** ******
5285 // ** ******* **
5286 // ** ******* ***
5287 // **** ******** ************
5288 // ************ ************
5289 // ******** *******
5290 // ****** ****
5291 // *** ***
5292 // ********************************
5293 // Copyright (c) 2009-2010 Satoshi Nakamoto
5294 // Copyright (c) 2011 The Bitcoin developers
5295 // Distributed under the MIT/X11 software license, see the accompanying
5296 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
5297 #ifndef BITCOIN_DB_H
5298 #define BITCOIN_DB_H
5299
5300 #include "key.h"
5301
5302 #include <map>
5303 #include <string>
5304 #include <vector>
5305
5306 #include <db_cxx.h>
5307
5308 class CTxIndex;
5309 class CDiskBlockIndex;
5310 class CDiskTxPos;
5311 class COutPoint;
5312 class CAddress;
5313 class CWalletTx;
5314 class CWallet;
5315 class CAccount;
5316 class CAccountingEntry;
5317 class CBlockLocator;
5318
5319
5320 extern unsigned int nWalletDBUpdated;
5321 extern DbEnv dbenv;
5322
5323 extern void DBFlush(bool fShutdown);
5324 void ThreadFlushWalletDB(void* parg);
5325 bool BackupWallet(const CWallet& wallet, const std::string& strDest);
5326
5327
5328
5329 class CDB
5330 {
5331 protected:
5332 Db* pdb;
5333 std::string strFile;
5334 std::vector<DbTxn*> vTxn;
5335 bool fReadOnly;
5336
5337 explicit CDB(const char* pszFile, const char* pszMode="r+");
5338 ~CDB() { Close(); }
5339 public:
5340 void Close();
5341 private:
5342 CDB(const CDB&);
5343 void operator=(const CDB&);
5344
5345 protected:
5346 template<typename K, typename T>
5347 bool Read(const K& key, T& value)
5348 {
5349 if (!pdb)
5350 return false;
5351
5352 // Key
5353 CDataStream ssKey(SER_DISK);
5354 ssKey.reserve(1000);
5355 ssKey << key;
5356 Dbt datKey(&ssKey[0], ssKey.size());
5357
5358 // Read
5359 Dbt datValue;
5360 datValue.set_flags(DB_DBT_MALLOC);
5361 int ret = pdb->get(GetTxn(), &datKey, &datValue, 0);
5362 memset(datKey.get_data(), 0, datKey.get_size());
5363 if (datValue.get_data() == NULL)
5364 return false;
5365
5366 // Unserialize value
5367 CDataStream ssValue((char*)datValue.get_data(), (char*)datValue.get_data() + datValue.get_size(), SER_DISK);
5368 ssValue >> value;
5369
5370 // Clear and free memory
5371 memset(datValue.get_data(), 0, datValue.get_size());
5372 free(datValue.get_data());
5373 return (ret == 0);
5374 }
5375
5376 template<typename K, typename T>
5377 bool Write(const K& key, const T& value, bool fOverwrite=true)
5378 {
5379 if (!pdb)
5380 return false;
5381 if (fReadOnly)
5382 assert(!"Write called on database in read-only mode");
5383
5384 // Key
5385 CDataStream ssKey(SER_DISK);
5386 ssKey.reserve(1000);
5387 ssKey << key;
5388 Dbt datKey(&ssKey[0], ssKey.size());
5389
5390 // Value
5391 CDataStream ssValue(SER_DISK);
5392 ssValue.reserve(10000);
5393 ssValue << value;
5394 Dbt datValue(&ssValue[0], ssValue.size());
5395
5396 // Write
5397 int ret = pdb->put(GetTxn(), &datKey, &datValue, (fOverwrite ? 0 : DB_NOOVERWRITE));
5398
5399 // Clear memory in case it was a private key
5400 memset(datKey.get_data(), 0, datKey.get_size());
5401 memset(datValue.get_data(), 0, datValue.get_size());
5402 return (ret == 0);
5403 }
5404
5405 template<typename K>
5406 bool Erase(const K& key)
5407 {
5408 if (!pdb)
5409 return false;
5410 if (fReadOnly)
5411 assert(!"Erase called on database in read-only mode");
5412
5413 // Key
5414 CDataStream ssKey(SER_DISK);
5415 ssKey.reserve(1000);
5416 ssKey << key;
5417 Dbt datKey(&ssKey[0], ssKey.size());
5418
5419 // Erase
5420 int ret = pdb->del(GetTxn(), &datKey, 0);
5421
5422 // Clear memory
5423 memset(datKey.get_data(), 0, datKey.get_size());
5424 return (ret == 0 || ret == DB_NOTFOUND);
5425 }
5426
5427 template<typename K>
5428 bool Exists(const K& key)
5429 {
5430 if (!pdb)
5431 return false;
5432
5433 // Key
5434 CDataStream ssKey(SER_DISK);
5435 ssKey.reserve(1000);
5436 ssKey << key;
5437 Dbt datKey(&ssKey[0], ssKey.size());
5438
5439 // Exists
5440 int ret = pdb->exists(GetTxn(), &datKey, 0);
5441
5442 // Clear memory
5443 memset(datKey.get_data(), 0, datKey.get_size());
5444 return (ret == 0);
5445 }
5446
5447 Dbc* GetCursor()
5448 {
5449 if (!pdb)
5450 return NULL;
5451 Dbc* pcursor = NULL;
5452 int ret = pdb->cursor(NULL, &pcursor, 0);
5453 if (ret != 0)
5454 return NULL;
5455 return pcursor;
5456 }
5457
5458 int ReadAtCursor(Dbc* pcursor, CDataStream& ssKey, CDataStream& ssValue, unsigned int fFlags=DB_NEXT)
5459 {
5460 // Read at cursor
5461 Dbt datKey;
5462 if (fFlags == DB_SET || fFlags == DB_SET_RANGE || fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
5463 {
5464 datKey.set_data(&ssKey[0]);
5465 datKey.set_size(ssKey.size());
5466 }
5467 Dbt datValue;
5468 if (fFlags == DB_GET_BOTH || fFlags == DB_GET_BOTH_RANGE)
5469 {
5470 datValue.set_data(&ssValue[0]);
5471 datValue.set_size(ssValue.size());
5472 }
5473 datKey.set_flags(DB_DBT_MALLOC);
5474 datValue.set_flags(DB_DBT_MALLOC);
5475 int ret = pcursor->get(&datKey, &datValue, fFlags);
5476 if (ret != 0)
5477 return ret;
5478 else if (datKey.get_data() == NULL || datValue.get_data() == NULL)
5479 return 99999;
5480
5481 // Convert to streams
5482 ssKey.SetType(SER_DISK);
5483 ssKey.clear();
5484 ssKey.write((char*)datKey.get_data(), datKey.get_size());
5485 ssValue.SetType(SER_DISK);
5486 ssValue.clear();
5487 ssValue.write((char*)datValue.get_data(), datValue.get_size());
5488
5489 // Clear and free memory
5490 memset(datKey.get_data(), 0, datKey.get_size());
5491 memset(datValue.get_data(), 0, datValue.get_size());
5492 free(datKey.get_data());
5493 free(datValue.get_data());
5494 return 0;
5495 }
5496
5497 DbTxn* GetTxn()
5498 {
5499 if (!vTxn.empty())
5500 return vTxn.back();
5501 else
5502 return NULL;
5503 }
5504
5505 public:
5506 bool TxnBegin()
5507 {
5508 if (!pdb)
5509 return false;
5510 DbTxn* ptxn = NULL;
5511 int ret = dbenv.txn_begin(GetTxn(), &ptxn, DB_TXN_NOSYNC);
5512 if (!ptxn || ret != 0)
5513 return false;
5514 vTxn.push_back(ptxn);
5515 return true;
5516 }
5517
5518 bool TxnCommit()
5519 {
5520 if (!pdb)
5521 return false;
5522 if (vTxn.empty())
5523 return false;
5524 int ret = vTxn.back()->commit(0);
5525 vTxn.pop_back();
5526 return (ret == 0);
5527 }
5528
5529 bool TxnAbort()
5530 {
5531 if (!pdb)
5532 return false;
5533 if (vTxn.empty())
5534 return false;
5535 int ret = vTxn.back()->abort();
5536 vTxn.pop_back();
5537 return (ret == 0);
5538 }
5539
5540 bool ReadVersion(int& nVersion)
5541 {
5542 nVersion = 0;
5543 return Read(std::string("version"), nVersion);
5544 }
5545
5546 bool WriteVersion(int nVersion)
5547 {
5548 return Write(std::string("version"), nVersion);
5549 }
5550
5551 bool static Rewrite(const std::string& strFile, const char* pszSkip = NULL);
5552 };
5553
5554
5555
5556
5557
5558
5559
5560
5561 class CTxDB : public CDB
5562 {
5563 public:
5564 CTxDB(const char* pszMode="r+") : CDB("blkindex.dat", pszMode) { }
5565 private:
5566 CTxDB(const CTxDB&);
5567 void operator=(const CTxDB&);
5568 public:
5569 bool ReadTxIndex(uint256 hash, CTxIndex& txindex);
5570 bool UpdateTxIndex(uint256 hash, const CTxIndex& txindex);
5571 bool AddTxIndex(const CTransaction& tx, const CDiskTxPos& pos, int nHeight);
5572 bool EraseTxIndex(const CTransaction& tx);
5573 bool ContainsTx(uint256 hash);
5574 bool ReadOwnerTxes(uint160 hash160, int nHeight, std::vector<CTransaction>& vtx);
5575 bool ReadDiskTx(uint256 hash, CTransaction& tx, CTxIndex& txindex);
5576 bool ReadDiskTx(uint256 hash, CTransaction& tx);
5577 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx, CTxIndex& txindex);
5578 bool ReadDiskTx(COutPoint outpoint, CTransaction& tx);
5579 bool WriteBlockIndex(const CDiskBlockIndex& blockindex);
5580 bool EraseBlockIndex(uint256 hash);
5581 bool ReadHashBestChain(uint256& hashBestChain);
5582 bool WriteHashBestChain(uint256 hashBestChain);
5583 bool ReadBestInvalidWork(CBigNum& bnBestInvalidWork);
5584 bool WriteBestInvalidWork(CBigNum bnBestInvalidWork);
5585 bool LoadBlockIndex();
5586 };
5587
5588
5589
5590
5591
5592 class CAddrDB : public CDB
5593 {
5594 public:
5595 CAddrDB(const char* pszMode="r+") : CDB("addr.dat", pszMode) { }
5596 private:
5597 CAddrDB(const CAddrDB&);
5598 void operator=(const CAddrDB&);
5599 public:
5600 bool WriteAddress(const CAddress& addr);
5601 bool EraseAddress(const CAddress& addr);
5602 bool LoadAddresses();
5603 };
5604
5605 bool LoadAddresses();
5606
5607
5608
5609 class CKeyPool
5610 {
5611 public:
5612 int64 nTime;
5613 std::vector<unsigned char> vchPubKey;
5614
5615 CKeyPool()
5616 {
5617 nTime = GetTime();
5618 }
5619
5620 CKeyPool(const std::vector<unsigned char>& vchPubKeyIn)
5621 {
5622 nTime = GetTime();
5623 vchPubKey = vchPubKeyIn;
5624 }
5625
5626 IMPLEMENT_SERIALIZE
5627 (
5628 if (!(nType & SER_GETHASH))
5629 READWRITE(nVersion);
5630 READWRITE(nTime);
5631 READWRITE(vchPubKey);
5632 )
5633 };
5634
5635
5636
5637
5638 enum DBErrors
5639 {
5640 DB_LOAD_OK,
5641 DB_CORRUPT,
5642 DB_TOO_NEW,
5643 DB_LOAD_FAIL,
5644 DB_NEED_REWRITE
5645 };
5646
5647 class CWalletDB : public CDB
5648 {
5649 public:
5650 CWalletDB(std::string strFilename, const char* pszMode="r+") : CDB(strFilename.c_str(), pszMode)
5651 {
5652 }
5653 private:
5654 CWalletDB(const CWalletDB&);
5655 void operator=(const CWalletDB&);
5656 public:
5657 bool ReadName(const std::string& strAddress, std::string& strName)
5658 {
5659 strName = "";
5660 return Read(std::make_pair(std::string("name"), strAddress), strName);
5661 }
5662
5663 bool WriteName(const std::string& strAddress, const std::string& strName);
5664
5665 bool EraseName(const std::string& strAddress);
5666
5667 bool ReadTx(uint256 hash, CWalletTx& wtx)
5668 {
5669 return Read(std::make_pair(std::string("tx"), hash), wtx);
5670 }
5671
5672 bool WriteTx(uint256 hash, const CWalletTx& wtx)
5673 {
5674 nWalletDBUpdated++;
5675 return Write(std::make_pair(std::string("tx"), hash), wtx);
5676 }
5677
5678 bool EraseTx(uint256 hash)
5679 {
5680 nWalletDBUpdated++;
5681 return Erase(std::make_pair(std::string("tx"), hash));
5682 }
5683
5684 bool ReadKey(const std::vector<unsigned char>& vchPubKey, CPrivKey& vchPrivKey)
5685 {
5686 vchPrivKey.clear();
5687 return Read(std::make_pair(std::string("key"), vchPubKey), vchPrivKey);
5688 }
5689
5690 bool WriteKey(const std::vector<unsigned char>& vchPubKey, const CPrivKey& vchPrivKey)
5691 {
5692 nWalletDBUpdated++;
5693 return Write(std::make_pair(std::string("key"), vchPubKey), vchPrivKey, false);
5694 }
5695
5696 bool WriteCryptedKey(const std::vector<unsigned char>& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, bool fEraseUnencryptedKey = true)
5697 {
5698 nWalletDBUpdated++;
5699 if (!Write(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false))
5700 return false;
5701 if (fEraseUnencryptedKey)
5702 {
5703 Erase(std::make_pair(std::string("key"), vchPubKey));
5704 Erase(std::make_pair(std::string("wkey"), vchPubKey));
5705 }
5706 return true;
5707 }
5708
5709 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
5710 {
5711 nWalletDBUpdated++;
5712 return Write(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
5713 }
5714
5715 bool WriteBestBlock(const CBlockLocator& locator)
5716 {
5717 nWalletDBUpdated++;
5718 return Write(std::string("bestblock"), locator);
5719 }
5720
5721 bool ReadBestBlock(CBlockLocator& locator)
5722 {
5723 return Read(std::string("bestblock"), locator);
5724 }
5725
5726 bool ReadDefaultKey(std::vector<unsigned char>& vchPubKey)
5727 {
5728 vchPubKey.clear();
5729 return Read(std::string("defaultkey"), vchPubKey);
5730 }
5731
5732 bool WriteDefaultKey(const std::vector<unsigned char>& vchPubKey)
5733 {
5734 nWalletDBUpdated++;
5735 return Write(std::string("defaultkey"), vchPubKey);
5736 }
5737
5738 bool ReadPool(int64 nPool, CKeyPool& keypool)
5739 {
5740 return Read(std::make_pair(std::string("pool"), nPool), keypool);
5741 }
5742
5743 bool WritePool(int64 nPool, const CKeyPool& keypool)
5744 {
5745 nWalletDBUpdated++;
5746 return Write(std::make_pair(std::string("pool"), nPool), keypool);
5747 }
5748
5749 bool ErasePool(int64 nPool)
5750 {
5751 nWalletDBUpdated++;
5752 return Erase(std::make_pair(std::string("pool"), nPool));
5753 }
5754
5755 template<typename T>
5756 bool ReadSetting(const std::string& strKey, T& value)
5757 {
5758 return Read(std::make_pair(std::string("setting"), strKey), value);
5759 }
5760
5761 template<typename T>
5762 bool WriteSetting(const std::string& strKey, const T& value)
5763 {
5764 nWalletDBUpdated++;
5765 return Write(std::make_pair(std::string("setting"), strKey), value);
5766 }
5767
5768 bool ReadAccount(const std::string& strAccount, CAccount& account);
5769 bool WriteAccount(const std::string& strAccount, const CAccount& account);
5770 bool WriteAccountingEntry(const CAccountingEntry& acentry);
5771 int64 GetAccountCreditDebit(const std::string& strAccount);
5772 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries);
5773
5774 int LoadWallet(CWallet* pwallet);
5775 };
5776
5777 #endif