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