Line data Source code
1 : // Copyright (c) 2009-2010 Satoshi Nakamoto
2 : // Copyright (c) 2009-2021 The Bitcoin developers
3 : // Copyright (c) 2016-2021 The PIVX Core developers
4 : // Distributed under the MIT/X11 software license, see the accompanying
5 : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 :
7 : #ifndef PIVX_WALLET_WALLETDB_H
8 : #define PIVX_WALLET_WALLETDB_H
9 :
10 : #include "amount.h"
11 : #include "wallet/db.h"
12 : #include "wallet/hdchain.h"
13 : #include "key.h"
14 : #include "keystore.h"
15 : #include "script/keyorigin.h"
16 :
17 : #include <list>
18 : #include <stdint.h>
19 : #include <string>
20 : #include <utility>
21 : #include <vector>
22 :
23 : /**
24 : * Overview of wallet database classes:
25 : *
26 : * - WalletBatch is an abstract modifier object for the wallet database, and encapsulates a database
27 : * batch update as well as methods to act on the database. It should be agnostic to the database implementation.
28 : *
29 : * The following classes are implementation specific:
30 : * - BerkeleyEnvironment is an environment in which the database exists.
31 : * - BerkeleyDatabase represents a wallet database.
32 : * - BerkeleyBatch is a low-level database batch update.
33 : */
34 :
35 : static const bool DEFAULT_FLUSHWALLET = true;
36 :
37 : struct CBlockLocator;
38 : class CKeyPool;
39 : class CMasterKey;
40 : class CScript;
41 : class CWallet;
42 : class CWalletTx;
43 : class uint160;
44 : class uint256;
45 :
46 : /** Backend-agnostic database type. */
47 : using WalletDatabase = BerkeleyDatabase;
48 :
49 : /** Error statuses for the wallet database */
50 : enum DBErrors {
51 : DB_LOAD_OK,
52 : DB_CORRUPT,
53 : DB_NONCRITICAL_ERROR,
54 : DB_TOO_NEW,
55 : DB_LOAD_FAIL,
56 : DB_NEED_REWRITE
57 : };
58 :
59 89785 : class CKeyMetadata
60 : {
61 : public:
62 : // Metadata versions
63 : static const int VERSION_BASIC = 1;
64 : static const int VERSION_WITH_KEY_ORIGIN = 12;
65 : // Active version
66 : static const int CURRENT_VERSION = VERSION_WITH_KEY_ORIGIN;
67 :
68 : int nVersion;
69 : int64_t nCreateTime; // 0 means unknown
70 : CKeyID hd_seed_id; //id of the HD seed used to derive this key
71 : KeyOriginInfo key_origin; // Key origin info with path and fingerprint
72 :
73 31949 : CKeyMetadata()
74 63898 : {
75 31949 : SetNull();
76 : }
77 :
78 16312 : explicit CKeyMetadata(int64_t nCreateTime_)
79 32624 : {
80 16312 : SetNull();
81 16312 : nCreateTime = nCreateTime_;
82 : }
83 :
84 48780 : SERIALIZE_METHODS(CKeyMetadata, obj)
85 : {
86 24390 : READWRITE(obj.nVersion, obj.nCreateTime);
87 24390 : if (obj.HasKeyOrigin()) {
88 24147 : READWRITE(obj.hd_seed_id, obj.key_origin);
89 : }
90 24390 : }
91 :
92 48261 : void SetNull()
93 : {
94 48261 : nVersion = CKeyMetadata::CURRENT_VERSION;
95 48261 : nCreateTime = 0;
96 48261 : hd_seed_id.SetNull();
97 48261 : key_origin.clear();
98 48261 : }
99 :
100 28868 : bool HasKeyOrigin() const
101 : {
102 28868 : return this->nVersion >= VERSION_WITH_KEY_ORIGIN;
103 : }
104 : };
105 :
106 : /** Access to the wallet database.
107 : * This represents a single transaction at the
108 : * database. It will be committed when the object goes out of scope.
109 : * Optionally (on by default) it will flush to disk as well.
110 : */
111 443966 : class WalletBatch
112 : {
113 : private:
114 : template <typename K, typename T>
115 521608 : bool WriteIC(const K& key, const T& value, bool fOverwrite = true)
116 : {
117 521608 : if (!m_batch.Write(key, value, fOverwrite)) {
118 : return false;
119 : }
120 521608 : m_database.IncrementUpdateCounter();
121 521608 : return true;
122 : }
123 :
124 : template <typename K>
125 9281 : bool EraseIC(const K& key)
126 : {
127 9281 : if (!m_batch.Erase(key)) {
128 : return false;
129 : }
130 9281 : m_database.IncrementUpdateCounter();
131 9281 : return true;
132 : }
133 :
134 : public:
135 443967 : explicit WalletBatch(WalletDatabase& database, const char* pszMode = "r+", bool _fFlushOnClose = true) :
136 : m_batch(database, pszMode, _fFlushOnClose),
137 443967 : m_database(database)
138 : {
139 47 : }
140 : WalletBatch(const WalletBatch&) = delete;
141 : WalletBatch& operator=(const WalletBatch&) = delete;
142 :
143 : bool WriteName(const std::string& strAddress, const std::string& strName);
144 : bool EraseName(const std::string& strAddress);
145 :
146 : bool WritePurpose(const std::string& strAddress, const std::string& purpose);
147 : bool ErasePurpose(const std::string& strAddress);
148 :
149 : bool WriteTx(const CWalletTx& wtx);
150 : bool EraseTx(uint256 hash);
151 :
152 : bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta);
153 : bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata& keyMeta);
154 : bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey);
155 :
156 : bool WriteCScript(const uint160& hash, const CScript& redeemScript);
157 :
158 : bool WriteWatchOnly(const CScript& script);
159 : bool EraseWatchOnly(const CScript& script);
160 :
161 : bool WriteBestBlock(const CBlockLocator& locator);
162 : bool ReadBestBlock(CBlockLocator& locator);
163 :
164 : bool WriteOrderPosNext(int64_t nOrderPosNext);
165 :
166 : bool WriteStakeSplitThreshold(const CAmount& nStakeSplitThreshold);
167 : bool WriteUseCustomFee(bool fUse);
168 : bool WriteCustomFeeValue(const CAmount& nCustomFee);
169 : bool WriteAutoCombineSettings(bool fEnable, CAmount nCombineThreshold, int frequency);
170 :
171 : bool ReadPool(int64_t nPool, CKeyPool& keypool);
172 : bool WritePool(int64_t nPool, const CKeyPool& keypool);
173 : bool ErasePool(int64_t nPool);
174 :
175 : bool WriteMinVersion(int nVersion);
176 :
177 : //! write the hdchain model (external/internal chain child index counter)
178 : bool WriteHDChain(const CHDChain& chain);
179 :
180 : /// Write extended spending key to wallet database, where the key is the incoming viewing key
181 : bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk,
182 : const libzcash::SaplingExtendedSpendingKey &key,
183 : const CKeyMetadata &keyMeta);
184 :
185 : bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr,
186 : const libzcash::SaplingIncomingViewingKey &ivk);
187 :
188 : bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk,
189 : const std::vector<unsigned char>& vchCryptedSecret,
190 : const CKeyMetadata &keyMeta);
191 :
192 : /// Common output viewing key, used when shielding transparent funds
193 : bool WriteSaplingCommonOVK(const uint256& ovk);
194 : bool ReadSaplingCommonOVK(uint256& ovkRet);
195 :
196 : bool WriteWitnessCacheSize(int64_t nWitnessCacheSize);
197 :
198 : /// Write destination data key,value tuple to database
199 : bool WriteDestData(const std::string& address, const std::string& key, const std::string& value);
200 : /// Erase destination data tuple from wallet database
201 : bool EraseDestData(const std::string& address, const std::string& key);
202 :
203 : DBErrors ReorderTransactions(CWallet* pwallet);
204 : DBErrors LoadWallet(CWallet* pwallet);
205 : DBErrors FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx);
206 : DBErrors ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx);
207 : /* Try to (very carefully!) recover wallet database (with a possible key type filter) */
208 : static bool Recover(const fs::path& wallet_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename);
209 : /* Recover convenience-function to bypass the key filter callback, called when verify fails, recovers everything */
210 : static bool Recover(const fs::path& wallet_path, std::string& out_backup_filename);
211 : /* Recover filter (used as callback), will only let keys (cryptographical keys) as KV/key-type pass through */
212 : static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue);
213 : /* Function to determine if a certain KV/key-type is a key (cryptographical key) type */
214 : static bool IsKeyType(const std::string& strType);
215 : /* verifies the database environment */
216 : static bool VerifyEnvironment(const fs::path& wallet_path, std::string& errorStr);
217 : /* verifies the database file */
218 : static bool VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr);
219 :
220 : //! Begin a new transaction
221 : bool TxnBegin();
222 : //! Commit current transaction
223 : bool TxnCommit();
224 : //! Abort current transaction
225 : bool TxnAbort();
226 : //! Read wallet version
227 : bool ReadVersion(int& nVersion);
228 : //! Write wallet version
229 : bool WriteVersion(int nVersion);
230 : private:
231 : BerkeleyBatch m_batch;
232 : WalletDatabase& m_database;
233 : };
234 :
235 : //! Called during init: Automatic backups
236 : bool AutoBackupWallet(CWallet& wallet, std::string& strBackupWarning, std::string& strBackupError);
237 :
238 : //! Compacts BDB state so that wallet.dat is self-contained (if there are changes)
239 : void MaybeCompactWalletDB();
240 :
241 : #endif // PIVX_WALLET_WALLETDB_H
|