Bitcoin Core  0.20.99
P2P Digital Currency
walletdb.h
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 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 <script/sign.h>
11 #include <wallet/bdb.h>
12 #include <wallet/db.h>
13 #include <wallet/walletutil.h>
14 #include <key.h>
15 
16 #include <stdint.h>
17 #include <string>
18 #include <vector>
19 
32 static const bool DEFAULT_FLUSHWALLET = true;
33 
34 struct CBlockLocator;
35 class CKeyPool;
36 class CMasterKey;
37 class CScript;
38 class CWallet;
39 class CWalletTx;
40 class uint160;
41 class uint256;
42 
45 
47 enum class DBErrors
48 {
49  LOAD_OK,
50  CORRUPT,
52  TOO_NEW,
53  LOAD_FAIL,
55 };
56 
57 namespace DBKeys {
58 extern const std::string ACENTRY;
59 extern const std::string ACTIVEEXTERNALSPK;
60 extern const std::string ACTIVEINTERNALSPK;
61 extern const std::string BESTBLOCK;
62 extern const std::string BESTBLOCK_NOMERKLE;
63 extern const std::string CRYPTED_KEY;
64 extern const std::string CSCRIPT;
65 extern const std::string DEFAULTKEY;
66 extern const std::string DESTDATA;
67 extern const std::string FLAGS;
68 extern const std::string HDCHAIN;
69 extern const std::string KEY;
70 extern const std::string KEYMETA;
71 extern const std::string MASTER_KEY;
72 extern const std::string MINVERSION;
73 extern const std::string NAME;
74 extern const std::string OLD_KEY;
75 extern const std::string ORDERPOSNEXT;
76 extern const std::string POOL;
77 extern const std::string PURPOSE;
78 extern const std::string SETTINGS;
79 extern const std::string TX;
80 extern const std::string VERSION;
81 extern const std::string WALLETDESCRIPTOR;
82 extern const std::string WALLETDESCRIPTORCKEY;
83 extern const std::string WALLETDESCRIPTORKEY;
84 extern const std::string WATCHMETA;
85 extern const std::string WATCHS;
86 } // namespace DBKeys
87 
88 /* simple HD chain data model */
89 class CHDChain
90 {
91 public:
95 
96  static const int VERSION_HD_BASE = 1;
97  static const int VERSION_HD_CHAIN_SPLIT = 2;
98  static const int CURRENT_VERSION = VERSION_HD_CHAIN_SPLIT;
99  int nVersion;
100 
101  CHDChain() { SetNull(); }
102 
104  {
105  READWRITE(obj.nVersion, obj.nExternalChainCounter, obj.seed_id);
106  if (obj.nVersion >= VERSION_HD_CHAIN_SPLIT) {
107  READWRITE(obj.nInternalChainCounter);
108  }
109  }
110 
111  void SetNull()
112  {
113  nVersion = CHDChain::CURRENT_VERSION;
114  nExternalChainCounter = 0;
115  nInternalChainCounter = 0;
116  seed_id.SetNull();
117  }
118 
119  bool operator==(const CHDChain& chain) const
120  {
121  return seed_id == chain.seed_id;
122  }
123 };
124 
126 {
127 public:
128  static const int VERSION_BASIC=1;
129  static const int VERSION_WITH_HDDATA=10;
130  static const int VERSION_WITH_KEY_ORIGIN = 12;
131  static const int CURRENT_VERSION=VERSION_WITH_KEY_ORIGIN;
132  int nVersion;
133  int64_t nCreateTime; // 0 means unknown
134  std::string hdKeypath; //optional HD/bip32 keypath. Still used to determine whether a key is a seed. Also kept for backwards compatibility
135  CKeyID hd_seed_id; //id of the HD seed used to derive this key
136  KeyOriginInfo key_origin; // Key origin info with path and fingerprint
137  bool has_key_origin = false;
138 
140  {
141  SetNull();
142  }
143  explicit CKeyMetadata(int64_t nCreateTime_)
144  {
145  SetNull();
146  nCreateTime = nCreateTime_;
147  }
148 
150  {
151  READWRITE(obj.nVersion, obj.nCreateTime);
152  if (obj.nVersion >= VERSION_WITH_HDDATA) {
153  READWRITE(obj.hdKeypath, obj.hd_seed_id);
154  }
155  if (obj.nVersion >= VERSION_WITH_KEY_ORIGIN)
156  {
157  READWRITE(obj.key_origin);
158  READWRITE(obj.has_key_origin);
159  }
160  }
161 
162  void SetNull()
163  {
165  nCreateTime = 0;
166  hdKeypath.clear();
167  hd_seed_id.SetNull();
168  key_origin.clear();
169  has_key_origin = false;
170  }
171 };
172 
181 {
182 private:
183  template <typename K, typename T>
184  bool WriteIC(const K& key, const T& value, bool fOverwrite = true)
185  {
186  if (!m_batch.Write(key, value, fOverwrite)) {
187  return false;
188  }
189  m_database.IncrementUpdateCounter();
190  if (m_database.nUpdateCounter % 1000 == 0) {
191  m_batch.Flush();
192  }
193  return true;
194  }
195 
196  template <typename K>
197  bool EraseIC(const K& key)
198  {
199  if (!m_batch.Erase(key)) {
200  return false;
201  }
202  m_database.IncrementUpdateCounter();
203  if (m_database.nUpdateCounter % 1000 == 0) {
204  m_batch.Flush();
205  }
206  return true;
207  }
208 
209 public:
210  explicit WalletBatch(WalletDatabase& database, const char* pszMode = "r+", bool _fFlushOnClose = true) :
211  m_batch(database, pszMode, _fFlushOnClose),
212  m_database(database)
213  {
214  }
215  WalletBatch(const WalletBatch&) = delete;
216  WalletBatch& operator=(const WalletBatch&) = delete;
217 
218  bool WriteName(const std::string& strAddress, const std::string& strName);
219  bool EraseName(const std::string& strAddress);
220 
221  bool WritePurpose(const std::string& strAddress, const std::string& purpose);
222  bool ErasePurpose(const std::string& strAddress);
223 
224  bool WriteTx(const CWalletTx& wtx);
225  bool EraseTx(uint256 hash);
226 
227  bool WriteKeyMetadata(const CKeyMetadata& meta, const CPubKey& pubkey, const bool overwrite);
228  bool WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata &keyMeta);
229  bool WriteCryptedKey(const CPubKey& vchPubKey, const std::vector<unsigned char>& vchCryptedSecret, const CKeyMetadata &keyMeta);
230  bool WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey);
231 
232  bool WriteCScript(const uint160& hash, const CScript& redeemScript);
233 
234  bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta);
235  bool EraseWatchOnly(const CScript &script);
236 
237  bool WriteBestBlock(const CBlockLocator& locator);
238  bool ReadBestBlock(CBlockLocator& locator);
239 
240  bool WriteOrderPosNext(int64_t nOrderPosNext);
241 
242  bool ReadPool(int64_t nPool, CKeyPool& keypool);
243  bool WritePool(int64_t nPool, const CKeyPool& keypool);
244  bool ErasePool(int64_t nPool);
245 
246  bool WriteMinVersion(int nVersion);
247 
248  bool WriteDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const CPrivKey& privkey);
249  bool WriteCryptedDescriptorKey(const uint256& desc_id, const CPubKey& pubkey, const std::vector<unsigned char>& secret);
250  bool WriteDescriptor(const uint256& desc_id, const WalletDescriptor& descriptor);
251  bool WriteDescriptorDerivedCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index, uint32_t der_index);
252  bool WriteDescriptorParentCache(const CExtPubKey& xpub, const uint256& desc_id, uint32_t key_exp_index);
253 
255  bool WriteDestData(const std::string &address, const std::string &key, const std::string &value);
257  bool EraseDestData(const std::string &address, const std::string &key);
258 
259  bool WriteActiveScriptPubKeyMan(uint8_t type, const uint256& id, bool internal);
260 
261  DBErrors LoadWallet(CWallet* pwallet);
262  DBErrors FindWalletTx(std::vector<uint256>& vTxHash, std::list<CWalletTx>& vWtx);
263  DBErrors ZapWalletTx(std::list<CWalletTx>& vWtx);
264  DBErrors ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut);
265  /* Function to determine if a certain KV/key-type is a key (cryptographical key) type */
266  static bool IsKeyType(const std::string& strType);
267  /* verifies the database environment */
268  static bool VerifyEnvironment(const fs::path& wallet_path, bilingual_str& errorStr);
269  /* verifies the database file */
270  static bool VerifyDatabaseFile(const fs::path& wallet_path, bilingual_str& errorStr);
271 
273  bool WriteHDChain(const CHDChain& chain);
274 
275  bool WriteWalletFlags(const uint64_t flags);
277  bool TxnBegin();
279  bool TxnCommit();
281  bool TxnAbort();
282 private:
285 };
286 
288 void MaybeCompactWalletDB();
289 
291 bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, std::string& strType, std::string& strErr);
292 
294 bool IsWalletLoaded(const fs::path& wallet_path);
295 
297 std::unique_ptr<BerkeleyDatabase> CreateWalletDatabase(const fs::path& path);
298 
300 std::unique_ptr<BerkeleyDatabase> CreateDummyWalletDatabase();
301 
303 std::unique_ptr<BerkeleyDatabase> CreateMockWalletDatabase();
304 
305 #endif // BITCOIN_WALLET_WALLETDB_H
static const int CURRENT_VERSION
Definition: walletdb.h:98
CKeyMetadata(int64_t nCreateTime_)
Definition: walletdb.h:143
bool EraseIC(const K &key)
Definition: walletdb.h:197
const std::string POOL
Definition: walletdb.cpp:40
const std::string FLAGS
Definition: walletdb.cpp:31
std::string hdKeypath
Definition: walletdb.h:134
void SetNull()
Definition: uint256.h:38
const std::string NAME
Definition: walletdb.cpp:37
Describes a place in the block chain to another node such that if the other node doesn&#39;t have the sam...
Definition: block.h:114
std::shared_ptr< CWallet > LoadWallet(interfaces::Chain &chain, const std::string &name, bilingual_str &error, std::vector< bilingual_str > &warnings)
Definition: dummywallet.cpp:76
bool IsWalletLoaded(const fs::path &wallet_path)
Return whether a wallet database is currently loaded.
Definition: walletdb.cpp:1025
bool operator==(const CHDChain &chain) const
Definition: walletdb.h:119
const std::string SETTINGS
Definition: walletdb.cpp:42
Bilingual messages:
Definition: translation.h:16
const std::string WALLETDESCRIPTORCKEY
Definition: walletdb.cpp:47
std::unique_ptr< BerkeleyDatabase > CreateDummyWalletDatabase()
Return object for accessing dummy database with no read/write capabilities.
Definition: walletdb.cpp:1038
const std::string CRYPTED_KEY
Definition: walletdb.cpp:27
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
Definition: walletdb.h:184
const std::string DEFAULTKEY
Definition: walletdb.cpp:29
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
Definition: crypter.h:33
const std::string KEYMETA
Definition: walletdb.cpp:33
An instance of this class represents one database.
Definition: bdb.h:99
uint32_t nExternalChainCounter
Definition: walletdb.h:92
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:201
SERIALIZE_METHODS(CKeyMetadata, obj)
Definition: walletdb.h:149
WalletBatch(WalletDatabase &database, const char *pszMode="r+", bool _fFlushOnClose=true)
Definition: walletdb.h:210
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:47
const std::string ORDERPOSNEXT
Definition: walletdb.cpp:39
const std::string MASTER_KEY
Definition: walletdb.cpp:35
void clear()
Definition: keyorigin.h:23
Access to the wallet database.
Definition: walletdb.h:180
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
secure_allocator is defined in allocators.h CPrivKey is a serialized private key, with all parameters...
Definition: key.h:24
const std::string OLD_KEY
Definition: walletdb.cpp:38
const std::string HDCHAIN
Definition: walletdb.cpp:32
const std::string WALLETDESCRIPTOR
Definition: walletdb.cpp:45
static const int CURRENT_VERSION
Definition: walletdb.h:131
const std::string ACTIVEINTERNALSPK
Definition: walletdb.cpp:24
WalletDatabase & m_database
Definition: walletdb.h:284
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
Definition: walletdb.cpp:949
An encapsulated public key.
Definition: pubkey.h:30
const std::string WATCHMETA
Definition: walletdb.cpp:49
std::unique_ptr< BerkeleyDatabase > CreateMockWalletDatabase()
Return object for accessing temporary in-memory database.
Definition: walletdb.cpp:1044
RAII class that provides access to a Berkeley database.
Definition: bdb.h:169
const std::string WALLETDESCRIPTORKEY
Definition: walletdb.cpp:48
const std::string DESTDATA
Definition: walletdb.cpp:30
Descriptor with some wallet metadata.
Definition: walletutil.h:91
KeyOriginInfo key_origin
Definition: walletdb.h:136
int64_t nCreateTime
Definition: walletdb.h:133
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:265
SERIALIZE_METHODS(CHDChain, obj)
Definition: walletdb.h:103
int nVersion
Definition: walletdb.h:132
int flags
Definition: bitcoin-tx.cpp:509
256-bit opaque blob.
Definition: uint256.h:120
BerkeleyBatch m_batch
Definition: walletdb.h:283
const std::string ACENTRY
Definition: walletdb.cpp:22
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:390
const std::string MINVERSION
Definition: walletdb.cpp:36
static const bool DEFAULT_FLUSHWALLET
Overview of wallet database classes:
Definition: walletdb.h:32
A reference to a CKey: the Hash160 of its serialized public key.
Definition: pubkey.h:20
const std::string ACTIVEEXTERNALSPK
Definition: walletdb.cpp:23
A CWallet maintains a set of transactions and balances, and provides the ability to create new transa...
Definition: wallet.h:618
160-bit opaque blob.
Definition: uint256.h:109
CHDChain()
Definition: walletdb.h:101
std::unique_ptr< BerkeleyDatabase > CreateWalletDatabase(const fs::path &path)
Return object for accessing database at specified path.
Definition: walletdb.cpp:1031
const std::string WATCHS
Definition: walletdb.cpp:50
bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, std::string &strType, std::string &strErr)
Unserialize a given Key-Value pair and load it into the wallet.
Definition: walletdb.cpp:674
void SetNull()
Definition: walletdb.h:111
const char * TX
The tx message transmits a single transaction.
Definition: protocol.cpp:26
CKeyID hd_seed_id
Definition: walletdb.h:135
const std::string BESTBLOCK
Definition: walletdb.cpp:26
const std::string CSCRIPT
Definition: walletdb.cpp:28
CKeyID seed_id
seed hash160
Definition: walletdb.h:94
#define VERSION
#define READWRITE(...)
Definition: serialize.h:171
const std::string BESTBLOCK_NOMERKLE
Definition: walletdb.cpp:25
const std::string KEY
Definition: walletdb.cpp:34
int nVersion
Definition: walletdb.h:99
void SetNull()
Definition: walletdb.h:162
uint32_t nInternalChainCounter
Definition: walletdb.h:93
A key from a CWallet&#39;s keypool.
const std::string PURPOSE
Definition: walletdb.cpp:41