21 #include <boost/thread.hpp> 29 return WriteIC(std::make_pair(std::string(
"name"), strAddress), strName);
36 return EraseIC(std::make_pair(std::string(
"name"), strAddress));
41 return WriteIC(std::make_pair(std::string(
"purpose"), strAddress), strPurpose);
46 return EraseIC(std::make_pair(std::string(
"purpose"), strPurpose));
51 return WriteIC(std::make_pair(std::string(
"tx"), wtx.
GetHash()), wtx);
56 return EraseIC(std::make_pair(std::string(
"tx"), hash));
61 if (!
WriteIC(std::make_pair(std::string(
"keymeta"), vchPubKey), keyMeta,
false)) {
66 std::vector<unsigned char> vchKey;
67 vchKey.reserve(vchPubKey.
size() + vchPrivKey.size());
68 vchKey.insert(vchKey.end(), vchPubKey.
begin(), vchPubKey.
end());
69 vchKey.insert(vchKey.end(), vchPrivKey.begin(), vchPrivKey.end());
71 return WriteIC(std::make_pair(std::string(
"key"), vchPubKey), std::make_pair(vchPrivKey,
Hash(vchKey.begin(), vchKey.end())),
false);
75 const std::vector<unsigned char>& vchCryptedSecret,
78 if (!
WriteIC(std::make_pair(std::string(
"keymeta"), vchPubKey), keyMeta)) {
82 if (!
WriteIC(std::make_pair(std::string(
"ckey"), vchPubKey), vchCryptedSecret,
false)) {
85 EraseIC(std::make_pair(std::string(
"key"), vchPubKey));
86 EraseIC(std::make_pair(std::string(
"wkey"), vchPubKey));
92 return WriteIC(std::make_pair(std::string(
"mkey"), nID), kMasterKey,
true);
97 return WriteIC(std::make_pair(std::string(
"cscript"), hash), redeemScript,
false);
102 if (!
WriteIC(std::make_pair(std::string(
"watchmeta"), dest), keyMeta)) {
105 return WriteIC(std::make_pair(std::string(
"watchs"), dest),
'1');
110 if (!
EraseIC(std::make_pair(std::string(
"watchmeta"), dest))) {
113 return EraseIC(std::make_pair(std::string(
"watchs"), dest));
119 return WriteIC(std::string(
"bestblock_nomerkle"), locator);
124 if (
batch.
Read(std::string(
"bestblock"), locator) && !locator.
vHave.empty())
return true;
125 return batch.
Read(std::string(
"bestblock_nomerkle"), locator);
130 return WriteIC(std::string(
"orderposnext"), nOrderPosNext);
135 return WriteIC(std::string(
"defaultkey"), vchPubKey);
140 return batch.
Read(std::make_pair(std::string(
"pool"), nPool), keypool);
145 return WriteIC(std::make_pair(std::string(
"pool"), nPool), keypool);
150 return EraseIC(std::make_pair(std::string(
"pool"), nPool));
155 return WriteIC(std::string(
"minversion"), nVersion);
161 return batch.
Read(std::make_pair(std::string(
"acc"), strAccount), account);
166 return WriteIC(std::make_pair(std::string(
"acc"), strAccount), account);
171 return WriteIC(std::make_pair(std::string(
"acentry"), std::make_pair(acentry.
strAccount, nAccEntryNum)), acentry);
176 std::list<CAccountingEntry> entries;
181 nCreditDebit += entry.nCreditDebit;
188 bool fAllAccounts = (strAccount ==
"*");
192 throw std::runtime_error(std::string(__func__) +
": cannot create DB cursor");
193 bool setRange =
true;
199 ssKey << std::make_pair(std::string(
"acentry"), std::make_pair((fAllAccounts ? std::string(
"") : strAccount), uint64_t(0)));
203 if (ret == DB_NOTFOUND)
208 throw std::runtime_error(std::string(__func__) +
": error scanning DB");
214 if (strType !=
"acentry")
218 if (!fAllAccounts && acentry.
strAccount != strAccount)
222 ssKey >> acentry.nEntryNo;
223 entries.push_back(acentry);
241 nKeys = nCKeys = nWatchKeys = nKeyMeta = 0;
242 fIsEncrypted =
false;
243 fAnyUnordered =
false;
257 if (strType ==
"name")
259 std::string strAddress;
263 else if (strType ==
"purpose")
265 std::string strAddress;
269 else if (strType ==
"tx")
280 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
282 if (!ssValue.
empty())
286 ssValue >> fTmp >> fUnused >> wtx.strFromAccount;
287 strErr =
strprintf(
"LoadWallet() upgrading tx ver=%d %d '%s' %s",
288 wtx.fTimeReceivedIsTxTime, fTmp, wtx.strFromAccount, hash.ToString());
289 wtx.fTimeReceivedIsTxTime = fTmp;
293 strErr =
strprintf(
"LoadWallet() repairing tx ver=%d %s", wtx.fTimeReceivedIsTxTime, hash.ToString());
294 wtx.fTimeReceivedIsTxTime = 0;
299 if (wtx.nOrderPos == -1)
304 else if (strType ==
"acentry")
306 std::string strAccount;
318 if (acentry.nOrderPos == -1)
322 else if (strType ==
"watchs")
332 else if (strType ==
"key" || strType ==
"wkey")
336 if (!vchPubKey.IsValid())
338 strErr =
"Error reading wallet database: CPubKey corrupt";
345 if (strType ==
"key")
366 bool fSkipCheck =
false;
371 std::vector<unsigned char> vchKey;
372 vchKey.reserve(vchPubKey.size() + pkey.size());
373 vchKey.insert(vchKey.end(), vchPubKey.begin(), vchPubKey.end());
374 vchKey.insert(vchKey.end(), pkey.begin(), pkey.end());
376 if (
Hash(vchKey.begin(), vchKey.end()) != hash)
378 strErr =
"Error reading wallet database: CPubKey/CPrivKey corrupt";
385 if (!key.
Load(pkey, vchPubKey, fSkipCheck))
387 strErr =
"Error reading wallet database: CPrivKey corrupt";
390 if (!pwallet->
LoadKey(key, vchPubKey))
392 strErr =
"Error reading wallet database: LoadKey failed";
396 else if (strType ==
"mkey")
401 ssValue >> kMasterKey;
404 strErr =
strprintf(
"Error reading wallet database: duplicate CMasterKey id %u", nID);
411 else if (strType ==
"ckey")
415 if (!vchPubKey.IsValid())
417 strErr =
"Error reading wallet database: CPubKey corrupt";
420 std::vector<unsigned char> vchPrivKey;
421 ssValue >> vchPrivKey;
426 strErr =
"Error reading wallet database: LoadCryptedKey failed";
431 else if (strType ==
"keymeta" || strType ==
"watchmeta")
434 if (strType ==
"keymeta")
438 keyID = vchPubKey.
GetID();
440 else if (strType ==
"watchmeta")
453 else if (strType ==
"defaultkey")
457 else if (strType ==
"pool")
466 else if (strType ==
"version")
472 else if (strType ==
"cscript")
480 strErr =
"Error reading wallet database: LoadCScript failed";
484 else if (strType ==
"orderposnext")
488 else if (strType ==
"destdata")
490 std::string strAddress, strKey, strValue;
496 strErr =
"Error reading wallet database: LoadDestData failed";
500 else if (strType ==
"hdchain")
506 strErr =
"Error reading wallet database: SetHDChain failed";
510 else if (strType ==
"token")
516 if (wtoken.GetHash() != hash)
518 strErr =
"Error reading wallet database: CTokenInfo corrupt";
524 else if (strType ==
"tokentx")
530 if (wTokenTx.GetHash() != hash)
532 strErr =
"Error reading wallet database: CTokenTx corrupt";
538 else if (strType ==
"contractdata")
540 std::string strAddress, strKey, strValue;
546 strErr =
"Error reading wallet database: LoadContractData failed";
559 return (strType==
"key" || strType ==
"wkey" ||
560 strType ==
"mkey" || strType ==
"ckey");
567 bool fNoncriticalErrors =
false;
573 if (
batch.
Read((std::string)
"minversion", nMinVersion))
575 if (nMinVersion > CLIENT_VERSION)
584 LogPrintf(
"Error getting wallet database cursor\n");
594 if (ret == DB_NOTFOUND)
598 LogPrintf(
"Error reading next record from wallet database\n");
603 std::string strType, strErr;
604 if (!
ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr))
613 fNoncriticalErrors =
true;
624 catch (
const boost::thread_interrupted&) {
631 if (fNoncriticalErrors && result ==
DB_LOAD_OK)
641 LogPrintf(
"Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n",
672 bool fNoncriticalErrors =
false;
677 if (
batch.
Read((std::string)
"minversion", nMinVersion))
679 if (nMinVersion > CLIENT_VERSION)
687 LogPrintf(
"Error getting wallet database cursor\n");
697 if (ret == DB_NOTFOUND)
701 LogPrintf(
"Error reading next record from wallet database\n");
707 if (strType ==
"tx") {
714 vTxHash.push_back(hash);
720 catch (
const boost::thread_interrupted&) {
727 if (fNoncriticalErrors && result ==
DB_LOAD_OK)
736 std::vector<uint256> vTxHash;
737 std::vector<CWalletTx> vWtx;
743 std::sort(vTxHash.begin(), vTxHash.end());
744 std::sort(vTxHashIn.begin(), vTxHashIn.end());
747 bool delerror =
false;
748 std::vector<uint256>::iterator it = vTxHashIn.begin();
750 while (it < vTxHashIn.end() && (*it) < hash) {
753 if (it == vTxHashIn.end()) {
756 else if ((*it) == hash) {
758 LogPrint(
BCLog::DB,
"Transaction was found for deletion but returned database error: %s\n", hash.GetHex());
761 vTxHashOut.push_back(hash);
774 std::vector<uint256> vTxHash;
780 for (
uint256& hash : vTxHash) {
790 static std::atomic<bool> fOneThread(
false);
791 if (fOneThread.exchange(
true)) {
823 return CDB::Recover(filename, callbackDataIn, recoverKVcallback, out_backup_filename);
837 std::string strType, strErr;
843 dummyWss, strType, strErr);
845 if (!
IsKeyType(strType) && strType !=
"hdchain" && strType !=
"token" && strType !=
"tokentx")
849 LogPrintf(
"WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr);
868 return WriteIC(std::make_pair(std::string(
"destdata"), std::make_pair(address, key)), value);
873 return EraseIC(std::make_pair(std::string(
"destdata"), std::make_pair(address, key)));
879 return WriteIC(std::string(
"hdchain"), chain);
909 return WriteIC(std::make_pair(std::string(
"token"), wtoken.
GetHash()), wtoken);
914 return EraseIC(std::make_pair(std::string(
"token"), hash));
919 return WriteIC(std::make_pair(std::string(
"tokentx"), wTokenTx.
GetHash()), wTokenTx);
924 return EraseIC(std::make_pair(std::string(
"tokentx"), hash));
928 return WriteIC(std::make_pair(std::string(
"contractdata"), std::make_pair(address, key)), value);
933 return EraseIC(std::make_pair(std::string(
"contractdata"), std::make_pair(address, key)));
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.
std::vector< CWalletRef > vpwallets
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 WriteToken(const CTokenInfo &wtoken)
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...
unsigned int size() const
Simple read-only vector-like interface to the pubkey data.
base58-encoded Fabcoin addresses.
std::vector< uint256 > vWalletUpgrade
bool GetBoolArg(const std::string &strArg, bool fDefault)
Return boolean argument or default value.
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)
void ListAccountCreditDebit(const std::string &strAccount, std::list< CAccountingEntry > &acentries)
Double ended buffer combining vector and stream-like interfaces.
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)
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 LoadContractData(const std::string &address, const std::string &key, const std::string &value)
Adds a contract data tuple to the store, without saving it to disk.
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 lius (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.
bool WriteTokenTx(const CTokenTx &wTokenTx)
unsigned int nMasterKeyMaxID
bool EraseToken(uint256 hash)
static bool VerifyEnvironment(const std::string &walletFile, const fs::path &dataDir, std::string &errorStr)
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)
bool EraseContractData(const std::string &address, const std::string &key)
Erase contract data tuple from wallet database.
An encapsulated public key.
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 EraseTokenTx(uint256 hash)
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.
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)
CTxDestination Get() const
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)
const unsigned char * begin() const
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)
bool WriteDefaultKey(const CPubKey &vchPubKey)
#define LogPrint(category,...)
bool WriteHDChain(const CHDChain &chain)
write the hdchain model (external chain child index counter)
Capture information about block/transaction validation.
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.
bool LoadTokenTx(const CTokenTx &tokenTx)
CAmount GetAccountCreditDebit(const std::string &strAccount)
bool WriteVersion(int nVersion)
Private key that includes an expiration date in case it never gets used.
bool WriteContractData(const std::string &address, const std::string &key, const std::string &value)
Write contract data key,value tuple to database.
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)
std::map< uint256, CWalletTx > mapWallet
bool LoadToken(const CTokenInfo &token)
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...
struct evm_uint160be address(struct evm_env *env)
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)
CKeyID GetID() const
Get the KeyID of this public key (hash of its serialization)
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)
const unsigned char * end() const
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.