1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 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.
6 #ifndef BITCOIN_WALLET_WALLETDB_H
7 #define BITCOIN_WALLET_WALLETDB_H
10 #include "primitives/transaction.h"
11 #include "wallet/db.h"
21 * Overview of wallet database classes:
23 * - CDBEnv is an environment in which the database exists (has no analog in dbwrapper.h)
24 * - CWalletDBWrapper represents a wallet database (similar to CDBWrapper in dbwrapper.h)
25 * - CDB is a low-level database transaction (similar to CDBBatch in dbwrapper.h)
26 * - CWalletDB is a modifier object for the wallet, and encapsulates a database
27 * transaction as well as methods to act on the database (no analog in
30 * The latter two are named confusingly, in contrast to what the names CDB
31 * and CWalletDB suggest they are transient transaction objects and don't
32 * represent the database itself.
35 static const bool DEFAULT_FLUSHWALLET
= true;
38 class CAccountingEntry
;
48 /** Error statuses for the wallet database */
59 /* simple HD chain data model */
63 uint32_t nExternalChainCounter
;
64 uint32_t nInternalChainCounter
;
65 CKeyID masterKeyID
; //!< master key hash160
67 static const int VERSION_HD_BASE
= 1;
68 static const int VERSION_HD_CHAIN_SPLIT
= 2;
69 static const int CURRENT_VERSION
= VERSION_HD_CHAIN_SPLIT
;
72 CHDChain() { SetNull(); }
73 ADD_SERIALIZE_METHODS
;
74 template <typename Stream
, typename Operation
>
75 inline void SerializationOp(Stream
& s
, Operation ser_action
)
77 READWRITE(this->nVersion
);
78 READWRITE(nExternalChainCounter
);
79 READWRITE(masterKeyID
);
80 if (this->nVersion
>= VERSION_HD_CHAIN_SPLIT
)
81 READWRITE(nInternalChainCounter
);
86 nVersion
= CHDChain::CURRENT_VERSION
;
87 nExternalChainCounter
= 0;
88 nInternalChainCounter
= 0;
89 masterKeyID
.SetNull();
96 static const int VERSION_BASIC
=1;
97 static const int VERSION_WITH_HDDATA
=10;
98 static const int CURRENT_VERSION
=VERSION_WITH_HDDATA
;
100 int64_t nCreateTime
; // 0 means unknown
101 std::string hdKeypath
; //optional HD/bip32 keypath
102 CKeyID hdMasterKeyID
; //id of the HD masterkey used to derive this key
108 explicit CKeyMetadata(int64_t nCreateTime_
)
111 nCreateTime
= nCreateTime_
;
114 ADD_SERIALIZE_METHODS
;
116 template <typename Stream
, typename Operation
>
117 inline void SerializationOp(Stream
& s
, Operation ser_action
) {
118 READWRITE(this->nVersion
);
119 READWRITE(nCreateTime
);
120 if (this->nVersion
>= VERSION_WITH_HDDATA
)
122 READWRITE(hdKeypath
);
123 READWRITE(hdMasterKeyID
);
129 nVersion
= CKeyMetadata::CURRENT_VERSION
;
132 hdMasterKeyID
.SetNull();
136 /** Access to the wallet database.
137 * This should really be named CWalletDBBatch, as it represents a single transaction at the
138 * database. It will be committed when the object goes out of scope.
139 * Optionally (on by default) it will flush to disk as well.
144 template <typename K
, typename T
>
145 bool WriteIC(const K
& key
, const T
& value
, bool fOverwrite
= true)
147 if (!batch
.Write(key
, value
, fOverwrite
)) {
150 m_dbw
.IncrementUpdateCounter();
154 template <typename K
>
155 bool EraseIC(const K
& key
)
157 if (!batch
.Erase(key
)) {
160 m_dbw
.IncrementUpdateCounter();
165 explicit CWalletDB(CWalletDBWrapper
& dbw
, const char* pszMode
= "r+", bool _fFlushOnClose
= true) :
166 batch(dbw
, pszMode
, _fFlushOnClose
),
171 bool WriteName(const std::string
& strAddress
, const std::string
& strName
);
172 bool EraseName(const std::string
& strAddress
);
174 bool WritePurpose(const std::string
& strAddress
, const std::string
& purpose
);
175 bool ErasePurpose(const std::string
& strAddress
);
177 bool WriteTx(const CWalletTx
& wtx
);
178 bool EraseTx(uint256 hash
);
180 bool WriteKey(const CPubKey
& vchPubKey
, const CPrivKey
& vchPrivKey
, const CKeyMetadata
&keyMeta
);
181 bool WriteCryptedKey(const CPubKey
& vchPubKey
, const std::vector
<unsigned char>& vchCryptedSecret
, const CKeyMetadata
&keyMeta
);
182 bool WriteMasterKey(unsigned int nID
, const CMasterKey
& kMasterKey
);
184 bool WriteCScript(const uint160
& hash
, const CScript
& redeemScript
);
186 bool WriteWatchOnly(const CScript
&script
, const CKeyMetadata
&keymeta
);
187 bool EraseWatchOnly(const CScript
&script
);
189 bool WriteBestBlock(const CBlockLocator
& locator
);
190 bool ReadBestBlock(CBlockLocator
& locator
);
192 bool WriteOrderPosNext(int64_t nOrderPosNext
);
194 bool WriteDefaultKey(const CPubKey
& vchPubKey
);
196 bool ReadPool(int64_t nPool
, CKeyPool
& keypool
);
197 bool WritePool(int64_t nPool
, const CKeyPool
& keypool
);
198 bool ErasePool(int64_t nPool
);
200 bool WriteMinVersion(int nVersion
);
202 /// This writes directly to the database, and will not update the CWallet's cached accounting entries!
203 /// Use wallet.AddAccountingEntry instead, to write *and* update its caches.
204 bool WriteAccountingEntry(const uint64_t nAccEntryNum
, const CAccountingEntry
& acentry
);
205 bool ReadAccount(const std::string
& strAccount
, CAccount
& account
);
206 bool WriteAccount(const std::string
& strAccount
, const CAccount
& account
);
208 /// Write destination data key,value tuple to database
209 bool WriteDestData(const std::string
&address
, const std::string
&key
, const std::string
&value
);
210 /// Erase destination data tuple from wallet database
211 bool EraseDestData(const std::string
&address
, const std::string
&key
);
213 CAmount
GetAccountCreditDebit(const std::string
& strAccount
);
214 void ListAccountCreditDebit(const std::string
& strAccount
, std::list
<CAccountingEntry
>& acentries
);
216 DBErrors
LoadWallet(CWallet
* pwallet
);
217 DBErrors
FindWalletTx(std::vector
<uint256
>& vTxHash
, std::vector
<CWalletTx
>& vWtx
);
218 DBErrors
ZapWalletTx(std::vector
<CWalletTx
>& vWtx
);
219 DBErrors
ZapSelectTx(std::vector
<uint256
>& vHashIn
, std::vector
<uint256
>& vHashOut
);
220 /* Try to (very carefully!) recover wallet database (with a possible key type filter) */
221 static bool Recover(const std::string
& filename
, void *callbackDataIn
, bool (*recoverKVcallback
)(void* callbackData
, CDataStream ssKey
, CDataStream ssValue
), std::string
& out_backup_filename
);
222 /* Recover convenience-function to bypass the key filter callback, called when verify fails, recovers everything */
223 static bool Recover(const std::string
& filename
, std::string
& out_backup_filename
);
224 /* Recover filter (used as callback), will only let keys (cryptographical keys) as KV/key-type pass through */
225 static bool RecoverKeysOnlyFilter(void *callbackData
, CDataStream ssKey
, CDataStream ssValue
);
226 /* Function to determine if a certain KV/key-type is a key (cryptographical key) type */
227 static bool IsKeyType(const std::string
& strType
);
228 /* verifies the database environment */
229 static bool VerifyEnvironment(const std::string
& walletFile
, const fs::path
& dataDir
, std::string
& errorStr
);
230 /* verifies the database file */
231 static bool VerifyDatabaseFile(const std::string
& walletFile
, const fs::path
& dataDir
, std::string
& warningStr
, std::string
& errorStr
);
233 //! write the hdchain model (external chain child index counter)
234 bool WriteHDChain(const CHDChain
& chain
);
236 //! Begin a new transaction
238 //! Commit current transaction
240 //! Abort current transaction
242 //! Read wallet version
243 bool ReadVersion(int& nVersion
);
244 //! Write wallet version
245 bool WriteVersion(int nVersion
);
248 CWalletDBWrapper
& m_dbw
;
250 CWalletDB(const CWalletDB
&);
251 void operator=(const CWalletDB
&);
254 //! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
255 void MaybeCompactWalletDB();
257 #endif // BITCOIN_WALLET_WALLETDB_H