BSHA3  0.17.99
P2P Blockchain, based on Bitcoin
walletdb.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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 #include <wallet/walletdb.h>
7 
8 #include <consensus/tx_verify.h>
9 #include <consensus/validation.h>
10 #include <fs.h>
11 #include <key_io.h>
12 #include <protocol.h>
13 #include <serialize.h>
14 #include <sync.h>
15 #include <util.h>
16 #include <utiltime.h>
17 #include <wallet/wallet.h>
18 
19 #include <atomic>
20 #include <string>
21 
22 #include <boost/thread.hpp>
23 
24 //
25 // WalletBatch
26 //
27 
28 bool WalletBatch::WriteName(const std::string& strAddress, const std::string& strName)
29 {
30  return WriteIC(std::make_pair(std::string("name"), strAddress), strName);
31 }
32 
33 bool WalletBatch::EraseName(const std::string& strAddress)
34 {
35  // This should only be used for sending addresses, never for receiving addresses,
36  // receiving addresses must always have an address book entry if they're not change return.
37  return EraseIC(std::make_pair(std::string("name"), strAddress));
38 }
39 
40 bool WalletBatch::WritePurpose(const std::string& strAddress, const std::string& strPurpose)
41 {
42  return WriteIC(std::make_pair(std::string("purpose"), strAddress), strPurpose);
43 }
44 
45 bool WalletBatch::ErasePurpose(const std::string& strAddress)
46 {
47  return EraseIC(std::make_pair(std::string("purpose"), strAddress));
48 }
49 
51 {
52  return WriteIC(std::make_pair(std::string("tx"), wtx.GetHash()), wtx);
53 }
54 
56 {
57  return EraseIC(std::make_pair(std::string("tx"), hash));
58 }
59 
60 bool WalletBatch::WriteKey(const CPubKey& vchPubKey, const CPrivKey& vchPrivKey, const CKeyMetadata& keyMeta)
61 {
62  if (!WriteIC(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta, false)) {
63  return false;
64  }
65 
66  // hash pubkey/privkey to accelerate wallet load
67  std::vector<unsigned char> vchKey;
68  vchKey.reserve(vchPubKey.size() + vchPrivKey.size());
69  vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
70  vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
71 
72  return WriteIC(std::make_pair(std::string("key"), vchPubKey), std::make_pair(vchPrivKey, Hash(vchKey.begin(), vchKey.end())), false);
73 }
74 
75 bool WalletBatch::WriteCryptedKey(const CPubKey& vchPubKey,
76  const std::vector<unsigned char>& vchCryptedSecret,
77  const CKeyMetadata &keyMeta)
78 {
79  if (!WriteIC(std::make_pair(std::string("keymeta"), vchPubKey), keyMeta)) {
80  return false;
81  }
82 
83  if (!WriteIC(std::make_pair(std::string("ckey"), vchPubKey), vchCryptedSecret, false)) {
84  return false;
85  }
86  EraseIC(std::make_pair(std::string("key"), vchPubKey));
87  EraseIC(std::make_pair(std::string("wkey"), vchPubKey));
88  return true;
89 }
90 
91 bool WalletBatch::WriteMasterKey(unsigned int nID, const CMasterKey& kMasterKey)
92 {
93  return WriteIC(std::make_pair(std::string("mkey"), nID), kMasterKey, true);
94 }
95 
96 bool WalletBatch::WriteCScript(const uint160& hash, const CScript& redeemScript)
97 {
98  return WriteIC(std::make_pair(std::string("cscript"), hash), redeemScript, false);
99 }
100 
101 bool WalletBatch::WriteWatchOnly(const CScript &dest, const CKeyMetadata& keyMeta)
102 {
103  if (!WriteIC(std::make_pair(std::string("watchmeta"), dest), keyMeta)) {
104  return false;
105  }
106  return WriteIC(std::make_pair(std::string("watchs"), dest), '1');
107 }
108 
110 {
111  if (!EraseIC(std::make_pair(std::string("watchmeta"), dest))) {
112  return false;
113  }
114  return EraseIC(std::make_pair(std::string("watchs"), dest));
115 }
116 
118 {
119  WriteIC(std::string("bestblock"), CBlockLocator()); // Write empty block locator so versions that require a merkle branch automatically rescan
120  return WriteIC(std::string("bestblock_nomerkle"), locator);
121 }
122 
124 {
125  if (m_batch.Read(std::string("bestblock"), locator) && !locator.vHave.empty()) return true;
126  return m_batch.Read(std::string("bestblock_nomerkle"), locator);
127 }
128 
129 bool WalletBatch::WriteOrderPosNext(int64_t nOrderPosNext)
130 {
131  return WriteIC(std::string("orderposnext"), nOrderPosNext);
132 }
133 
134 bool WalletBatch::ReadPool(int64_t nPool, CKeyPool& keypool)
135 {
136  return m_batch.Read(std::make_pair(std::string("pool"), nPool), keypool);
137 }
138 
139 bool WalletBatch::WritePool(int64_t nPool, const CKeyPool& keypool)
140 {
141  return WriteIC(std::make_pair(std::string("pool"), nPool), keypool);
142 }
143 
144 bool WalletBatch::ErasePool(int64_t nPool)
145 {
146  return EraseIC(std::make_pair(std::string("pool"), nPool));
147 }
148 
150 {
151  return WriteIC(std::string("minversion"), nVersion);
152 }
153 
155 public:
156  unsigned int nKeys;
157  unsigned int nCKeys;
158  unsigned int nWatchKeys;
159  unsigned int nKeyMeta;
160  unsigned int m_unknown_records;
164  std::vector<uint256> vWalletUpgrade;
165 
168  fIsEncrypted = false;
169  fAnyUnordered = false;
170  nFileVersion = 0;
171  }
172 };
173 
174 static bool
175 ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
176  CWalletScanState &wss, std::string& strType, std::string& strErr) EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)
177 {
178  try {
179  // Unserialize
180  // Taking advantage of the fact that pair serialization
181  // is just the two items serialized one after the other
182  ssKey >> strType;
183  if (strType == "name")
184  {
185  std::string strAddress;
186  ssKey >> strAddress;
187  ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)].name;
188  }
189  else if (strType == "purpose")
190  {
191  std::string strAddress;
192  ssKey >> strAddress;
193  ssValue >> pwallet->mapAddressBook[DecodeDestination(strAddress)].purpose;
194  }
195  else if (strType == "tx")
196  {
197  uint256 hash;
198  ssKey >> hash;
199  CWalletTx wtx(nullptr /* pwallet */, MakeTransactionRef());
200  ssValue >> wtx;
201  CValidationState state;
202  if (!(CheckTransaction(*wtx.tx, state) && (wtx.GetHash() == hash) && state.IsValid()))
203  return false;
204 
205  // Undo serialize changes in 31600
206  if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
207  {
208  if (!ssValue.empty())
209  {
210  char fTmp;
211  char fUnused;
212  std::string unused_string;
213  ssValue >> fTmp >> fUnused >> unused_string;
214  strErr = strprintf("LoadWallet() upgrading tx ver=%d %d %s",
215  wtx.fTimeReceivedIsTxTime, fTmp, hash.ToString());
216  wtx.fTimeReceivedIsTxTime = fTmp;
217  }
218  else
219  {
220  strErr = strprintf("LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString());
221  wtx.fTimeReceivedIsTxTime = 0;
222  }
223  wss.vWalletUpgrade.push_back(hash);
224  }
225 
226  if (wtx.nOrderPos == -1)
227  wss.fAnyUnordered = true;
228 
229  pwallet->LoadToWallet(wtx);
230  }
231  else if (strType == "watchs")
232  {
233  wss.nWatchKeys++;
234  CScript script;
235  ssKey >> script;
236  char fYes;
237  ssValue >> fYes;
238  if (fYes == '1')
239  pwallet->LoadWatchOnly(script);
240  }
241  else if (strType == "key" || strType == "wkey")
242  {
243  CPubKey vchPubKey;
244  ssKey >> vchPubKey;
245  if (!vchPubKey.IsValid())
246  {
247  strErr = "Error reading wallet database: CPubKey corrupt";
248  return false;
249  }
250  CKey key;
251  CPrivKey pkey;
252  uint256 hash;
253 
254  if (strType == "key")
255  {
256  wss.nKeys++;
257  ssValue >> pkey;
258  } else {
259  CWalletKey wkey;
260  ssValue >> wkey;
261  pkey = wkey.vchPrivKey;
262  }
263 
264  // Old wallets store keys as "key" [pubkey] => [privkey]
265  // ... which was slow for wallets with lots of keys, because the public key is re-derived from the private key
266  // using EC operations as a checksum.
267  // Newer wallets store keys as "key"[pubkey] => [privkey][hash(pubkey,privkey)], which is much faster while
268  // remaining backwards-compatible.
269  try
270  {
271  ssValue >> hash;
272  }
273  catch (...) {}
274 
275  bool fSkipCheck = false;
276 
277  if (!hash.IsNull())
278  {
279  // hash pubkey/privkey to accelerate wallet load
280  std::vector<unsigned char> vchKey;
281  vchKey.reserve(vchPubKey.size() + pkey.size());
282  vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
283  vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
284 
285  if (Hash(vchKey.begin(), vchKey.end()) != hash)
286  {
287  strErr = "Error reading wallet database: CPubKey/CPrivKey corrupt";
288  return false;
289  }
290 
291  fSkipCheck = true;
292  }
293 
294  if (!key.Load(pkey, vchPubKey, fSkipCheck))
295  {
296  strErr = "Error reading wallet database: CPrivKey corrupt";
297  return false;
298  }
299  if (!pwallet->LoadKey(key, vchPubKey))
300  {
301  strErr = "Error reading wallet database: LoadKey failed";
302  return false;
303  }
304  }
305  else if (strType == "mkey")
306  {
307  unsigned int nID;
308  ssKey >> nID;
309  CMasterKey kMasterKey;
310  ssValue >> kMasterKey;
311  if(pwallet->mapMasterKeys.count(nID) != 0)
312  {
313  strErr = strprintf("Error reading wallet database: duplicate CMasterKey id %u", nID);
314  return false;
315  }
316  pwallet->mapMasterKeys[nID] = kMasterKey;
317  if (pwallet->nMasterKeyMaxID < nID)
318  pwallet->nMasterKeyMaxID = nID;
319  }
320  else if (strType == "ckey")
321  {
322  CPubKey vchPubKey;
323  ssKey >> vchPubKey;
324  if (!vchPubKey.IsValid())
325  {
326  strErr = "Error reading wallet database: CPubKey corrupt";
327  return false;
328  }
329  std::vector<unsigned char> vchPrivKey;
330  ssValue >> vchPrivKey;
331  wss.nCKeys++;
332 
333  if (!pwallet->LoadCryptedKey(vchPubKey, vchPrivKey))
334  {
335  strErr = "Error reading wallet database: LoadCryptedKey failed";
336  return false;
337  }
338  wss.fIsEncrypted = true;
339  }
340  else if (strType == "keymeta")
341  {
342  CPubKey vchPubKey;
343  ssKey >> vchPubKey;
344  CKeyMetadata keyMeta;
345  ssValue >> keyMeta;
346  wss.nKeyMeta++;
347  pwallet->LoadKeyMetadata(vchPubKey.GetID(), keyMeta);
348  }
349  else if (strType == "watchmeta")
350  {
351  CScript script;
352  ssKey >> script;
353  CKeyMetadata keyMeta;
354  ssValue >> keyMeta;
355  wss.nKeyMeta++;
356  pwallet->LoadScriptMetadata(CScriptID(script), keyMeta);
357  }
358  else if (strType == "defaultkey")
359  {
360  // We don't want or need the default key, but if there is one set,
361  // we want to make sure that it is valid so that we can detect corruption
362  CPubKey vchPubKey;
363  ssValue >> vchPubKey;
364  if (!vchPubKey.IsValid()) {
365  strErr = "Error reading wallet database: Default Key corrupt";
366  return false;
367  }
368  }
369  else if (strType == "pool")
370  {
371  int64_t nIndex;
372  ssKey >> nIndex;
373  CKeyPool keypool;
374  ssValue >> keypool;
375 
376  pwallet->LoadKeyPool(nIndex, keypool);
377  }
378  else if (strType == "version")
379  {
380  ssValue >> wss.nFileVersion;
381  if (wss.nFileVersion == 10300)
382  wss.nFileVersion = 300;
383  }
384  else if (strType == "cscript")
385  {
386  uint160 hash;
387  ssKey >> hash;
388  CScript script;
389  ssValue >> script;
390  if (!pwallet->LoadCScript(script))
391  {
392  strErr = "Error reading wallet database: LoadCScript failed";
393  return false;
394  }
395  }
396  else if (strType == "orderposnext")
397  {
398  ssValue >> pwallet->nOrderPosNext;
399  }
400  else if (strType == "destdata")
401  {
402  std::string strAddress, strKey, strValue;
403  ssKey >> strAddress;
404  ssKey >> strKey;
405  ssValue >> strValue;
406  pwallet->LoadDestData(DecodeDestination(strAddress), strKey, strValue);
407  }
408  else if (strType == "hdchain")
409  {
410  CHDChain chain;
411  ssValue >> chain;
412  pwallet->SetHDChain(chain, true);
413  } else if (strType == "flags") {
414  uint64_t flags;
415  ssValue >> flags;
416  if (!pwallet->SetWalletFlags(flags, true)) {
417  strErr = "Error reading wallet database: Unknown non-tolerable wallet flags found";
418  return false;
419  }
420  } else if (strType != "bestblock" && strType != "bestblock_nomerkle" &&
421  strType != "minversion" && strType != "acentry") {
422  wss.m_unknown_records++;
423  }
424  } catch (...)
425  {
426  return false;
427  }
428  return true;
429 }
430 
431 bool WalletBatch::IsKeyType(const std::string& strType)
432 {
433  return (strType== "key" || strType == "wkey" ||
434  strType == "mkey" || strType == "ckey");
435 }
436 
438 {
439  CWalletScanState wss;
440  bool fNoncriticalErrors = false;
441  DBErrors result = DBErrors::LOAD_OK;
442 
443  LOCK(pwallet->cs_wallet);
444  try {
445  int nMinVersion = 0;
446  if (m_batch.Read((std::string)"minversion", nMinVersion))
447  {
448  if (nMinVersion > FEATURE_LATEST)
449  return DBErrors::TOO_NEW;
450  pwallet->LoadMinVersion(nMinVersion);
451  }
452 
453  // Get cursor
454  Dbc* pcursor = m_batch.GetCursor();
455  if (!pcursor)
456  {
457  pwallet->WalletLogPrintf("Error getting wallet database cursor\n");
458  return DBErrors::CORRUPT;
459  }
460 
461  while (true)
462  {
463  // Read next record
464  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
465  CDataStream ssValue(SER_DISK, CLIENT_VERSION);
466  int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
467  if (ret == DB_NOTFOUND)
468  break;
469  else if (ret != 0)
470  {
471  pwallet->WalletLogPrintf("Error reading next record from wallet database\n");
472  return DBErrors::CORRUPT;
473  }
474 
475  // Try to be tolerant of single corrupt records:
476  std::string strType, strErr;
477  if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
478  {
479  // losing keys is considered a catastrophic error, anything else
480  // we assume the user can live with:
481  if (IsKeyType(strType) || strType == "defaultkey") {
482  result = DBErrors::CORRUPT;
483  } else if(strType == "flags") {
484  // reading the wallet flags can only fail if unknown flags are present
485  result = DBErrors::TOO_NEW;
486  } else {
487  // Leave other errors alone, if we try to fix them we might make things worse.
488  fNoncriticalErrors = true; // ... but do warn the user there is something wrong.
489  if (strType == "tx")
490  // Rescan if there is a bad transaction record:
491  gArgs.SoftSetBoolArg("-rescan", true);
492  }
493  }
494  if (!strErr.empty())
495  pwallet->WalletLogPrintf("%s\n", strErr);
496  }
497  pcursor->close();
498  }
499  catch (const boost::thread_interrupted&) {
500  throw;
501  }
502  catch (...) {
503  result = DBErrors::CORRUPT;
504  }
505 
506  if (fNoncriticalErrors && result == DBErrors::LOAD_OK)
508 
509  // Any wallet corruption at all: skip any rewriting or
510  // upgrading, we don't want to make it worse.
511  if (result != DBErrors::LOAD_OK)
512  return result;
513 
514  pwallet->WalletLogPrintf("nFileVersion = %d\n", wss.nFileVersion);
515 
516  pwallet->WalletLogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total. Unknown wallet records: %u\n",
517  wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys, wss.m_unknown_records);
518 
519  // nTimeFirstKey is only reliable if all keys have metadata
520  if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta)
521  pwallet->UpdateTimeFirstKey(1);
522 
523  for (const uint256& hash : wss.vWalletUpgrade)
524  WriteTx(pwallet->mapWallet.at(hash));
525 
526  // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc:
527  if (wss.fIsEncrypted && (wss.nFileVersion == 40000 || wss.nFileVersion == 50000))
528  return DBErrors::NEED_REWRITE;
529 
530  if (wss.nFileVersion < CLIENT_VERSION) // Update
531  WriteVersion(CLIENT_VERSION);
532 
533  if (wss.fAnyUnordered)
534  result = pwallet->ReorderTransactions();
535 
536  return result;
537 }
538 
539 DBErrors WalletBatch::FindWalletTx(std::vector<uint256>& vTxHash, std::vector<CWalletTx>& vWtx)
540 {
541  DBErrors result = DBErrors::LOAD_OK;
542 
543  try {
544  int nMinVersion = 0;
545  if (m_batch.Read((std::string)"minversion", nMinVersion))
546  {
547  if (nMinVersion > FEATURE_LATEST)
548  return DBErrors::TOO_NEW;
549  }
550 
551  // Get cursor
552  Dbc* pcursor = m_batch.GetCursor();
553  if (!pcursor)
554  {
555  LogPrintf("Error getting wallet database cursor\n");
556  return DBErrors::CORRUPT;
557  }
558 
559  while (true)
560  {
561  // Read next record
562  CDataStream ssKey(SER_DISK, CLIENT_VERSION);
563  CDataStream ssValue(SER_DISK, CLIENT_VERSION);
564  int ret = m_batch.ReadAtCursor(pcursor, ssKey, ssValue);
565  if (ret == DB_NOTFOUND)
566  break;
567  else if (ret != 0)
568  {
569  LogPrintf("Error reading next record from wallet database\n");
570  return DBErrors::CORRUPT;
571  }
572 
573  std::string strType;
574  ssKey >> strType;
575  if (strType == "tx") {
576  uint256 hash;
577  ssKey >> hash;
578 
579  CWalletTx wtx(nullptr /* pwallet */, MakeTransactionRef());
580  ssValue >> wtx;
581 
582  vTxHash.push_back(hash);
583  vWtx.push_back(wtx);
584  }
585  }
586  pcursor->close();
587  }
588  catch (const boost::thread_interrupted&) {
589  throw;
590  }
591  catch (...) {
592  result = DBErrors::CORRUPT;
593  }
594 
595  return result;
596 }
597 
598 DBErrors WalletBatch::ZapSelectTx(std::vector<uint256>& vTxHashIn, std::vector<uint256>& vTxHashOut)
599 {
600  // build list of wallet TXs and hashes
601  std::vector<uint256> vTxHash;
602  std::vector<CWalletTx> vWtx;
603  DBErrors err = FindWalletTx(vTxHash, vWtx);
604  if (err != DBErrors::LOAD_OK) {
605  return err;
606  }
607 
608  std::sort(vTxHash.begin(), vTxHash.end());
609  std::sort(vTxHashIn.begin(), vTxHashIn.end());
610 
611  // erase each matching wallet TX
612  bool delerror = false;
613  std::vector<uint256>::iterator it = vTxHashIn.begin();
614  for (const uint256& hash : vTxHash) {
615  while (it < vTxHashIn.end() && (*it) < hash) {
616  it++;
617  }
618  if (it == vTxHashIn.end()) {
619  break;
620  }
621  else if ((*it) == hash) {
622  if(!EraseTx(hash)) {
623  LogPrint(BCLog::DB, "Transaction was found for deletion but returned database error: %s\n", hash.GetHex());
624  delerror = true;
625  }
626  vTxHashOut.push_back(hash);
627  }
628  }
629 
630  if (delerror) {
631  return DBErrors::CORRUPT;
632  }
633  return DBErrors::LOAD_OK;
634 }
635 
636 DBErrors WalletBatch::ZapWalletTx(std::vector<CWalletTx>& vWtx)
637 {
638  // build list of wallet TXs
639  std::vector<uint256> vTxHash;
640  DBErrors err = FindWalletTx(vTxHash, vWtx);
641  if (err != DBErrors::LOAD_OK)
642  return err;
643 
644  // erase each wallet TX
645  for (const uint256& hash : vTxHash) {
646  if (!EraseTx(hash))
647  return DBErrors::CORRUPT;
648  }
649 
650  return DBErrors::LOAD_OK;
651 }
652 
654 {
655  static std::atomic<bool> fOneThread(false);
656  if (fOneThread.exchange(true)) {
657  return;
658  }
659  if (!gArgs.GetBoolArg("-flushwallet", DEFAULT_FLUSHWALLET)) {
660  return;
661  }
662 
663  for (const std::shared_ptr<CWallet>& pwallet : GetWallets()) {
664  WalletDatabase& dbh = pwallet->GetDBHandle();
665 
666  unsigned int nUpdateCounter = dbh.nUpdateCounter;
667 
668  if (dbh.nLastSeen != nUpdateCounter) {
669  dbh.nLastSeen = nUpdateCounter;
670  dbh.nLastWalletUpdate = GetTime();
671  }
672 
673  if (dbh.nLastFlushed != nUpdateCounter && GetTime() - dbh.nLastWalletUpdate >= 2) {
674  if (BerkeleyBatch::PeriodicFlush(dbh)) {
675  dbh.nLastFlushed = nUpdateCounter;
676  }
677  }
678  }
679 
680  fOneThread = false;
681 }
682 
683 //
684 // Try to (very carefully!) recover wallet file if there is a problem.
685 //
686 bool WalletBatch::Recover(const fs::path& wallet_path, void *callbackDataIn, bool (*recoverKVcallback)(void* callbackData, CDataStream ssKey, CDataStream ssValue), std::string& out_backup_filename)
687 {
688  return BerkeleyBatch::Recover(wallet_path, callbackDataIn, recoverKVcallback, out_backup_filename);
689 }
690 
691 bool WalletBatch::Recover(const fs::path& wallet_path, std::string& out_backup_filename)
692 {
693  // recover without a key filter callback
694  // results in recovering all record types
695  return WalletBatch::Recover(wallet_path, nullptr, nullptr, out_backup_filename);
696 }
697 
698 bool WalletBatch::RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
699 {
700  CWallet *dummyWallet = reinterpret_cast<CWallet*>(callbackData);
701  CWalletScanState dummyWss;
702  std::string strType, strErr;
703  bool fReadOK;
704  {
705  // Required in LoadKeyMetadata():
706  LOCK(dummyWallet->cs_wallet);
707  fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue,
708  dummyWss, strType, strErr);
709  }
710  if (!IsKeyType(strType) && strType != "hdchain")
711  return false;
712  if (!fReadOK)
713  {
714  LogPrintf("WARNING: WalletBatch::Recover skipping %s: %s\n", strType, strErr);
715  return false;
716  }
717 
718  return true;
719 }
720 
721 bool WalletBatch::VerifyEnvironment(const fs::path& wallet_path, std::string& errorStr)
722 {
723  return BerkeleyBatch::VerifyEnvironment(wallet_path, errorStr);
724 }
725 
726 bool WalletBatch::VerifyDatabaseFile(const fs::path& wallet_path, std::string& warningStr, std::string& errorStr)
727 {
728  return BerkeleyBatch::VerifyDatabaseFile(wallet_path, warningStr, errorStr, WalletBatch::Recover);
729 }
730 
731 bool WalletBatch::WriteDestData(const std::string &address, const std::string &key, const std::string &value)
732 {
733  return WriteIC(std::make_pair(std::string("destdata"), std::make_pair(address, key)), value);
734 }
735 
736 bool WalletBatch::EraseDestData(const std::string &address, const std::string &key)
737 {
738  return EraseIC(std::make_pair(std::string("destdata"), std::make_pair(address, key)));
739 }
740 
741 
743 {
744  return WriteIC(std::string("hdchain"), chain);
745 }
746 
748 {
749  return WriteIC(std::string("flags"), flags);
750 }
751 
753 {
754  return m_batch.TxnBegin();
755 }
756 
758 {
759  return m_batch.TxnCommit();
760 }
761 
763 {
764  return m_batch.TxnAbort();
765 }
766 
767 bool WalletBatch::ReadVersion(int& nVersion)
768 {
769  return m_batch.ReadVersion(nVersion);
770 }
771 
772 bool WalletBatch::WriteVersion(int nVersion)
773 {
774  return m_batch.WriteVersion(nVersion);
775 }
bool TxnCommit()
Commit current transaction.
Definition: walletdb.cpp:757
bool WriteName(const std::string &strAddress, const std::string &strName)
Definition: walletdb.cpp:28
bool EraseIC(const K &key)
Definition: walletdb.h:153
bool WriteVersion(int nVersion)
Write wallet version.
Definition: walletdb.cpp:772
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
Definition: walletdb.cpp:736
unsigned int nKeyMeta
Definition: walletdb.cpp:159
unsigned int nKeys
Definition: walletdb.cpp:156
bool ErasePurpose(const std::string &strAddress)
Definition: walletdb.cpp:45
unsigned int nWatchKeys
Definition: walletdb.cpp:158
bool ReadBestBlock(CBlockLocator &locator)
Definition: walletdb.cpp:123
CPrivKey vchPrivKey
Definition: wallet.h:559
std::vector< std::shared_ptr< CWallet > > GetWallets()
Definition: dummywallet.cpp:47
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:128
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:75
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn&#39;t already have a value.
Definition: util.cpp:558
bool TxnCommit()
Definition: db.h:372
unsigned int nLastSeen
Definition: db.h:160
#define strprintf
Definition: tinyformat.h:1066
const uint256 & GetHash() const
Definition: wallet.h:283
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
Definition: walletdb.h:143
DBErrors FindWalletTx(std::vector< uint256 > &vTxHash, std::vector< CWalletTx > &vWtx)
Definition: walletdb.cpp:539
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
Definition: walletdb.cpp:598
bool WriteMinVersion(int nVersion)
Definition: walletdb.cpp:149
bool TxnBegin()
Definition: db.h:361
UniValue ret(UniValue::VARR)
Definition: rpcwallet.cpp:1140
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
Definition: walletdb.cpp:742
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
Definition: crypter.h:34
bool IsValid() const
Definition: validation.h:65
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
Definition: walletdb.cpp:101
std::vector< uint256 > vWalletUpgrade
Definition: walletdb.cpp:164
static bool VerifyDatabaseFile(const fs::path &wallet_path, std::string &warningStr, std::string &errorStr)
Definition: walletdb.cpp:726
An instance of this class represents one database.
Definition: db.h:104
unsigned int m_unknown_records
Definition: walletdb.cpp:160
Dbc * GetCursor()
Definition: db.h:314
bool TxnBegin()
Begin a new transaction.
Definition: walletdb.cpp:752
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:221
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
Definition: util.cpp:542
DBErrors ZapWalletTx(std::vector< CWalletTx > &vWtx)
Definition: walletdb.cpp:636
bool WriteTx(const CWalletTx &wtx)
Definition: walletdb.cpp:50
unsigned int nCKeys
Definition: walletdb.cpp:157
DBErrors LoadWallet(CWallet *pwallet)
Definition: walletdb.cpp:437
DBErrors
Error statuses for the wallet database.
Definition: walletdb.h:47
static bool PeriodicFlush(BerkeleyDatabase &database)
Definition: db.cpp:732
bool WriteWalletFlags(const uint64_t flags)
Definition: walletdb.cpp:747
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
Definition: hash.h:119
bool IsNull() const
Definition: uint256.h:32
const unsigned char * begin() const
Definition: pubkey.h:111
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:686
bool EraseWatchOnly(const CScript &script)
Definition: walletdb.cpp:109
bool WriteBestBlock(const CBlockLocator &locator)
Definition: walletdb.cpp:117
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
bool TxnAbort()
Abort current transaction.
Definition: walletdb.cpp:762
bool TxnAbort()
Definition: db.h:381
DBErrors ReorderTransactions()
Definition: wallet.cpp:736
bool Read(const K &key, T &value)
Definition: db.h:209
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:731
static bool IsKeyType(const std::string &strType)
Definition: walletdb.cpp:431
const unsigned char * end() const
Definition: pubkey.h:112
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
Definition: walletdb.cpp:96
void WalletLogPrintf(std::string fmt, Params... parameters) const
Prepends the wallet name in logging output to ease debugging in multi-wallet use cases.
Definition: wallet.h:1136
void UpdateTimeFirstKey(int64_t nCreateTime) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Update wallet first key creation time.
Definition: wallet.cpp:343
static bool VerifyEnvironment(const fs::path &wallet_path, std::string &errorStr)
Definition: walletdb.cpp:721
#define LOCK(cs)
Definition: sync.h:181
An encapsulated public key.
Definition: pubkey.h:30
bool WriteVersion(int nVersion)
Definition: db.h:396
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
Definition: walletdb.cpp:91
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
Definition: walletdb.cpp:653
bool WriteOrderPosNext(int64_t nOrderPosNext)
Definition: walletdb.cpp:129
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
Definition: pubkey.h:109
std::vector< uint256 > vHave
Definition: block.h:130
CCriticalSection cs_wallet
Definition: wallet.h:709
static bool VerifyEnvironment(const fs::path &file_path, std::string &errorStr)
Definition: db.cpp:319
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:250
A transaction with a bunch of additional info that only the owner cares about.
Definition: wallet.h:295
bool ErasePool(int64_t nPool)
Definition: walletdb.cpp:144
bool WritePool(int64_t nPool, const CKeyPool &keypool)
Definition: walletdb.cpp:139
Capture information about block/transaction validation.
Definition: validation.h:26
256-bit opaque blob.
Definition: uint256.h:122
CTxDestination DecodeDestination(const std::string &str)
Definition: key_io.cpp:214
ArgsManager gArgs
Definition: util.cpp:88
BerkeleyBatch m_batch
Definition: walletdb.h:237
#define EXCLUSIVE_LOCKS_REQUIRED(...)
Definition: threadsafety.h:51
int64_t nLastWalletUpdate
Definition: db.h:162
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:384
unsigned int nLastFlushed
Definition: db.h:161
int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue, bool setRange=false)
Definition: db.h:325
Private key that includes an expiration date in case it never gets used.
Definition: wallet.h:556
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:599
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
Definition: walletdb.cpp:40
160-bit opaque blob.
Definition: uint256.h:111
std::atomic< unsigned int > nUpdateCounter
Definition: db.h:159
bool CheckTransaction(const CTransaction &tx, CValidationState &state, bool fCheckDuplicateInputs)
Transaction validation functions.
Definition: tx_verify.cpp:159
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Definition: walletdb.cpp:134
A reference to a CScript: the Hash360 of its serialization (see script.h)
Definition: standard.h:22
bool ReadVersion(int &nVersion)
Definition: db.h:390
bool ReadVersion(int &nVersion)
Read wallet version.
Definition: walletdb.cpp:767
static bool VerifyDatabaseFile(const fs::path &file_path, std::string &warningStr, std::string &errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
Definition: db.cpp:343
bool LoadMinVersion(int nVersion) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
Definition: wallet.h:826
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
Definition: walletdb.cpp:60
int flags
Definition: bsha3-tx.cpp:509
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
Definition: utiltime.cpp:20
An encapsulated private key.
Definition: key.h:27
bool EraseTx(uint256 hash)
Definition: walletdb.cpp:55
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
Definition: walletdb.cpp:698
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
Definition: key.cpp:256
A key pool entry.
Definition: wallet.h:117
bool EraseName(const std::string &strAddress)
Definition: walletdb.cpp:33