PIVX Core  5.6.99
P2P Digital Currency
walletdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2021 The Bitcoin developers
3 // Copyright (c) 2014-2015 The Dash developers
4 // Copyright (c) 2015-2021 The PIVX Core developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #include "wallet/walletdb.h"
9 
10 #include "fs.h"
11 
12 #include "key_io.h"
13 #include "protocol.h"
14 #include "reverse_iterate.h"
15 #include "sapling/key_io_sapling.h"
16 #include "serialize.h"
17 #include "sync.h"
18 #include "util/system.h"
19 #include "utiltime.h"
20 #include "wallet/wallet.h"
21 #include "wallet/walletutil.h"
22 
23 #include <atomic>
24 
25 #include <boost/thread.hpp>
26 
27 namespace DBKeys {
28  const std::string BESTBLOCK_NOMERKLE{"bestblock_nomerkle"};
29  const std::string BESTBLOCK{"bestblock"};
30  const std::string CRYPTED_KEY{"ckey"};
31  const std::string CSCRIPT{"cscript"};
32  const std::string DEFAULTKEY{"defaultkey"};
33  const std::string DESTDATA{"destdata"};
34  const std::string HDCHAIN{"hdchain"};
35  const std::string KEYMETA{"keymeta"};
36  const std::string KEY{"key"};
37  const std::string MASTER_KEY{"mkey"};
38  const std::string MINVERSION{"minversion"};
39  const std::string NAME{"name"};
40  const std::string ORDERPOSNEXT{"orderposnext"};
41  const std::string POOL{"pool"};
42  const std::string PURPOSE{"purpose"};
43  const std::string TX{"tx"};
44  const std::string VERSION{"version"};
45  const std::string WATCHS{"watchs"};
46 
47  // Sapling
48  const std::string SAP_KEYMETA{"sapzkeymeta"};
49  const std::string SAP_KEY{"sapzkey"};
50  const std::string SAP_KEY_CRIPTED{"csapzkey"};
51  const std::string SAP_ADDR{"sapzaddr"};
52  const std::string SAP_COMMON_OVK{"commonovk"};
53  const std::string SAP_HDCHAIN{"hdchain_sap"};
54  const std::string SAP_WITNESS_CACHE_SIZE{"witnesscachesize"};
55 
56  // Wallet custom settings
57  const std::string AUTOCOMBINE{"autocombinesettings"};
58  const std::string AUTOCOMBINE_V2{"autocombinesettingsV2"};
59  const std::string STAKE_SPLIT_THRESHOLD{"stakeSplitThreshold"};
60  const std::string USE_CUSTOM_FEE{"fUseCustomFee"};
61  const std::string CUSTOM_FEE_VALUE{"nCustomFee"};
62 
63 } // namespace DBKeys
64 
65 
66 //
67 // WalletBatch
68 //
69 
70 bool WalletBatch::WriteName(const std::string& strAddress, const std::string& strName)
71 {
72  return WriteIC(std::make_pair(std::string(DBKeys::NAME), strAddress), strName);
73 }
74 
75 bool WalletBatch::EraseName(const std::string& strAddress)
76 {
77  // This should only be used for sending addresses, never for receiving addresses,
78  // receiving addresses must always have an address book entry if they're not change return.
79  return EraseIC(std::make_pair(std::string(DBKeys::NAME), strAddress));
80 }
81 
82 bool WalletBatch::WritePurpose(const std::string& strAddress, const std::string& strPurpose)
83 {
84  return WriteIC(std::make_pair(std::string(DBKeys::PURPOSE), strAddress), strPurpose);
85 }
86 
87 bool WalletBatch::ErasePurpose(const std::string& strPurpose)
88 {
89  return EraseIC(std::make_pair(std::string(DBKeys::PURPOSE), strPurpose));
90 }
91 
93 {
94  return WriteIC(std::make_pair(std::string(DBKeys::TX), wtx.GetHash()), wtx);
95 }
96 
98 {
99  return EraseIC(std::make_pair(std::string(DBKeys::TX), hash));
100 }
101 
102 bool WalletBatch::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta)
103 {
104  if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta, false)) {
105  return false;
106  }
107 
108  // hash pubkey/privkey to accelerate wallet load
109  std::vector<unsigned char> vchKey;
110  vchKey.reserve(vchPubKey.size() + vchPrivKey.size());
111  vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
112  vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
113 
114  return WriteIC(std::make_pair(std::string(DBKeys::KEY), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
115 }
116 
117 bool WalletBatch::WriteCryptedKey(const CPubKey& vchPubKey,
118  const std::vector<unsigned char>& vchCryptedSecret,
119  const CKeyMetadata& keyMeta)
120 {
121  const bool fEraseUnencryptedKey = true;
122 
123  if (!WriteIC(std::make_pair(std::string(DBKeys::KEYMETA), vchPubKey), keyMeta)) {
124  return false;
125  }
126 
127  if (!WriteIC(std::make_pair(std::string(DBKeys::CRYPTED_KEY), vchPubKey), vchCryptedSecret, false)) {
128  return false;
129  }
130  if (fEraseUnencryptedKey) {
131  EraseIC(std::make_pair(std::string(DBKeys::KEY), vchPubKey));
132  }
133 
134  return true;
135 }
136 
139  const CKeyMetadata &keyMeta)
140 {
141  if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) {
142  return false;
143  }
144 
145  return WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY), ivk), key, false);
146 }
147 
150 {
151  return WriteIC(std::make_pair(std::string(DBKeys::SAP_ADDR), addr), ivk, false);
152 }
153 
155  const std::vector<unsigned char>& vchCryptedSecret,
156  const CKeyMetadata &keyMeta)
157 {
158  const bool fEraseUnencryptedKey = true;
159  auto ivk = extfvk.fvk.in_viewing_key();
160 
161  if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEYMETA), ivk), keyMeta)) {
162  return false;
163  }
164 
165  if (!WriteIC(std::make_pair(std::string(DBKeys::SAP_KEY_CRIPTED), ivk),
166  std::make_pair(extfvk, vchCryptedSecret), false)) {
167  return false;
168  }
169 
170  if (fEraseUnencryptedKey) {
171  EraseIC(std::make_pair(std::string(DBKeys::SAP_KEY), ivk));
172  }
173  return true;
174 }
175 
177 {
178  return WriteIC(std::string(DBKeys::SAP_COMMON_OVK), ovk);
179 }
180 
182 {
183  return m_batch.Read(std::string(DBKeys::SAP_COMMON_OVK), ovkRet);
184 }
185 
186 bool WalletBatch::WriteWitnessCacheSize(int64_t nWitnessCacheSize)
187 {
188  return WriteIC(std::string(DBKeys::SAP_WITNESS_CACHE_SIZE), nWitnessCacheSize);
189 }
190 
191 bool WalletBatch::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
192 {
193  return WriteIC(std::make_pair(std::string(DBKeys::MASTER_KEY), nID), kMasterKey, true);
194 }
195 
196 bool WalletBatch::WriteCScript(const uint160& hash, const CScript& redeemScript)
197 {
198  return WriteIC(std::make_pair(std::string(DBKeys::CSCRIPT), hash), redeemScript, false);
199 }
200 
202 {
203  return WriteIC(std::make_pair(std::string(DBKeys::WATCHS), dest), '1');
204 }
205 
207 {
208  return EraseIC(std::make_pair(std::string(DBKeys::WATCHS), dest));
209 }
210 
212 {
213  WriteIC(std::string(DBKeys::BESTBLOCK), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
214  return WriteIC(std::string(DBKeys::BESTBLOCK_NOMERKLE), locator);
215 }
216 
218 {
219  if (m_batch.Read(std::string(DBKeys::BESTBLOCK), locator) && !locator.vHave.empty()) {
220  return true;
221  }
222  return m_batch.Read(std::string(DBKeys::BESTBLOCK_NOMERKLE), locator);
223 }
224 
225 bool WalletBatch::WriteOrderPosNext(int64_t nOrderPosNext)
226 {
227  return WriteIC(std::string(DBKeys::ORDERPOSNEXT), nOrderPosNext);
228 }
229 
230 bool WalletBatch::WriteStakeSplitThreshold(const CAmount& nStakeSplitThreshold)
231 {
232  return WriteIC(std::string(DBKeys::STAKE_SPLIT_THRESHOLD), nStakeSplitThreshold);
233 }
234 
236 {
237  return WriteIC(std::string(DBKeys::USE_CUSTOM_FEE), fUse);
238 }
239 
241 {
242  return WriteIC(std::string(DBKeys::CUSTOM_FEE_VALUE), nFee);
243 }
244 
245 bool WalletBatch::WriteAutoCombineSettings(bool fEnable, CAmount nCombineThreshold, int frequency)
246 {
247  std::pair<std::pair<bool, CAmount>, int> pSettings;
248  pSettings.first.first = fEnable;
249  pSettings.first.second = nCombineThreshold;
250  pSettings.second = frequency;
251  EraseIC(std::string(DBKeys::AUTOCOMBINE));
252  return WriteIC(std::string(DBKeys::AUTOCOMBINE_V2), pSettings, true);
253 }
254 
255 bool WalletBatch::ReadPool(int64_t nPool, CKeyPool& keypool)
256 {
257  return m_batch.Read(std::make_pair(std::string(DBKeys::POOL), nPool), keypool);
258 }
259 
260 bool WalletBatch::WritePool(int64_t nPool, const CKeyPool& keypool)
261 {
262  return WriteIC(std::make_pair(std::string(DBKeys::POOL), nPool), keypool);
263 }
264 
265 bool WalletBatch::ErasePool(int64_t nPool)
266 {
267  return EraseIC(std::make_pair(std::string(DBKeys::POOL), nPool));
268 }
269 
271 {
272  return WriteIC(std::string(DBKeys::MINVERSION), nVersion);
273 }
274 
276 {
277  std::string key = chain.chainType == HDChain::ChainCounterType::Sapling ?
279  return WriteIC(key, chain);
280 }
281 
283 {
284  LOCK(pwallet->cs_wallet);
285  // Old wallets didn't have any defined order for transactions
286  // Probably a bad idea to change the output of this
287 
288  // First: get all CWalletTx into a sorted-by-time multimap.
289  typedef std::multimap<int64_t, CWalletTx*> TxItems;
290  TxItems txByTime;
291 
292  for (auto it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) {
293  CWalletTx* wtx = &((*it).second);
294  txByTime.insert(std::make_pair(wtx->nTimeReceived, wtx));
295  }
296 
297  int64_t& nOrderPosNext = pwallet->nOrderPosNext;
298  nOrderPosNext = 0;
299  std::vector<int64_t> nOrderPosOffsets;
300  for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) {
301  CWalletTx *const pwtx = (*it).second;
302  int64_t& nOrderPos = pwtx->nOrderPos;
303 
304  if (nOrderPos == -1) {
305  nOrderPos = nOrderPosNext++;
306  nOrderPosOffsets.push_back(nOrderPos);
307 
308  if (!WriteTx(*pwtx)) return DB_LOAD_FAIL;
309 
310  } else {
311  int64_t nOrderPosOff = 0;
312  for (const int64_t& nOffsetStart : nOrderPosOffsets) {
313  if (nOrderPos >= nOffsetStart)
314  ++nOrderPosOff;
315  }
316  nOrderPos += nOrderPosOff;
317  nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
318 
319  if (!nOrderPosOff) continue;
320 
321  // Since we're changing the order, write it back
322  if (!WriteTx(*pwtx)) return DB_LOAD_FAIL;
323  }
324  }
325  WriteOrderPosNext(nOrderPosNext);
326 
327  return DB_LOAD_OK;
328 }
329 
331 {
332 public:
333  unsigned int nKeys;
334  unsigned int nCKeys;
335  unsigned int nKeyMeta;
336  unsigned int nZKeys;
337  unsigned int nZKeyMeta;
338  unsigned int nSapZAddrs;
342  std::vector<uint256> vWalletUpgrade;
343 
345  {
347  fIsEncrypted = false;
348  fAnyUnordered = false;
349  nFileVersion = 0;
350  }
351 };
352 
353 bool ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CWalletScanState& wss, std::string& strType, std::string& strErr)
354 {
355  try {
356  // Unserialize
357  // Taking advantage of the fact that pair serialization
358  // is just the two items serialized one after the other
359  ssKey >> strType;
360  if (strType == DBKeys::NAME) {
361  std::string strAddress;
362  ssKey >> strAddress;
363  std::string strName;
364  ssValue >> strName;
365  pwallet->LoadAddressBookName(Standard::DecodeDestination(strAddress), strName);
366  } else if (strType == DBKeys::PURPOSE) {
367  std::string strAddress;
368  ssKey >> strAddress;
369  std::string strPurpose;
370  ssValue >> strPurpose;
371  pwallet->LoadAddressBookPurpose(Standard::DecodeDestination(strAddress), strPurpose);
372  } else if (strType == DBKeys::TX) {
373  uint256 hash;
374  ssKey >> hash;
375  CWalletTx wtx(nullptr /* pwallet */, MakeTransactionRef());
376  ssValue >> wtx;
377  if (wtx.GetHash() != hash)
378  return false;
379 
380  // Undo serialize changes in 31600
381  if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) {
382  if (!ssValue.empty()) {
383  char fTmp;
384  char fUnused;
385  std::string unused_string;
386  ssValue >> fTmp >> fUnused >> unused_string;
387  strErr = strprintf("LoadWallet() upgrading tx ver=%d %d %s",
388  wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
389  wtx.fTimeReceivedIsTxTime = fTmp;
390  } else {
391  strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString());
392  wtx.fTimeReceivedIsTxTime = 0;
393  }
394  wss.vWalletUpgrade.push_back(hash);
395  }
396 
397  if (wtx.nOrderPos == -1)
398  wss.fAnyUnordered = true;
399 
400  pwallet->LoadToWallet(wtx);
401  } else if (strType == DBKeys::WATCHS) {
402  CScript script;
403  ssKey >> script;
404  char fYes;
405  ssValue >> fYes;
406  if (fYes == '1')
407  pwallet->LoadWatchOnly(script);
408 
409  // Watch-only addresses have no birthday information for now,
410  // so set the wallet birthday to the beginning of time.
411  pwallet->nTimeFirstKey = 1;
412  } else if (strType == DBKeys::KEY) {
413  CPubKey vchPubKey;
414  ssKey >> vchPubKey;
415  if (!vchPubKey.IsValid()) {
416  strErr = "Error reading wallet database: CPubKey corrupt";
417  return false;
418  }
419  CKey key;
420  CPrivKey pkey;
421  uint256 hash;
422  wss.nKeys++;
423  ssValue >> pkey;
424 
425  // Old wallets store keys as "key" [pubkey] => [privkey]
426  // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key
427  // using EC operations as a checksum.
428  // Newer wallets store keys as "key"[pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while
429  // remaining backwards-compatible.
430  try {
431  ssValue >> hash;
432  } catch (...) {
433  }
434 
435  bool fSkipCheck = false;
436 
437  if (!hash.IsNull()) {
438  // hash pubkey/privkey to accelerate wallet load
439  std::vector<unsigned char> vchKey;
440  vchKey.reserve(vchPubKey.size() + pkey.size());
441  vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
442  vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
443 
444  if (Hash(vchKey.begin(), vchKey.end()) != hash) {
445  strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt";
446  return false;
447  }
448 
449  fSkipCheck = true;
450  }
451 
452  if (!key.Load(pkey, vchPubKey, fSkipCheck)) {
453  strErr = "Error reading wallet database: CPrivKey corrupt";
454  return false;
455  }
456  if (!pwallet->LoadKey(key, vchPubKey)) {
457  strErr = "Error reading wallet database: LoadKey failed";
458  return false;
459  }
460  } else if (strType == DBKeys::MASTER_KEY) {
461  unsigned int nID;
462  ssKey >> nID;
463  CMasterKey kMasterKey;
464  ssValue >> kMasterKey;
465  if (pwallet->mapMasterKeys.count(nID) != 0) {
466  strErr = strprintf("Error reading wallet database: duplicate CMasterKey id %u", nID);
467  return false;
468  }
469  pwallet->mapMasterKeys[nID] = kMasterKey;
470  if (pwallet->nMasterKeyMaxID < nID)
471  pwallet->nMasterKeyMaxID = nID;
472  } else if (strType == DBKeys::CRYPTED_KEY) {
473  CPubKey vchPubKey;
474  ssKey >> vchPubKey;
475  std::vector<unsigned char> vchPrivKey;
476  ssValue >> vchPrivKey;
477  wss.nCKeys++;
478 
479  if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey)) {
480  strErr = "Error reading wallet database: LoadCryptedKey failed";
481  return false;
482  }
483  wss.fIsEncrypted = true;
484  } else if (strType == DBKeys::KEYMETA) {
485  CPubKey vchPubKey;
486  ssKey >> vchPubKey;
487  CKeyMetadata keyMeta;
488  ssValue >> keyMeta;
489  wss.nKeyMeta++;
490 
491  pwallet->LoadKeyMetadata(vchPubKey, keyMeta);
492 
493  // find earliest key creation time, as wallet birthday
494  if (!pwallet->nTimeFirstKey ||
495  (keyMeta.nCreateTime < pwallet->nTimeFirstKey))
496  pwallet->nTimeFirstKey = keyMeta.nCreateTime;
497  } else if (strType == DBKeys::DEFAULTKEY) {
498  // We don't want or need the default key, but if there is one set,
499  // we want to make sure that it is valid so that we can detect corruption
500  CPubKey vchPubKey;
501  ssValue >> vchPubKey;
502  if (!vchPubKey.IsValid()) {
503  strErr = "Error reading wallet database: Default Key corrupt";
504  return false;
505  }
506  } else if (strType == DBKeys::POOL) {
507  int64_t nIndex;
508  ssKey >> nIndex;
509  CKeyPool keypool;
510  ssValue >> keypool;
511  pwallet->GetScriptPubKeyMan()->LoadKeyPool(nIndex, keypool);
512  } else if (strType == DBKeys::VERSION) {
513  ssValue >> wss.nFileVersion;
514  if (wss.nFileVersion == 10300)
515  wss.nFileVersion = 300;
516  } else if (strType == DBKeys::CSCRIPT) {
517  uint160 hash;
518  ssKey >> hash;
519  CScript script;
520  ssValue >> script;
521  if (!pwallet->LoadCScript(script)) {
522  strErr = "Error reading wallet database: LoadCScript failed";
523  return false;
524  }
525  } else if (strType == DBKeys::ORDERPOSNEXT) {
526  ssValue >> pwallet->nOrderPosNext;
527  } else if (strType == DBKeys::STAKE_SPLIT_THRESHOLD) {
528  ssValue >> pwallet->nStakeSplitThreshold;
529  // originally saved as integer
530  if (pwallet->nStakeSplitThreshold < COIN)
531  pwallet->nStakeSplitThreshold *= COIN;
532  } else if (strType == DBKeys::USE_CUSTOM_FEE) {
533  ssValue >> pwallet->fUseCustomFee;
534  } else if (strType == DBKeys::CUSTOM_FEE_VALUE) {
535  ssValue >> pwallet->nCustomFee;
536  } else if (strType == DBKeys::AUTOCOMBINE) {
537  std::pair<bool, CAmount> pSettings;
538  ssValue >> pSettings;
539  pwallet->fCombineDust = pSettings.first;
540  pwallet->nAutoCombineThreshold = pSettings.second;
541  // Value used for old autocombine
542  pwallet->frequency = 1;
543  // originally saved as integer
544  if (pwallet->nAutoCombineThreshold < COIN)
545  pwallet->nAutoCombineThreshold *= COIN;
546  } else if (strType == DBKeys::AUTOCOMBINE_V2) {
547  std::pair<std::pair<bool, CAmount>, int> pSettings;
548  ssValue >> pSettings;
549  pwallet->fCombineDust = pSettings.first.first;
550  pwallet->nAutoCombineThreshold = pSettings.first.second;
551  pwallet->frequency = pSettings.second;
552  } else if (strType == DBKeys::DESTDATA) {
553  std::string strAddress, strKey, strValue;
554  ssKey >> strAddress;
555  ssKey >> strKey;
556  ssValue >> strValue;
557  if (!pwallet->LoadDestData(DecodeDestination(strAddress), strKey, strValue)) {
558  strErr = "Error reading wallet database: LoadDestData failed";
559  return false;
560  }
561  } else if (strType == DBKeys::HDCHAIN) { // Regular key chain counter
562  CHDChain chain;
563  ssValue >> chain;
564  pwallet->GetScriptPubKeyMan()->SetHDChain(chain, true);
565  } else if (strType == DBKeys::SAP_HDCHAIN) {
566  CHDChain chain;
567  ssValue >> chain;
568  pwallet->GetSaplingScriptPubKeyMan()->SetHDChain(chain, true);
569  } else if (strType == DBKeys::SAP_KEY) {
571  ssKey >> ivk;
573  ssValue >> key;
574  if (!pwallet->LoadSaplingZKey(key)) {
575  strErr = "Error reading wallet database: LoadSaplingZKey failed";
576  return false;
577  }
578  //add checks for integrity
579  wss.nZKeys++;
580  } else if (strType == DBKeys::SAP_COMMON_OVK) {
581  uint256 ovk;
582  ssValue >> ovk;
583  pwallet->GetSaplingScriptPubKeyMan()->setCommonOVK(ovk);
584  } else if (strType == DBKeys::SAP_KEY_CRIPTED) {
586  ssKey >> ivk;
588  ssValue >> extfvk;
589  std::vector<unsigned char> vchCryptedSecret;
590  ssValue >> vchCryptedSecret;
591  wss.nCKeys++;
592 
593  if (!pwallet->LoadCryptedSaplingZKey(extfvk, vchCryptedSecret)) {
594  strErr = "Error reading wallet database: LoadCryptedSaplingZKey failed";
595  return false;
596  }
597  wss.fIsEncrypted = true;
598  } else if (strType == DBKeys::SAP_KEYMETA) {
600  ssKey >> ivk;
601  CKeyMetadata keyMeta;
602  ssValue >> keyMeta;
603 
604  wss.nZKeyMeta++;
605 
606  pwallet->LoadSaplingZKeyMetadata(ivk, keyMeta);
607  } else if (strType == DBKeys::SAP_ADDR) {
609  ssKey >> addr;
611  ssValue >> ivk;
612 
613  wss.nSapZAddrs++;
614 
615  if (!pwallet->LoadSaplingPaymentAddress(addr, ivk)) {
616  strErr = "Error reading wallet database: LoadSaplingPaymentAddress failed";
617  return false;
618  }
619  } else if (strType == DBKeys::SAP_WITNESS_CACHE_SIZE) {
620  ssValue >> pwallet->GetSaplingScriptPubKeyMan()->nWitnessCacheSize;
621  }
622  } catch (...) {
623  return false;
624  }
625  return true;
626 }
627 
628 bool WalletBatch::IsKeyType(const std::string& strType)
629 {
630  return (strType == DBKeys::KEY ||
631  strType == DBKeys::MASTER_KEY || strType == DBKeys::CRYPTED_KEY ||
632  strType == DBKeys::SAP_KEY || strType == DBKeys::SAP_KEY_CRIPTED);
633 }
634 
636 {
637  CWalletScanState wss;
638  bool fNoncriticalErrors = false;
639  DBErrors result = DB_LOAD_OK;
640 
641  LOCK(pwallet->cs_wallet);
642  try {
643  int nMinVersion = 0;
644  if (m_batch.Read((std::string) DBKeys::MINVERSION, nMinVersion)) {
645  if (nMinVersion > CLIENT_VERSION) {
646  return DB_TOO_NEW;
647  }
648  pwallet->LoadMinVersion(nMinVersion);
649  }
650 
651  // Get cursor
652  Dbc* pcursor = m_batch.GetCursor();
653  if (!pcursor) {
654  LogPrintf("Error getting wallet database cursor\n");
655  return DB_CORRUPT;
656  }
657 
658  while (true) {
659  // Read next record
660  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
661  CDataStream ssValue(SER_DISK, CLIENT_VERSION);
662  int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
663  if (ret == DB_NOTFOUND) {
664  break;
665  } else if (ret != 0) {
666  LogPrintf("Error reading next record from wallet database\n");
667  return DB_CORRUPT;
668  }
669 
670  // Try to be tolerant of single corrupt records:
671  std::string strType, strErr;
672  if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) {
673  // losing keys is considered a catastrophic error, anything else
674  // we assume the user can live with:
675  if (IsKeyType(strType) || strType == DBKeys::DEFAULTKEY) {
676  result = DB_CORRUPT;
677  } else {
678  // Leave other errors alone, if we try to fix them we might make things worse.
679  fNoncriticalErrors = true; // ... but do warn the user there is something wrong.
680  if (strType == DBKeys::TX)
681  // Rescan if there is a bad transaction record:
682  gArgs.SoftSetBoolArg("-rescan", true);
683  }
684  }
685  if (!strErr.empty())
686  LogPrintf("%s\n", strErr);
687  }
688  pcursor->close();
689  } catch (const boost::thread_interrupted&) {
690  throw;
691  } catch (...) {
692  result = DB_CORRUPT;
693  }
694 
695  if (fNoncriticalErrors && result == DB_LOAD_OK)
696  result = DB_NONCRITICAL_ERROR;
697 
698  // Any wallet corruption at all: skip any rewriting or
699  // upgrading, we don't want to make it worse.
700  if (result != DB_LOAD_OK)
701  return result;
702 
703  LogPrintf("nFileVersion = %d\n", wss.nFileVersion);
704 
705  LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
706  wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys);
707 
708  LogPrintf("ZKeys: %u plaintext, -- encrypted, %u w/metadata, %u total\n",
709  wss.nZKeys, wss.nZKeyMeta, wss.nZKeys + 0);
710 
711  // nTimeFirstKey is only reliable if all keys have metadata
712  if ((wss.nKeys + wss.nCKeys) != wss.nKeyMeta)
713  pwallet->nTimeFirstKey = 1; // 0 would be considered 'no value'
714 
715  for (const uint256& hash : wss.vWalletUpgrade) {
716  WriteTx(pwallet->mapWallet.at(hash));
717  }
718 
719  // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
720  if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000)) {
721  return DB_NEED_REWRITE;
722  }
723 
724  if (wss.nFileVersion < CLIENT_VERSION) { // Update
725  WriteVersion(CLIENT_VERSION);
726  }
727 
728  if (wss.fAnyUnordered) {
729  result = ReorderTransactions(pwallet);
730  }
731 
732  return result;
733 }
734 
735 DBErrors WalletBatch::FindWalletTx(CWallet* pwallet, std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx)
736 {
737  bool fNoncriticalErrors = false;
738  DBErrors result = DB_LOAD_OK;
739 
740  try {
741  LOCK(pwallet->cs_wallet);
742  int nMinVersion = 0;
743  if (m_batch.Read((std::string) DBKeys::MINVERSION, nMinVersion)) {
744  if (nMinVersion > CLIENT_VERSION) {
745  return DB_TOO_NEW;
746  }
747  pwallet->LoadMinVersion(nMinVersion);
748  }
749 
750  // Get cursor
751  Dbc* pcursor = m_batch.GetCursor();
752  if (!pcursor) {
753  LogPrintf("Error getting wallet database cursor\n");
754  return DB_CORRUPT;
755  }
756 
757  while (true) {
758  // Read next record
759  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
760  CDataStream ssValue(SER_DISK, CLIENT_VERSION);
761  int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
762  if (ret == DB_NOTFOUND) {
763  break;
764  } else if (ret != 0) {
765  LogPrintf("Error reading next record from wallet database\n");
766  return DB_CORRUPT;
767  }
768 
769  std::string strType;
770  ssKey >> strType;
771  if (strType == DBKeys::TX) {
772  uint256 hash;
773  ssKey >> hash;
774 
775  CWalletTx wtx(nullptr /* pwallet */, MakeTransactionRef());
776  ssValue >> wtx;
777 
778  vTxHash.push_back(hash);
779  vWtx.push_back(wtx);
780  }
781  }
782  pcursor->close();
783  } catch (const boost::thread_interrupted&) {
784  throw;
785  } catch (...) {
786  result = DB_CORRUPT;
787  }
788 
789  if (fNoncriticalErrors && result == DB_LOAD_OK)
790  result = DB_NONCRITICAL_ERROR;
791 
792  return result;
793 }
794 
795 DBErrors WalletBatch::ZapWalletTx(CWallet* pwallet, std::vector<CWalletTx>& vWtx)
796 {
797  // build list of wallet TXs
798  std::vector<uint256> vTxHash;
799  DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx);
800  if (err != DB_LOAD_OK) {
801  return err;
802  }
803 
804  // erase each wallet TX
805  for (uint256& hash : vTxHash) {
806  if (!EraseTx(hash)) return DB_CORRUPT;
807  }
808 
809  return DB_LOAD_OK;
810 }
811 
813 {
814  static std::atomic<bool> fOneThread;
815  if (fOneThread.exchange(true)) {
816  return;
817  }
818  if (!gArgs.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) {
819  return;
820  }
821 
822  for (CWalletRef pwallet : vpwallets) {
823  WalletDatabase& dbh = pwallet->GetDBHandle();
824 
825  unsigned int nUpdateCounter = dbh.nUpdateCounter;
826  if (dbh.nLastSeen != nUpdateCounter) {
827  dbh.nLastSeen = nUpdateCounter;
828  dbh.nLastWalletUpdate = GetTime();
829  }
830 
831  if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) {
832  if (BerkeleyBatch::PeriodicFlush(dbh)) {
833  dbh.nLastFlushed = nUpdateCounter;
834  }
835  }
836  }
837 
838  fOneThread = false;
839 }
840 
841 typedef std::multimap<std::time_t, fs::path> folder_set_t;
842 static folder_set_t buildBackupsMapSortedByLastWrite(const std::string& strWalletFile, const fs::path& backupsDir)
843 {
844  folder_set_t folder_set;
845  fs::directory_iterator end_iter;
846  // Build map of backup files for current(!) wallet sorted by last write time
847  for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) {
848  // Only check regular files
849  if (fs::is_regular_file(dir_iter->status())) {
850  // Only add the backups for the current wallet, e.g. wallet.dat.*
851  if(dir_iter->path().stem().string() == strWalletFile) {
852  folder_set.insert(folder_set_t::value_type(fs::last_write_time(dir_iter->path()), *dir_iter));
853  }
854  }
855  }
856  return folder_set;
857 }
858 
859 static bool cleanWalletBackups(folder_set_t& folder_set, int nWalletBackups, std::string& strBackupWarning)
860 {
861  // Loop backward through backup files and keep the N newest ones (1 <= N <= 10)
862  int counter = 0;
863  for (const std::pair<const std::time_t, fs::path>& file : reverse_iterate(folder_set)) {
864  counter++;
865  if (counter > nWalletBackups) {
866  // More than nWalletBackups backups: delete oldest one(s)
867  try {
868  fs::remove(file.second);
869  LogPrintf("Old backup deleted: %s\n", file.second);
870  } catch (fs::filesystem_error &error) {
871  strBackupWarning = strprintf(_("Failed to delete backup, error: %s"), error.what());
872  LogPrintf("%s\n", strBackupWarning);
873  return false;
874  }
875  }
876  }
877  return true;
878 }
879 
880 bool AutoBackupWallet(CWallet& wallet, std::string& strBackupWarning, std::string& strBackupError)
881 {
882  strBackupWarning = strBackupError = "";
883  int nWalletBackups = std::max(0, std::min(10, (int)gArgs.GetArg("-createwalletbackups", DEFAULT_CREATEWALLETBACKUPS)));
884  if (nWalletBackups == 0) {
885  LogPrintf("Automatic wallet backups are disabled!\n");
886  return false;
887  }
888 
889  fs::path backupsDir = GetDataDir() / "backups";
890  backupsDir.make_preferred();
891  TryCreateDirectories(backupsDir);
892  std::string strWalletFile = wallet.GetUniqueWalletBackupName();
893  fs::path backupFile = backupsDir / strWalletFile;
894  backupFile.make_preferred();
895  if (fs::exists(backupFile)) {
896  LogPrintf("%s\n", _("Failed to create backup, file already exists! This could happen if you restarted wallet in less than 60 seconds. You can continue if you are ok with this."));
897  return false;
898  }
899 
900  // Try to backup
901  if (!wallet.BackupWallet(backupFile.string())) {
902  strBackupError = "Failed to backup wallet";
903  return false; // error is logged internally
904  }
905 
906  // Keep only 0 < nWalletBackups <= 10 backups, including the new one of course
907  folder_set_t folder_set = buildBackupsMapSortedByLastWrite(backupFile.stem().string(), backupsDir);
908  return cleanWalletBackups(folder_set, nWalletBackups, strBackupWarning);
909 }
910 
911 //
912 // Try to (very carefully!) recover wallet file if there is a problem.
913 //
914 bool WalletBatch::Recover(const fs::path& wallet_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename)
915 {
916  return BerkeleyBatch::Recover(wallet_path, callbackDataIn, recoverKVcallback, out_backup_filename);
917 }
918 
919 bool WalletBatch::Recover(const fs::path& wallet_path, std::string& out_backup_filename)
920 {
921  // recover without a key filter callback
922  // results in recovering all record types
923  return WalletBatch::Recover(wallet_path, nullptr, nullptr, out_backup_filename);
924 }
925 
926 bool WalletBatch::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
927 {
928  CWallet *dummyWallet = reinterpret_cast<CWallet*>(callbackData);
929  CWalletScanState dummyWss;
930  std::string strType, strErr;
931  bool fReadOK;
932  {
933  // Required in LoadKeyMetadata():
934  LOCK(dummyWallet->cs_wallet);
935  fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue,
936  dummyWss, strType, strErr);
937  }
938  if (!IsKeyType(strType) && strType != DBKeys::HDCHAIN)
939  return false;
940  if (!fReadOK)
941  {
942  LogPrintf("WARNING: WalletBatch::Recover skipping %s: %s\n", strType, strErr);
943  return false;
944  }
945 
946  return true;
947 }
948 
949 bool WalletBatch::VerifyEnvironment(const fs::path& wallet_path, std::string& errorStr)
950 {
951  return BerkeleyBatch::VerifyEnvironment(wallet_path, errorStr);
952 }
953 
954 bool WalletBatch::VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr)
955 {
956  return BerkeleyBatch::VerifyDatabaseFile(wallet_path, warningStr, errorStr, WalletBatch::Recover);
957 }
958 
959 bool WalletBatch::WriteDestData(const std::string& address, const std::string& key, const std::string& value)
960 {
961  return WriteIC(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key)), value);
962 }
963 
964 bool WalletBatch::EraseDestData(const std::string& address, const std::string& key)
965 {
966  return EraseIC(std::make_pair(std::string(DBKeys::DESTDATA), std::make_pair(address, key)));
967 }
968 
970 {
971  return m_batch.TxnBegin();
972 }
973 
975 {
976  return m_batch.TxnCommit();
977 }
978 
980 {
981  return m_batch.TxnAbort();
982 }
983 
984 bool WalletBatch::ReadVersion(int& nVersion)
985 {
986  return m_batch.ReadVersion(nVersion);
987 }
988 
989 bool WalletBatch::WriteVersion(int nVersion)
990 {
991  return m_batch.WriteVersion(nVersion);
992 }
int64_t CAmount
Amount in PIV (Can be negative)
Definition: amount.h:13
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
Definition: system.cpp:449
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
Definition: system.cpp:481
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: system.cpp:465
bool WriteVersion(int nVersion)
Definition: db.h:397
Dbc * GetCursor()
Definition: db.h:315
bool TxnCommit()
Definition: db.h:373
bool ReadVersion(int &nVersion)
Definition: db.h:391
static bool VerifyEnvironment(const fs::path &file_path, std::string &errorStr)
Definition: db.cpp:322
static bool PeriodicFlush(BerkeleyDatabase &database)
Definition: db.cpp:732
bool TxnBegin()
Definition: db.h:362
static bool VerifyDatabaseFile(const fs::path &file_path, std::string &warningStr, std::string &errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
Definition: db.cpp:344
int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue, bool setRange=false)
Definition: db.h:326
bool TxnAbort()
Definition: db.h:382
static bool Recover(const fs::path &file_path, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
Definition: db.cpp:254
bool Read(const K &key, T &value)
Definition: db.h:210
An instance of this class represents one database.
Definition: db.h:105
int64_t nLastWalletUpdate
Definition: db.h:162
unsigned int nLastFlushed
Definition: db.h:161
std::atomic< unsigned int > nUpdateCounter
Definition: db.h:159
unsigned int nLastSeen
Definition: db.h:160
bool empty() const
Definition: streams.h:166
uint8_t chainType
Definition: hdchain.h:38
An encapsulated private key.
Definition: key.h:30
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
Definition: key.cpp:247
int64_t nCreateTime
Definition: walletdb.h:69
A key pool entry.
Definition: wallet.h:125
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key.
Definition: crypter.h:39
An encapsulated public key.
Definition: pubkey.h:44
const unsigned char * end() const
Definition: pubkey.h:124
bool IsValid() const
Definition: pubkey.h:183
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:121
const unsigned char * begin() const
Definition: pubkey.h:123
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:381
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
Definition: wallet.h:577
std::map< uint256, CWalletTx > mapWallet
Definition: wallet.h:766
bool LoadDestData(const CTxDestination &dest, const std::string &key, const std::string &value)
Adds a destination data tuple to the store, without saving it to disk.
Definition: wallet.cpp:4092
bool LoadCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted spending key to the store, without saving it to disk (used by LoadWallet)
Definition: wallet.cpp:4741
MasterKeyMap mapMasterKeys
Definition: wallet.h:729
bool LoadSaplingZKeyMetadata(const libzcash::SaplingIncomingViewingKey &ivk, const CKeyMetadata &meta)
Load spending key metadata (used by LoadWallet)
Definition: wallet.cpp:4740
RecursiveMutex cs_wallet
Definition: wallet.h:720
bool fCombineDust
Definition: wallet.h:744
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
Definition: wallet.h:978
CAmount nStakeSplitThreshold
Definition: wallet.h:733
bool BackupWallet(const std::string &strDest)
Creates a wallet backup in strDest path.
Definition: wallet.cpp:4457
int64_t nTimeFirstKey
Definition: wallet.h:776
bool LoadMinVersion(int nVersion)
Definition: wallet.cpp:4590
CAmount nAutoCombineThreshold
Definition: wallet.h:745
bool LoadSaplingZKey(const libzcash::SaplingExtendedSpendingKey &key)
Adds spending key to the store, without saving it to disk (used by LoadWallet)
Definition: wallet.cpp:4739
bool fUseCustomFee
Definition: wallet.h:740
CAmount nCustomFee
Definition: wallet.h:741
SaplingScriptPubKeyMan * GetSaplingScriptPubKeyMan() const
Definition: wallet.h:712
std::string GetUniqueWalletBackupName() const
Definition: wallet.cpp:4529
bool LoadSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk)
Adds a Sapling payment address -> incoming viewing key map entry, without saving it to disk (used by ...
Definition: wallet.cpp:4744
int frequency
Definition: wallet.h:746
unsigned int nMasterKeyMaxID
Definition: wallet.h:730
int64_t nOrderPosNext
Definition: wallet.h:771
unsigned int nKeyMeta
Definition: walletdb.cpp:335
unsigned int nSapZAddrs
Definition: walletdb.cpp:338
unsigned int nKeys
Definition: walletdb.cpp:333
std::vector< uint256 > vWalletUpgrade
Definition: walletdb.cpp:342
unsigned int nZKeys
Definition: walletdb.cpp:336
unsigned int nZKeyMeta
Definition: walletdb.cpp:337
unsigned int nCKeys
Definition: walletdb.cpp:334
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:325
const uint256 & GetHash() const
Definition: wallet.h:561
unsigned int fTimeReceivedIsTxTime
Definition: wallet.h:338
unsigned int nTimeReceived
Definition: wallet.h:339
int64_t nOrderPos
Definition: wallet.h:346
void setCommonOVK(const uint256 &ovk)
void SetHDChain(CHDChain &chain, bool memonly)
void SetHDChain(CHDChain &chain, bool memonly)
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
Load a keypool entry.
bool TxnCommit()
Commit current transaction.
Definition: walletdb.cpp:974
bool WriteCustomFeeValue(const CAmount &nCustomFee)
Definition: walletdb.cpp:240
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
Definition: walletdb.cpp:191
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
Definition: walletdb.cpp:926
bool ErasePool(int64_t nPool)
Definition: walletdb.cpp:265
bool WriteName(const std::string &strAddress, const std::string &strName)
Definition: walletdb.cpp:70
bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk)
Definition: walletdb.cpp:148
static bool Recover(const fs::path &wallet_path, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
Definition: walletdb.cpp:914
bool WriteMinVersion(int nVersion)
Definition: walletdb.cpp:270
DBErrors ZapWalletTx(CWallet *pwallet, std::vector< CWalletTx > &vWtx)
Definition: walletdb.cpp:795
DBErrors ReorderTransactions(CWallet *pwallet)
Definition: walletdb.cpp:282
BerkeleyBatch m_batch
Definition: walletdb.h:231
static bool IsKeyType(const std::string &strType)
Definition: walletdb.cpp:628
bool ErasePurpose(const std::string &strAddress)
Definition: walletdb.cpp:87
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
Definition: walletdb.cpp:196
bool EraseWatchOnly(const CScript &script)
Definition: walletdb.cpp:206
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:117
DBErrors FindWalletTx(CWallet *pwallet, std::vector< uint256 > &vTxHash, std::vector< CWalletTx > &vWtx)
Definition: walletdb.cpp:735
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Definition: walletdb.cpp:255
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
Definition: walletdb.h:115
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:102
bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:154
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
Definition: walletdb.cpp:964
bool ReadVersion(int &nVersion)
Read wallet version.
Definition: walletdb.cpp:984
static bool VerifyEnvironment(const fs::path &wallet_path, std::string &errorStr)
Definition: walletdb.cpp:949
bool WriteAutoCombineSettings(bool fEnable, CAmount nCombineThreshold, int frequency)
Definition: walletdb.cpp:245
bool ReadSaplingCommonOVK(uint256 &ovkRet)
Definition: walletdb.cpp:181
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external/internal chain child index counter)
Definition: walletdb.cpp:275
bool ReadBestBlock(CBlockLocator &locator)
Definition: walletdb.cpp:217
bool WriteOrderPosNext(int64_t nOrderPosNext)
Definition: walletdb.cpp:225
bool WriteTx(const CWalletTx &wtx)
Definition: walletdb.cpp:92
bool EraseIC(const K &key)
Definition: walletdb.h:125
static bool VerifyDatabaseFile(const fs::path &wallet_path, std::string &warningStr, std::string &errorStr)
Definition: walletdb.cpp:954
bool TxnBegin()
Begin a new transaction.
Definition: walletdb.cpp:969
bool TxnAbort()
Abort current transaction.
Definition: walletdb.cpp:979
bool WritePool(int64_t nPool, const CKeyPool &keypool)
Definition: walletdb.cpp:260
bool WriteWitnessCacheSize(int64_t nWitnessCacheSize)
Definition: walletdb.cpp:186
bool WriteUseCustomFee(bool fUse)
Definition: walletdb.cpp:235
bool WriteBestBlock(const CBlockLocator &locator)
Definition: walletdb.cpp:211
bool WriteVersion(int nVersion)
Write wallet version.
Definition: walletdb.cpp:989
bool WriteWatchOnly(const CScript &script)
Definition: walletdb.cpp:201
bool EraseTx(uint256 hash)
Definition: walletdb.cpp:97
bool WriteStakeSplitThreshold(const CAmount &nStakeSplitThreshold)
Definition: walletdb.cpp:230
bool WriteSaplingCommonOVK(const uint256 &ovk)
Common output viewing key, used when shielding transparent funds.
Definition: walletdb.cpp:176
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
Definition: walletdb.cpp:82
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
Definition: walletdb.cpp:959
bool EraseName(const std::string &strAddress)
Definition: walletdb.cpp:75
DBErrors LoadWallet(CWallet *pwallet)
Definition: walletdb.cpp:635
bool WriteSaplingZKey(const libzcash::SaplingIncomingViewingKey &ivk, const libzcash::SaplingExtendedSpendingKey &key, const CKeyMetadata &keyMeta)
Write extended spending key to wallet database, where the key is the incoming viewing key.
Definition: walletdb.cpp:137
std::string ToString() const
Definition: uint256.cpp:65
bool IsNull() const
Definition: uint256.h:36
SaplingIncomingViewingKey in_viewing_key() const
Definition: address.cpp:45
Sapling functions.
Definition: address.h:30
160-bit opaque blob.
Definition: uint256.h:127
256-bit opaque blob.
Definition: uint256.h:138
void LoadAddressBookPurpose(const CWDestination &dest, const std::string &strPurpose)
Definition: wallet.cpp:3705
void LoadAddressBookName(const CWDestination &dest, const std::string &strName)
Definition: wallet.cpp:3700
bool LoadCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret)
Adds an encrypted key to the store, without saving it to disk (used by LoadWallet)
Definition: wallet.cpp:306
bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
Definition: wallet.cpp:296
ScriptPubKeyMan * GetScriptPubKeyMan() const
Get spkm.
Definition: wallet.cpp:701
bool LoadToWallet(CWalletTx &wtxIn)
Definition: wallet.cpp:983
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
Definition: wallet.cpp:371
bool LoadCScript(const CScript &redeemScript)
Definition: wallet.cpp:334
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
Definition: hash.h:173
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (PRIVATE_KEY_SIZE bytes)
Definition: key.h:20
@ LOCK
Definition: lockunlock.h:16
const std::string ORDERPOSNEXT
Definition: walletdb.cpp:40
const std::string DEFAULTKEY
Definition: walletdb.cpp:32
const std::string CSCRIPT
Definition: walletdb.cpp:31
const std::string TX
Definition: walletdb.cpp:43
const std::string SAP_COMMON_OVK
Definition: walletdb.cpp:52
const std::string SAP_KEYMETA
Definition: walletdb.cpp:48
const std::string BESTBLOCK_NOMERKLE
Definition: walletdb.cpp:28
const std::string DESTDATA
Definition: walletdb.cpp:33
const std::string POOL
Definition: walletdb.cpp:41
const std::string AUTOCOMBINE_V2
Definition: walletdb.cpp:58
const std::string NAME
Definition: walletdb.cpp:39
const std::string SAP_KEY_CRIPTED
Definition: walletdb.cpp:50
const std::string MINVERSION
Definition: walletdb.cpp:38
const std::string HDCHAIN
Definition: walletdb.cpp:34
const std::string VERSION
Definition: walletdb.cpp:44
const std::string KEY
Definition: walletdb.cpp:36
const std::string KEYMETA
Definition: walletdb.cpp:35
const std::string SAP_HDCHAIN
Definition: walletdb.cpp:53
const std::string SAP_ADDR
Definition: walletdb.cpp:51
const std::string AUTOCOMBINE
Definition: walletdb.cpp:57
const std::string MASTER_KEY
Definition: walletdb.cpp:37
const std::string CUSTOM_FEE_VALUE
Definition: walletdb.cpp:61
const std::string WATCHS
Definition: walletdb.cpp:45
const std::string PURPOSE
Definition: walletdb.cpp:42
const std::string SAP_KEY
Definition: walletdb.cpp:49
const std::string STAKE_SPLIT_THRESHOLD
Definition: walletdb.cpp:59
const std::string USE_CUSTOM_FEE
Definition: walletdb.cpp:60
const std::string CRYPTED_KEY
Definition: walletdb.cpp:30
const std::string BESTBLOCK
Definition: walletdb.cpp:29
const std::string SAP_WITNESS_CACHE_SIZE
Definition: walletdb.cpp:54
CWDestination DecodeDestination(const std::string &strAddress)
reverse_range< T > reverse_iterate(T &x)
@ SER_DISK
Definition: serialize.h:175
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
Definition: block.h:154
std::vector< uint256 > vHave
Definition: block.h:155
libzcash::SaplingFullViewingKey fvk
Definition: zip32.h:56
const fs::path & GetDataDir(bool fNetSpecific)
Definition: system.cpp:724
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
Definition: system.cpp:891
ArgsManager gArgs
Definition: system.cpp:89
bool error(const char *fmt, const Args &... args)
Definition: system.h:77
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
Definition: system.h:65
#define strprintf
Definition: tinyformat.h:1056
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
Definition: utiltime.cpp:27
std::vector< CWalletRef > vpwallets
Definition: wallet.cpp:33
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
Definition: walletdb.cpp:812
std::multimap< std::time_t, fs::path > folder_set_t
Definition: walletdb.cpp:841
bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, CWalletScanState &wss, std::string &strType, std::string &strErr)
Definition: walletdb.cpp:353
bool AutoBackupWallet(CWallet &wallet, std::string &strBackupWarning, std::string &strBackupError)
Called during init: Automatic backups.
Definition: walletdb.cpp:880
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:50
@ DB_TOO_NEW
Definition: walletdb.h:54
@ DB_CORRUPT
Definition: walletdb.h:52
@ DB_LOAD_OK
Definition: walletdb.h:51
@ DB_LOAD_FAIL
Definition: walletdb.h:55
@ DB_NONCRITICAL_ERROR
Definition: walletdb.h:53
@ DB_NEED_REWRITE
Definition: walletdb.h:56