22 #include <boost/thread.hpp> 30 return WriteIC(std::make_pair(std::string(
"name"), strAddress), strName);
37 return EraseIC(std::make_pair(std::string(
"name"), strAddress));
42 return WriteIC(std::make_pair(std::string(
"purpose"), strAddress), strPurpose);
47 return EraseIC(std::make_pair(std::string(
"purpose"), strAddress));
52 return WriteIC(std::make_pair(std::string(
"tx"), wtx.
GetHash()), wtx);
57 return EraseIC(std::make_pair(std::string(
"tx"), hash));
62 if (!
WriteIC(std::make_pair(std::string(
"keymeta"), vchPubKey), keyMeta,
false)) {
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());
72 return WriteIC(std::make_pair(std::string(
"key"), vchPubKey), std::make_pair(vchPrivKey,
Hash(vchKey.begin(), vchKey.end())),
false);
76 const std::vector<unsigned char>& vchCryptedSecret,
79 if (!
WriteIC(std::make_pair(std::string(
"keymeta"), vchPubKey), keyMeta)) {
83 if (!
WriteIC(std::make_pair(std::string(
"ckey"), vchPubKey), vchCryptedSecret,
false)) {
86 EraseIC(std::make_pair(std::string(
"key"), vchPubKey));
87 EraseIC(std::make_pair(std::string(
"wkey"), vchPubKey));
93 return WriteIC(std::make_pair(std::string(
"mkey"), nID), kMasterKey,
true);
98 return WriteIC(std::make_pair(std::string(
"cscript"), hash), redeemScript,
false);
103 if (!
WriteIC(std::make_pair(std::string(
"watchmeta"), dest), keyMeta)) {
106 return WriteIC(std::make_pair(std::string(
"watchs"), dest),
'1');
111 if (!
EraseIC(std::make_pair(std::string(
"watchmeta"), dest))) {
114 return EraseIC(std::make_pair(std::string(
"watchs"), dest));
120 return WriteIC(std::string(
"bestblock_nomerkle"), locator);
125 if (
batch.
Read(std::string(
"bestblock"), locator) && !locator.
vHave.empty())
return true;
126 return batch.
Read(std::string(
"bestblock_nomerkle"), locator);
131 return WriteIC(std::string(
"orderposnext"), nOrderPosNext);
136 return batch.
Read(std::make_pair(std::string(
"pool"), nPool), keypool);
141 return WriteIC(std::make_pair(std::string(
"pool"), nPool), keypool);
146 return EraseIC(std::make_pair(std::string(
"pool"), nPool));
151 return WriteIC(std::string(
"minversion"), nVersion);
157 return batch.
Read(std::make_pair(std::string(
"acc"), strAccount), account);
162 return WriteIC(std::make_pair(std::string(
"acc"), strAccount), account);
167 return WriteIC(std::make_pair(std::string(
"acentry"), std::make_pair(acentry.
strAccount, nAccEntryNum)), acentry);
172 std::list<CAccountingEntry> entries;
177 nCreditDebit += entry.nCreditDebit;
184 bool fAllAccounts = (strAccount ==
"*");
188 throw std::runtime_error(std::string(__func__) +
": cannot create DB cursor");
189 bool setRange =
true;
195 ssKey << std::make_pair(std::string(
"acentry"), std::make_pair((fAllAccounts ? std::string(
"") : strAccount), uint64_t(0)));
199 if (ret == DB_NOTFOUND)
204 throw std::runtime_error(std::string(__func__) +
": error scanning DB");
210 if (strType !=
"acentry")
214 if (!fAllAccounts && acentry.
strAccount != strAccount)
218 ssKey >> acentry.nEntryNo;
219 entries.push_back(acentry);
237 nKeys = nCKeys = nWatchKeys = nKeyMeta = 0;
238 fIsEncrypted =
false;
239 fAnyUnordered =
false;
252 if (strType ==
"name")
254 std::string strAddress;
258 else if (strType ==
"purpose")
260 std::string strAddress;
264 else if (strType ==
"tx")
275 if (state.
GetRejectReason() !=
"bad-txns-is-asset-and-asset-not-active") {
282 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
284 if (!ssValue.
empty())
288 ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
289 strErr =
strprintf(
"LoadWallet() upgrading tx ver=%d %d '%s' %s",
290 wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount, hash.ToString());
291 wtx.fTimeReceivedIsTxTime = fTmp;
295 strErr =
strprintf(
"LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString());
296 wtx.fTimeReceivedIsTxTime = 0;
301 if (wtx.nOrderPos == -1)
306 else if (strType ==
"acentry")
308 std::string strAccount;
320 if (acentry.nOrderPos == -1)
324 else if (strType ==
"watchs")
334 else if (strType ==
"key" || strType ==
"wkey")
338 if (!vchPubKey.IsValid())
340 strErr =
"Error reading wallet database: CPubKey corrupt";
347 if (strType ==
"key")
368 bool fSkipCheck =
false;
373 std::vector<unsigned char> vchKey;
374 vchKey.reserve(vchPubKey.size() + pkey.size());
375 vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
376 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
378 if (
Hash(vchKey.begin(), vchKey.end()) != hash)
380 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
387 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
389 strErr =
"Error reading wallet database: CPrivKey corrupt";
392 if (!pwallet->
LoadKey(key, vchPubKey))
394 strErr =
"Error reading wallet database: LoadKey failed";
398 else if (strType ==
"mkey")
403 ssValue >> kMasterKey;
406 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
413 else if (strType ==
"ckey")
417 if (!vchPubKey.IsValid())
419 strErr =
"Error reading wallet database: CPubKey corrupt";
422 std::vector<unsigned char> vchPrivKey;
423 ssValue >> vchPrivKey;
428 strErr =
"Error reading wallet database: LoadCryptedKey failed";
433 else if (strType ==
"keymeta" || strType ==
"watchmeta")
436 if (strType ==
"keymeta")
440 keyID = vchPubKey.
GetID();
442 else if (strType ==
"watchmeta")
455 else if (strType ==
"defaultkey")
460 ssValue >> vchPubKey;
461 if (!vchPubKey.IsValid()) {
462 strErr =
"Error reading wallet database: Default Key corrupt";
466 else if (strType ==
"pool")
475 else if (strType ==
"version")
481 else if (strType ==
"cscript")
489 strErr =
"Error reading wallet database: LoadCScript failed";
493 else if (strType ==
"orderposnext")
497 else if (strType ==
"destdata")
499 std::string strAddress, strKey, strValue;
505 strErr =
"Error reading wallet database: LoadDestData failed";
509 else if (strType ==
"hdchain")
515 strErr =
"Error reading wallet database: SetHDChain failed";
528 return (strType==
"key" || strType ==
"wkey" ||
529 strType ==
"mkey" || strType ==
"ckey");
535 bool fNoncriticalErrors =
false;
541 if (
batch.
Read((std::string)
"minversion", nMinVersion))
543 if (nMinVersion > CLIENT_VERSION)
552 LogPrintf(
"Error getting wallet database cursor\n");
562 if (ret == DB_NOTFOUND)
566 LogPrintf(
"Error reading next record from wallet database\n");
571 std::string strType, strErr;
572 if (!
ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
576 if (
IsKeyType(strType) || strType ==
"defaultkey")
581 fNoncriticalErrors =
true;
582 if (strType ==
"tx") {
593 catch (
const boost::thread_interrupted&) {
600 if (fNoncriticalErrors && result ==
DB_LOAD_OK)
610 LogPrintf(
"Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
641 bool fNoncriticalErrors =
false;
646 if (
batch.
Read((std::string)
"minversion", nMinVersion))
648 if (nMinVersion > CLIENT_VERSION)
656 LogPrintf(
"Error getting wallet database cursor\n");
666 if (ret == DB_NOTFOUND)
670 LogPrintf(
"Error reading next record from wallet database\n");
676 if (strType ==
"tx") {
683 vTxHash.push_back(hash);
689 catch (
const boost::thread_interrupted&) {
696 if (fNoncriticalErrors && result ==
DB_LOAD_OK)
705 std::vector<uint256> vTxHash;
706 std::vector<CWalletTx> vWtx;
712 std::sort(vTxHash.begin(), vTxHash.end());
713 std::sort(vTxHashIn.begin(), vTxHashIn.end());
716 bool delerror =
false;
717 std::vector<uint256>::iterator it = vTxHashIn.begin();
719 while (it < vTxHashIn.end() && (*it) < hash) {
722 if (it == vTxHashIn.end()) {
725 else if ((*it) == hash) {
727 LogPrint(
BCLog::DB,
"Transaction was found for deletion but returned database error: %s\n", hash.GetHex());
730 vTxHashOut.push_back(hash);
743 std::vector<uint256> vTxHash;
749 for (
uint256& hash : vTxHash) {
759 static std::atomic<bool> fOneThread(
false);
760 if (fOneThread.exchange(
true)) {
792 return CDB::Recover(filename, callbackDataIn, recoverKVcallback, out_backup_filename);
806 std::string strType, strErr;
812 dummyWss, strType, strErr);
814 if (!
IsKeyType(strType) && strType !=
"hdchain")
818 LogPrintf(
"WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr);
837 return WriteIC(std::make_pair(std::string(
"destdata"), std::make_pair(address, key)), value);
842 return EraseIC(std::make_pair(std::string(
"destdata"), std::make_pair(address, key)));
848 return WriteIC(std::string(
"hdchain"), chain);
bool WriteMinVersion(int nVersion)
int64_t nOrderPos
position in ordered transaction list
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
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 WriteAccount(const std::string &strAccount, const CAccount &account)
Describes a place in the block chain to another node such that if the other node doesn't have the sam...
bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, CWalletScanState &wss, std::string &strType, std::string &strErr)
uint64_t nAccountingEntryNumber
bool SoftSetBoolArg(const std::string &strArg, bool fValue)
Set a boolean argument if it doesn't already have a value.
bool WriteTx(const CWalletTx &wtx)
bool TxnBegin()
Begin a new transaction.
bool WriteIC(const K &key, const T &value, bool fOverwrite=true)
std::map< CTxDestination, CAddressBookData > mapAddressBook
CCriticalSection cs_wallet
const uint256 & GetHash() const
bool WriteMasterKey(unsigned int nID, const CMasterKey &kMasterKey)
bool TxnCommit()
Commit current transaction.
bool WriteCryptedKey(const CPubKey &vchPubKey, const std::vector< unsigned char > &vchCryptedSecret, const CKeyMetadata &keyMeta)
Private key encryption is done based on a CMasterKey, which holds a salt and random encryption key...
CTxDestination DecodeDestination(const std::string &str)
std::vector< uint256 > vWalletUpgrade
bool EraseIC(const K &key)
static bool VerifyDatabaseFile(const std::string &walletFile, const fs::path &dataDir, std::string &warningStr, std::string &errorStr, CDBEnv::recoverFunc_type recoverFunc)
std::vector< CWalletRef > vpwallets
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &acentries)
Double ended buffer combining vector and stream-like interfaces.
bool GetBoolArg(const std::string &strArg, bool fDefault) const
Return boolean argument or default value.
bool ErasePurpose(const std::string &strAddress)
bool WriteAccountingEntry(const uint64_t nAccEntryNum, const CAccountingEntry &acentry)
This writes directly to the database, and will not update the CWallet's cached accounting entries! Us...
DBErrors
Error statuses for the wallet database.
void LoadKeyPool(int64_t nIndex, const CKeyPool &keypool)
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
const unsigned char * begin() const
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 WriteVersion(int nVersion)
Write wallet version.
bool WriteOrderPosNext(int64_t nOrderPosNext)
static bool RecoverKeysOnlyFilter(void *callbackData, CDataStream ssKey, CDataStream ssValue)
std::atomic< unsigned int > nUpdateCounter
bool EraseTx(uint256 hash)
std::list< CAccountingEntry > laccentries
int64_t CAmount
Amount in corbies (Can be negative)
std::vector< unsigned char, secure_allocator< unsigned char > > CPrivKey
secp256k1: const unsigned int PRIVATE_KEY_SIZE = 279; const unsigned int PUBLIC_KEY_SIZE = 65; const ...
DBErrors ReorderTransactions()
An instance of this class represents one database.
unsigned int nMasterKeyMaxID
static bool VerifyEnvironment(const std::string &walletFile, const fs::path &dataDir, std::string &errorStr)
const unsigned char * end() const
bool EraseDestData(const std::string &address, const std::string &key)
Erase destination data tuple from wallet database.
bool WritePool(int64_t nPool, const CKeyPool &keypool)
static bool VerifyEnvironment(const std::string &walletFile, const fs::path &dataDir, std::string &errorStr)
bool WriteName(const std::string &strAddress, const std::string &strName)
DBErrors LoadWallet(CWallet *pwallet)
bool ReadVersion(int &nVersion)
An encapsulated public key.
std::string GetRejectReason() const
static bool VerifyDatabaseFile(const std::string &walletFile, const fs::path &dataDir, std::string &warningStr, std::string &errorStr)
bool LoadKey(const CKey &key, const CPubKey &pubkey)
Adds a key to the store, without saving it to disk (used by LoadWallet)
unsigned int nLastFlushed
bool WriteDestData(const std::string &address, const std::string &key, const std::string &value)
Write destination data key,value tuple to database.
void UpdateTimeFirstKey(int64_t nCreateTime)
Update wallet first key creation time.
void MaybeCompactWalletDB()
Compacts BDB state so that wallet.dat is self-contained (if there are changes)
uint256 Hash(const T1 pbegin, const T1 pend)
Compute the 256-bit hash of an object.
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
static bool Recover(const std::string &filename, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
std::vector< uint256 > vHave
bool LoadToWallet(const CWalletTx &wtxIn)
bool ErasePool(int64_t nPool)
bool EraseWatchOnly(const CScript &script)
int64_t nLastWalletUpdate
bool LoadMinVersion(int nVersion)
static bool Recover(const std::string &filename, void *callbackDataIn, bool(*recoverKVcallback)(void *callbackData, CDataStream ssKey, CDataStream ssValue), std::string &out_backup_filename)
bool Read(const K &key, T &value)
bool Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck)
Load private key and check that public key matches.
A transaction with a bunch of additional info that only the owner cares about.
DBErrors ZapWalletTx(std::vector< CWalletTx > &vWtx)
DBErrors FindWalletTx(std::vector< uint256 > &vTxHash, std::vector< CWalletTx > &vWtx)
bool ReadBestBlock(CBlockLocator &locator)
#define LogPrint(category,...)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
bool WriteBestBlock(const CBlockLocator &locator)
MasterKeyMap mapMasterKeys
bool LoadKeyMetadata(const CTxDestination &pubKey, const CKeyMetadata &metadata)
Load metadata (used by LoadWallet)
bool ReadPool(int64_t nPool, CKeyPool &keypool)
Serialized script, used inside transaction inputs and outputs.
CAmount GetAccountCreditDebit(const std::string &strAccount)
bool WriteVersion(int nVersion)
Private key that includes an expiration date in case it never gets used.
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
bool SetHDChain(const CHDChain &chain, bool memonly)
bool LoadCScript(const CScript &redeemScript)
int ReadAtCursor(Dbc *pcursor, CDataStream &ssKey, CDataStream &ssValue, bool setRange=false)
bool CheckTransaction(const CTransaction &tx, CValidationState &state, bool fCheckDuplicateInputs)
Transaction validation functions.
std::map< uint256, CWalletTx > mapWallet
A reference to a CScript: the Hash160 of its serialization (see script.h)
bool TxnAbort()
Abort current transaction.
int64_t GetTime()
GetTimeMicros() and GetTimeMillis() both return the system time, but in different units...
An encapsulated private key.
bool EraseName(const std::string &strAddress)
bool WriteCScript(const uint160 &hash, const CScript &redeemScript)
bool WritePurpose(const std::string &strAddress, const std::string &purpose)
std::pair< CWalletTx *, CAccountingEntry * > TxPair
static bool PeriodicFlush(CWalletDBWrapper &dbw)
DBErrors ZapSelectTx(std::vector< uint256 > &vHashIn, std::vector< uint256 > &vHashOut)
static bool IsKeyType(const std::string &strType)
bool WriteWatchOnly(const CScript &script, const CKeyMetadata &keymeta)
bool ReadAccount(const std::string &strAccount, CAccount &account)
bool LoadWatchOnly(const CScript &dest)
Adds a watch-only address to the store, without saving it to disk (used by LoadWallet) ...
bool WriteKey(const CPubKey &vchPubKey, const CPrivKey &vchPrivKey, const CKeyMetadata &keyMeta)
bool ReadVersion(int &nVersion)
Read wallet version.