1 // Copyright (c) 2009-2010 Satoshi Nakamoto 2 // Copyright (c) 2009-2015 The Bitcoin Core developers 3 // Distributed under the MIT software license, see the accompanying 4 // file COPYING or http://www.opensource.org/licenses/mit-license.php. 5 6 #ifndef BITCOIN_WALLET_WALLETDB_H 7 #define BITCOIN_WALLET_WALLETDB_H 8 9 #include "amount.h" 10 #include "primitives/transaction.h" 11 #include "wallet/db.h" 12 #include "key.h" 13 14 #include <list> 15 #include <stdint.h> 16 #include <string> 17 #include <utility> 18 #include <vector> 19 20 static const bool DEFAULT_FLUSHWALLET = true; 21 22 class CAccount; 23 class CAccountingEntry; 24 struct CBlockLocator; 25 class CKeyPool; 26 class CMasterKey; 27 class CScript; 28 class CWallet; 29 class CWalletTx; 30 class uint160; 31 class uint256; 32 33 /** Error statuses for the wallet database */ 34 enum DBErrors 35 { 36 DB_LOAD_OK, 37 DB_CORRUPT, 38 DB_NONCRITICAL_ERROR, 39 DB_TOO_NEW, 40 DB_LOAD_FAIL, 41 DB_NEED_REWRITE 42 }; 43 44 /* simple HD chain data model */ 45 class CHDChain 46 { 47 public: 48 uint32_t nExternalChainCounter; 49 CKeyID masterKeyID; //!< master key hash160 50 51 static const int CURRENT_VERSION = 1; 52 int nVersion; 53 CHDChain()54 CHDChain() { SetNull(); } 55 ADD_SERIALIZE_METHODS; 56 template <typename Stream, typename Operation> SerializationOp(Stream & s,Operation ser_action,int nType,int nVersion)57 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) 58 { 59 READWRITE(this->nVersion); 60 nVersion = this->nVersion; 61 READWRITE(nExternalChainCounter); 62 READWRITE(masterKeyID); 63 } 64 SetNull()65 void SetNull() 66 { 67 nVersion = CHDChain::CURRENT_VERSION; 68 nExternalChainCounter = 0; 69 masterKeyID.SetNull(); 70 } 71 }; 72 73 class CKeyMetadata 74 { 75 public: 76 static const int VERSION_BASIC=1; 77 static const int VERSION_WITH_HDDATA=10; 78 static const int CURRENT_VERSION=VERSION_WITH_HDDATA; 79 int nVersion; 80 int64_t nCreateTime; // 0 means unknown 81 std::string hdKeypath; //optional HD/bip32 keypath 82 CKeyID hdMasterKeyID; //id of the HD masterkey used to derive this key 83 CKeyMetadata()84 CKeyMetadata() 85 { 86 SetNull(); 87 } CKeyMetadata(int64_t nCreateTime_)88 CKeyMetadata(int64_t nCreateTime_) 89 { 90 SetNull(); 91 nCreateTime = nCreateTime_; 92 } 93 94 ADD_SERIALIZE_METHODS; 95 96 template <typename Stream, typename Operation> SerializationOp(Stream & s,Operation ser_action,int nType,int nVersion)97 inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) { 98 READWRITE(this->nVersion); 99 nVersion = this->nVersion; 100 READWRITE(nCreateTime); 101 if (this->nVersion >= VERSION_WITH_HDDATA) 102 { 103 READWRITE(hdKeypath); 104 READWRITE(hdMasterKeyID); 105 } 106 } 107 SetNull()108 void SetNull() 109 { 110 nVersion = CKeyMetadata::CURRENT_VERSION; 111 nCreateTime = 0; 112 hdKeypath.clear(); 113 hdMasterKeyID.SetNull(); 114 } 115 }; 116 117 /** Access to the wallet database */ 118 class CWalletDB : public CDB 119 { 120 public: CDB(strFilename,pszMode,fFlushOnClose)121 CWalletDB(const std::string& strFilename, const char* pszMode = "r+", bool fFlushOnClose = true) : CDB(strFilename, pszMode, fFlushOnClose) 122 { 123 } 124 125 bool WriteName(const std::string& strAddress, const std::string& strName); 126 bool EraseName(const std::string& strAddress); 127 128 bool WritePurpose(const std::string& strAddress, const std::string& purpose); 129 bool ErasePurpose(const std::string& strAddress); 130 131 bool WriteTx(const CWalletTx& wtx); 132 bool EraseTx(uint256 hash); 133 134 bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta); 135 bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta); 136 bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey); 137 138 bool WriteCScript(const uint160& hash, const CScript& redeemScript); 139 140 bool WriteWatchOnly(const CScript &script); 141 bool EraseWatchOnly(const CScript &script); 142 143 bool WriteBestBlock(const CBlockLocator& locator); 144 bool ReadBestBlock(CBlockLocator& locator); 145 146 bool WriteOrderPosNext(int64_t nOrderPosNext); 147 148 bool WriteDefaultKey(const CPubKey& vchPubKey); 149 150 bool ReadPool(int64_t nPool, CKeyPool& keypool); 151 bool WritePool(int64_t nPool, const CKeyPool& keypool); 152 bool ErasePool(int64_t nPool); 153 154 bool WriteMinVersion(int nVersion); 155 156 /// This writes directly to the database, and will not update the CWallet's cached accounting entries! 157 /// Use wallet.AddAccountingEntry instead, to write *and* update its caches. 158 bool WriteAccountingEntry_Backend(const CAccountingEntry& acentry); 159 bool ReadAccount(const std::string& strAccount, CAccount& account); 160 bool WriteAccount(const std::string& strAccount, const CAccount& account); 161 162 /// Write destination data key,value tuple to database 163 bool WriteDestData(const std::string &address, const std::string &key, const std::string &value); 164 /// Erase destination data tuple from wallet database 165 bool EraseDestData(const std::string &address, const std::string &key); 166 167 CAmount GetAccountCreditDebit(const std::string& strAccount); 168 void ListAccountCreditDebit(const std::string& strAccount, std::list<CAccountingEntry>& acentries); 169 170 DBErrors ReorderTransactions(CWallet* pwallet); 171 DBErrors LoadWallet(CWallet* pwallet); 172 DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx); 173 DBErrors ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx); 174 DBErrors ZapSelectTx(CWallet* pwallet, std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut); 175 static bool Recover(CDBEnv& dbenv, const std::string& filename, bool fOnlyKeys); 176 static bool Recover(CDBEnv& dbenv, const std::string& filename); 177 178 //! write the hdchain model (external chain child index counter) 179 bool WriteHDChain(const CHDChain& chain); 180 181 private: 182 CWalletDB(const CWalletDB&); 183 void operator=(const CWalletDB&); 184 185 bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry& acentry); 186 }; 187 188 void ThreadFlushWalletDB(const std::string& strFile); 189 190 #endif // BITCOIN_WALLET_WALLETDB_H 191