25 #include <boost/thread.hpp>
36 const std::string
KEY{
"key"};
39 const std::string
NAME{
"name"};
41 const std::string
POOL{
"pool"};
43 const std::string
TX{
"tx"};
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());
114 return WriteIC(std::make_pair(std::string(
DBKeys::KEY), vchPubKey), std::make_pair(vchPrivKey,
Hash(vchKey.begin(), vchKey.end())),
false);
118 const std::vector<unsigned char>& vchCryptedSecret,
121 const bool fEraseUnencryptedKey =
true;
130 if (fEraseUnencryptedKey) {
155 const std::vector<unsigned char>& vchCryptedSecret,
158 const bool fEraseUnencryptedKey =
true;
166 std::make_pair(extfvk, vchCryptedSecret),
false)) {
170 if (fEraseUnencryptedKey) {
247 std::pair<std::pair<bool, CAmount>,
int> pSettings;
248 pSettings.first.first = fEnable;
249 pSettings.first.second = nCombineThreshold;
250 pSettings.second = frequency;
277 std::string key = chain.
chainType == HDChain::ChainCounterType::Sapling ?
289 typedef std::multimap<int64_t, CWalletTx*> TxItems;
299 std::vector<int64_t> nOrderPosOffsets;
300 for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) {
304 if (nOrderPos == -1) {
305 nOrderPos = nOrderPosNext++;
306 nOrderPosOffsets.push_back(nOrderPos);
311 int64_t nOrderPosOff = 0;
312 for (
const int64_t& nOffsetStart : nOrderPosOffsets) {
313 if (nOrderPos >= nOffsetStart)
316 nOrderPos += nOrderPosOff;
317 nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1);
319 if (!nOrderPosOff)
continue;
361 std::string strAddress;
367 std::string strAddress;
369 std::string strPurpose;
370 ssValue >> strPurpose;
375 CWalletTx wtx(
nullptr , MakeTransactionRef());
382 if (!ssValue.
empty()) {
385 std::string unused_string;
386 ssValue >> fTmp >> fUnused >> unused_string;
387 strErr =
strprintf(
"LoadWallet() upgrading tx ver=%d %d %s",
416 strErr =
"Error reading wallet database: CPubKey corrupt";
435 bool fSkipCheck =
false;
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());
444 if (
Hash(vchKey.begin(), vchKey.end()) != hash) {
445 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
452 if (!key.
Load(pkey, vchPubKey, fSkipCheck)) {
453 strErr =
"Error reading wallet database: CPrivKey corrupt";
456 if (!pwallet->
LoadKey(key, vchPubKey)) {
457 strErr =
"Error reading wallet database: LoadKey failed";
464 ssValue >> kMasterKey;
466 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
475 std::vector<unsigned char> vchPrivKey;
476 ssValue >> vchPrivKey;
480 strErr =
"Error reading wallet database: LoadCryptedKey failed";
501 ssValue >> vchPubKey;
503 strErr =
"Error reading wallet database: Default Key corrupt";
522 strErr =
"Error reading wallet database: LoadCScript failed";
537 std::pair<bool, CAmount> pSettings;
538 ssValue >> pSettings;
547 std::pair<std::pair<bool, CAmount>,
int> pSettings;
548 ssValue >> pSettings;
553 std::string strAddress, strKey, strValue;
558 strErr =
"Error reading wallet database: LoadDestData failed";
575 strErr =
"Error reading wallet database: LoadSaplingZKey failed";
589 std::vector<unsigned char> vchCryptedSecret;
590 ssValue >> vchCryptedSecret;
594 strErr =
"Error reading wallet database: LoadCryptedSaplingZKey failed";
616 strErr =
"Error reading wallet database: LoadSaplingPaymentAddress failed";
638 bool fNoncriticalErrors =
false;
645 if (nMinVersion > CLIENT_VERSION) {
654 LogPrintf(
"Error getting wallet database cursor\n");
663 if (ret == DB_NOTFOUND) {
665 }
else if (ret != 0) {
666 LogPrintf(
"Error reading next record from wallet database\n");
671 std::string strType, strErr;
672 if (!
ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) {
679 fNoncriticalErrors =
true;
686 LogPrintf(
"%s\n", strErr);
689 }
catch (
const boost::thread_interrupted&) {
695 if (fNoncriticalErrors && result ==
DB_LOAD_OK)
705 LogPrintf(
"Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
708 LogPrintf(
"ZKeys: %u plaintext, -- encrypted, %u w/metadata, %u total\n",
737 bool fNoncriticalErrors =
false;
744 if (nMinVersion > CLIENT_VERSION) {
753 LogPrintf(
"Error getting wallet database cursor\n");
762 if (ret == DB_NOTFOUND) {
764 }
else if (ret != 0) {
765 LogPrintf(
"Error reading next record from wallet database\n");
775 CWalletTx wtx(
nullptr , MakeTransactionRef());
778 vTxHash.push_back(hash);
783 }
catch (
const boost::thread_interrupted&) {
789 if (fNoncriticalErrors && result ==
DB_LOAD_OK)
798 std::vector<uint256> vTxHash;
805 for (
uint256& hash : vTxHash) {
814 static std::atomic<bool> fOneThread;
815 if (fOneThread.exchange(
true)) {
842 static folder_set_t buildBackupsMapSortedByLastWrite(
const std::string& strWalletFile,
const fs::path& backupsDir)
845 fs::directory_iterator end_iter;
847 for (fs::directory_iterator dir_iter(backupsDir); dir_iter != end_iter; ++dir_iter) {
849 if (fs::is_regular_file(dir_iter->status())) {
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));
859 static bool cleanWalletBackups(
folder_set_t& folder_set,
int nWalletBackups, std::string& strBackupWarning)
863 for (
const std::pair<const std::time_t, fs::path>& file :
reverse_iterate(folder_set)) {
865 if (counter > nWalletBackups) {
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);
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");
889 fs::path backupsDir =
GetDataDir() /
"backups";
890 backupsDir.make_preferred();
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."));
902 strBackupError =
"Failed to backup wallet";
907 folder_set_t folder_set = buildBackupsMapSortedByLastWrite(backupFile.stem().string(), backupsDir);
908 return cleanWalletBackups(folder_set, nWalletBackups, strBackupWarning);
930 std::string strType, strErr;
936 dummyWss, strType, strErr);
942 LogPrintf(
"WARNING: WalletBatch::Recover skipping %s: %s\n", strType, strErr);
int64_t CAmount
Amount in PIV (Can be negative)
std::string GetArg(const std::string &strArg, const std::string &strDefault) const
Return string argument or default value.
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool WriteVersion(int nVersion)
bool ReadVersion(int &nVersion)
static bool VerifyEnvironment(const fs::path &file_path, std::string &errorStr)
static bool PeriodicFlush(BerkeleyDatabase &database)
static bool VerifyDatabaseFile(const fs::path &file_path, std::string &warningStr, std::string &errorStr, BerkeleyEnvironment::recoverFunc_type recoverFunc)
int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue, bool setRange=false)
static bool Recover(const fs::path &file_path, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
bool Read(const K &key, T &value)
An instance of this class represents one database.
int64_t nLastWalletUpdate
unsigned int nLastFlushed
std::atomic< unsigned int > nUpdateCounter
An encapsulated private key.
bool Load(const CPrivKey &privkey, const CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key.
An encapsulated public key.
const unsigned char * end() const
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
const unsigned char * begin() const
Serialized script, used inside transaction inputs and outputs.
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances,...
std::map< uint256, CWalletTx > mapWallet
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.
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)
MasterKeyMap mapMasterKeys
bool LoadSaplingZKeyMetadata(const libzcash::SaplingIncomingViewingKey &ivk, const CKeyMetadata &meta)
Load spending key metadata (used by LoadWallet)
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
CAmount nStakeSplitThreshold
bool BackupWallet(const std::string &strDest)
Creates a wallet backup in strDest path.
bool LoadMinVersion(int nVersion)
CAmount nAutoCombineThreshold
bool LoadSaplingZKey(const libzcash::SaplingExtendedSpendingKey &key)
Adds spending key to the store, without saving it to disk (used by LoadWallet)
SaplingScriptPubKeyMan * GetSaplingScriptPubKeyMan() const
std::string GetUniqueWalletBackupName() const
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 ...
unsigned int nMasterKeyMaxID
std::vector< uint256 > vWalletUpgrade
A transaction with a bunch of additional info that only the owner cares about.
const uint256 & GetHash() const
unsigned int fTimeReceivedIsTxTime
unsigned int nTimeReceived
int64_t nWitnessCacheSize
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.
bool WriteCustomFeeValue(const CAmount &nCustomFee)
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
bool ErasePool(int64_t nPool)
bool WriteName(const std::string &strAddress, const std::string &strName)
bool WriteSaplingPaymentAddress(const libzcash::SaplingPaymentAddress &addr, const libzcash::SaplingIncomingViewingKey &ivk)
static bool Recover(const fs::path &wallet_path, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
bool WriteMinVersion(int nVersion)
DBErrors ZapWalletTx(CWallet *pwallet, std::vector< CWalletTx > &vWtx)
DBErrors ReorderTransactions(CWallet *pwallet)
static bool IsKeyType(const std::string &strType)
bool ErasePurpose(const std::string &strAddress)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool EraseWatchOnly(const CScript &script)
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
DBErrors FindWalletTx(CWallet *pwallet, std::vector< uint256 > &vTxHash, std::vector< CWalletTx > &vWtx)
bool ReadPool(int64_t nPool, CKeyPool &keypool)
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool WriteCryptedSaplingZKey(const libzcash::SaplingExtendedFullViewingKey &extfvk, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
bool ReadVersion(int &nVersion)
Read wallet version.
static bool VerifyEnvironment(const fs::path &wallet_path, std::string &errorStr)
bool WriteAutoCombineSettings(bool fEnable, CAmount nCombineThreshold, int frequency)
bool ReadSaplingCommonOVK(uint256 &ovkRet)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external/internal chain child index counter)
bool ReadBestBlock(CBlockLocator &locator)
bool WriteOrderPosNext(int64_t nOrderPosNext)
bool WriteTx(const CWalletTx &wtx)
bool EraseIC(const K &key)
static bool VerifyDatabaseFile(const fs::path &wallet_path, std::string &warningStr, std::string &errorStr)
bool TxnBegin()
Begin a new transaction.
bool TxnAbort()
Abort current transaction.
bool WritePool(int64_t nPool, const CKeyPool &keypool)
bool WriteWitnessCacheSize(int64_t nWitnessCacheSize)
bool WriteUseCustomFee(bool fUse)
bool WriteBestBlock(const CBlockLocator &locator)
bool WriteVersion(int nVersion)
Write wallet version.
bool WriteWatchOnly(const CScript &script)
bool EraseTx(uint256 hash)
bool WriteStakeSplitThreshold(const CAmount &nStakeSplitThreshold)
bool WriteSaplingCommonOVK(const uint256 &ovk)
Common output viewing key, used when shielding transparent funds.
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
bool EraseName(const std::string &strAddress)
DBErrors LoadWallet(CWallet *pwallet)
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.
std::string ToString() const
SaplingIncomingViewingKey in_viewing_key() const
void LoadAddressBookPurpose(const CWDestination &dest, const std::string &strPurpose)
void LoadAddressBookName(const CWDestination &dest, const std::string &strName)
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)
bool LoadKeyMetadata(const CPubKey &pubkey, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
ScriptPubKeyMan * GetScriptPubKeyMan() const
Get spkm.
bool LoadToWallet(CWalletTx &wtxIn)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet)
bool LoadCScript(const CScript &redeemScript)
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
CPrivKey is a serialized private key, with all parameters included (PRIVATE_KEY_SIZE bytes)
const std::string ORDERPOSNEXT
const std::string DEFAULTKEY
const std::string CSCRIPT
const std::string SAP_COMMON_OVK
const std::string SAP_KEYMETA
const std::string BESTBLOCK_NOMERKLE
const std::string DESTDATA
const std::string AUTOCOMBINE_V2
const std::string SAP_KEY_CRIPTED
const std::string MINVERSION
const std::string HDCHAIN
const std::string VERSION
const std::string KEYMETA
const std::string SAP_HDCHAIN
const std::string SAP_ADDR
const std::string AUTOCOMBINE
const std::string MASTER_KEY
const std::string CUSTOM_FEE_VALUE
const std::string PURPOSE
const std::string SAP_KEY
const std::string STAKE_SPLIT_THRESHOLD
const std::string USE_CUSTOM_FEE
const std::string CRYPTED_KEY
const std::string BESTBLOCK
const std::string SAP_WITNESS_CACHE_SIZE
CWDestination DecodeDestination(const std::string &strAddress)
reverse_range< T > reverse_iterate(T &x)
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
std::vector< uint256 > vHave
libzcash::SaplingFullViewingKey fvk
const fs::path & GetDataDir(bool fNetSpecific)
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by Boost's create_directories if the requested directory exists.
bool error(const char *fmt, const Args &... args)
std::string _(const char *psz)
Translation function: Call Translate signal on UI interface, which returns a Optional result.
int64_t GetTime()
DEPRECATED Use either GetSystemTimeInSeconds (not mockable) or GetTime<T> (mockable)
std::vector< CWalletRef > vpwallets
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
std::multimap< std::time_t, fs::path > folder_set_t
bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, CWalletScanState &wss, std::string &strType, std::string &strErr)
bool AutoBackupWallet(CWallet &wallet, std::string &strBackupWarning, std::string &strBackupError)
Called during init: Automatic backups.
DBErrors
Error statuses for the wallet database.