Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/walletdb.cpp
Show All 23 Lines | |||||
static uint64_t nAccountingEntryNumber = 0; | static uint64_t nAccountingEntryNumber = 0; | ||||
static std::atomic<unsigned int> nWalletDBUpdateCounter; | static std::atomic<unsigned int> nWalletDBUpdateCounter; | ||||
// | // | ||||
// CWalletDB | // CWalletDB | ||||
// | // | ||||
bool CWalletDB::WriteName(const std::string &strAddress, const std::string &strName) { | bool CWalletDB::WriteName(const std::string &strAddress, | ||||
const std::string &strName) { | |||||
nWalletDBUpdateCounter++; | nWalletDBUpdateCounter++; | ||||
return Write(make_pair(std::string("name"), strAddress), strName); | return Write(std::make_pair(std::string("name"), strAddress), strName); | ||||
} | } | ||||
bool CWalletDB::EraseName(const std::string &strAddress) { | bool CWalletDB::EraseName(const std::string &strAddress) { | ||||
// This should only be used for sending addresses, never for receiving | // This should only be used for sending addresses, never for receiving | ||||
// addresses, receiving addresses must always have an address book entry if | // addresses, receiving addresses must always have an address book entry if | ||||
// they're not change return. | // they're not change return. | ||||
nWalletDBUpdateCounter++; | nWalletDBUpdateCounter++; | ||||
return Erase(make_pair(std::string("name"), strAddress)); | return Erase(std::make_pair(std::string("name"), strAddress)); | ||||
} | } | ||||
bool CWalletDB::WritePurpose(const std::string &strAddress, | bool CWalletDB::WritePurpose(const std::string &strAddress, | ||||
const std::string &strPurpose) { | const std::string &strPurpose) { | ||||
nWalletDBUpdateCounter++; | nWalletDBUpdateCounter++; | ||||
return Write(make_pair(std::string("purpose"), strAddress), strPurpose); | return Write(std::make_pair(std::string("purpose"), strAddress), | ||||
strPurpose); | |||||
} | } | ||||
bool CWalletDB::ErasePurpose(const std::string &strPurpose) { | bool CWalletDB::ErasePurpose(const std::string &strPurpose) { | ||||
nWalletDBUpdateCounter++; | nWalletDBUpdateCounter++; | ||||
return Erase(make_pair(std::string("purpose"), strPurpose)); | return Erase(std::make_pair(std::string("purpose"), strPurpose)); | ||||
} | } | ||||
bool CWalletDB::WriteTx(const CWalletTx &wtx) { | bool CWalletDB::WriteTx(const CWalletTx &wtx) { | ||||
nWalletDBUpdateCounter++; | nWalletDBUpdateCounter++; | ||||
return Write(std::make_pair(std::string("tx"), wtx.GetId()), wtx); | return Write(std::make_pair(std::string("tx"), wtx.GetId()), wtx); | ||||
} | } | ||||
bool CWalletDB::EraseTx(uint256 hash) { | bool CWalletDB::EraseTx(uint256 hash) { | ||||
▲ Show 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool CWalletDB::WriteMinVersion(int nVersion) { | bool CWalletDB::WriteMinVersion(int nVersion) { | ||||
return Write(std::string("minversion"), nVersion); | return Write(std::string("minversion"), nVersion); | ||||
} | } | ||||
bool CWalletDB::ReadAccount(const std::string &strAccount, CAccount &account) { | bool CWalletDB::ReadAccount(const std::string &strAccount, CAccount &account) { | ||||
account.SetNull(); | account.SetNull(); | ||||
return Read(make_pair(std::string("acc"), strAccount), account); | return Read(std::make_pair(std::string("acc"), strAccount), account); | ||||
} | } | ||||
bool CWalletDB::WriteAccount(const std::string &strAccount, | bool CWalletDB::WriteAccount(const std::string &strAccount, | ||||
const CAccount &account) { | const CAccount &account) { | ||||
return Write(make_pair(std::string("acc"), strAccount), account); | return Write(std::make_pair(std::string("acc"), strAccount), account); | ||||
} | } | ||||
bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, | bool CWalletDB::WriteAccountingEntry(const uint64_t nAccEntryNum, | ||||
const CAccountingEntry &acentry) { | const CAccountingEntry &acentry) { | ||||
return Write( | return Write( | ||||
std::make_pair(std::string("acentry"), | std::make_pair(std::string("acentry"), | ||||
std::make_pair(acentry.strAccount, nAccEntryNum)), | std::make_pair(acentry.strAccount, nAccEntryNum)), | ||||
acentry); | acentry); | ||||
Show All 17 Lines | |||||
void CWalletDB::ListAccountCreditDebit(const std::string &strAccount, | void CWalletDB::ListAccountCreditDebit(const std::string &strAccount, | ||||
std::list<CAccountingEntry> &entries) { | std::list<CAccountingEntry> &entries) { | ||||
bool fAllAccounts = (strAccount == "*"); | bool fAllAccounts = (strAccount == "*"); | ||||
Dbc *pcursor = GetCursor(); | Dbc *pcursor = GetCursor(); | ||||
if (!pcursor) | if (!pcursor) | ||||
throw std::runtime_error(std::string(__func__) + | throw std::runtime_error(std::string(__func__) + | ||||
": cannot create DB cursor"); | ": cannot create DB cursor"); | ||||
bool setRange = true; | bool setRange = true; | ||||
while (true) { | while (true) { | ||||
// Read next record | // Read next record | ||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION); | CDataStream ssKey(SER_DISK, CLIENT_VERSION); | ||||
if (setRange) | if (setRange) | ||||
ssKey << std::make_pair( | ssKey << std::make_pair( | ||||
std::string("acentry"), | std::string("acentry"), | ||||
std::make_pair((fAllAccounts ? std::string("") : strAccount), | std::make_pair((fAllAccounts ? std::string("") : strAccount), | ||||
uint64_t(0))); | uint64_t(0))); | ||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION); | CDataStream ssValue(SER_DISK, CLIENT_VERSION); | ||||
int ret = ReadAtCursor(pcursor, ssKey, ssValue, setRange); | int ret = ReadAtCursor(pcursor, ssKey, ssValue, setRange); | ||||
setRange = false; | setRange = false; | ||||
if (ret == DB_NOTFOUND) | if (ret == DB_NOTFOUND) | ||||
break; | break; | ||||
else if (ret != 0) { | else if (ret != 0) { | ||||
pcursor->close(); | pcursor->close(); | ||||
throw std::runtime_error(std::string(__func__) + ": error scanning DB"); | throw std::runtime_error(std::string(__func__) + | ||||
": error scanning DB"); | |||||
} | } | ||||
// Unserialize | // Unserialize | ||||
std::string strType; | std::string strType; | ||||
ssKey >> strType; | ssKey >> strType; | ||||
if (strType != "acentry") break; | if (strType != "acentry") break; | ||||
CAccountingEntry acentry; | CAccountingEntry acentry; | ||||
ssKey >> acentry.strAccount; | ssKey >> acentry.strAccount; | ||||
Show All 22 Lines | CWalletScanState() { | ||||
nKeys = nCKeys = nWatchKeys = nKeyMeta = 0; | nKeys = nCKeys = nWatchKeys = nKeyMeta = 0; | ||||
fIsEncrypted = false; | fIsEncrypted = false; | ||||
fAnyUnordered = false; | fAnyUnordered = false; | ||||
nFileVersion = 0; | nFileVersion = 0; | ||||
} | } | ||||
}; | }; | ||||
bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, | bool ReadKeyValue(CWallet *pwallet, CDataStream &ssKey, CDataStream &ssValue, | ||||
CWalletScanState &wss, std::string &strType, std::string &strErr) { | CWalletScanState &wss, std::string &strType, | ||||
std::string &strErr) { | |||||
try { | try { | ||||
// Unserialize | // Unserialize | ||||
// Taking advantage of the fact that pair serialization is just the two | // Taking advantage of the fact that pair serialization is just the two | ||||
// items serialized one after the other. | // items serialized one after the other. | ||||
ssKey >> strType; | ssKey >> strType; | ||||
if (strType == "name") { | if (strType == "name") { | ||||
std::string strAddress; | std::string strAddress; | ||||
ssKey >> strAddress; | ssKey >> strAddress; | ||||
▲ Show 20 Lines • Show All 302 Lines • ▼ Show 20 Lines | DBErrors CWalletDB::LoadWallet(CWallet *pwallet) { | ||||
if (wss.nFileVersion < CLIENT_VERSION) // Update | if (wss.nFileVersion < CLIENT_VERSION) // Update | ||||
WriteVersion(CLIENT_VERSION); | WriteVersion(CLIENT_VERSION); | ||||
if (wss.fAnyUnordered) result = pwallet->ReorderTransactions(); | if (wss.fAnyUnordered) result = pwallet->ReorderTransactions(); | ||||
pwallet->laccentries.clear(); | pwallet->laccentries.clear(); | ||||
ListAccountCreditDebit("*", pwallet->laccentries); | ListAccountCreditDebit("*", pwallet->laccentries); | ||||
for (CAccountingEntry &entry : pwallet->laccentries) { | for (CAccountingEntry &entry : pwallet->laccentries) { | ||||
pwallet->wtxOrdered.insert(make_pair( | pwallet->wtxOrdered.insert(std::make_pair( | ||||
entry.nOrderPos, CWallet::TxPair((CWalletTx *)0, &entry))); | entry.nOrderPos, CWallet::TxPair((CWalletTx *)0, &entry))); | ||||
} | } | ||||
return result; | return result; | ||||
} | } | ||||
DBErrors CWalletDB::FindWalletTx(CWallet *pwallet, std::vector<uint256> &vTxHash, | DBErrors CWalletDB::FindWalletTx(CWallet *pwallet, | ||||
std::vector<uint256> &vTxHash, | |||||
std::vector<CWalletTx> &vWtx) { | std::vector<CWalletTx> &vWtx) { | ||||
pwallet->vchDefaultKey = CPubKey(); | pwallet->vchDefaultKey = CPubKey(); | ||||
bool fNoncriticalErrors = false; | bool fNoncriticalErrors = false; | ||||
DBErrors result = DB_LOAD_OK; | DBErrors result = DB_LOAD_OK; | ||||
try { | try { | ||||
LOCK(pwallet->cs_wallet); | LOCK(pwallet->cs_wallet); | ||||
int nMinVersion = 0; | int nMinVersion = 0; | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | DBErrors CWalletDB::FindWalletTx(CWallet *pwallet, | ||||
} | } | ||||
if (fNoncriticalErrors && result == DB_LOAD_OK) | if (fNoncriticalErrors && result == DB_LOAD_OK) | ||||
result = DB_NONCRITICAL_ERROR; | result = DB_NONCRITICAL_ERROR; | ||||
return result; | return result; | ||||
} | } | ||||
DBErrors CWalletDB::ZapSelectTx(CWallet *pwallet, std::vector<uint256> &vTxHashIn, | DBErrors CWalletDB::ZapSelectTx(CWallet *pwallet, | ||||
std::vector<uint256> &vTxHashIn, | |||||
std::vector<uint256> &vTxHashOut) { | std::vector<uint256> &vTxHashOut) { | ||||
// Build list of wallet TXs and hashes. | // Build list of wallet TXs and hashes. | ||||
std::vector<uint256> vTxHash; | std::vector<uint256> vTxHash; | ||||
std::vector<CWalletTx> vWtx; | std::vector<CWalletTx> vWtx; | ||||
DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); | DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); | ||||
if (err != DB_LOAD_OK) { | if (err != DB_LOAD_OK) { | ||||
return err; | return err; | ||||
} | } | ||||
Show All 23 Lines | DBErrors CWalletDB::ZapSelectTx(CWallet *pwallet, | ||||
} | } | ||||
if (delerror) { | if (delerror) { | ||||
return DB_CORRUPT; | return DB_CORRUPT; | ||||
} | } | ||||
return DB_LOAD_OK; | return DB_LOAD_OK; | ||||
} | } | ||||
DBErrors CWalletDB::ZapWalletTx(CWallet *pwallet, std::vector<CWalletTx> &vWtx) { | DBErrors CWalletDB::ZapWalletTx(CWallet *pwallet, | ||||
std::vector<CWalletTx> &vWtx) { | |||||
// Build list of wallet TXs. | // Build list of wallet TXs. | ||||
std::vector<uint256> vTxHash; | std::vector<uint256> vTxHash; | ||||
DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); | DBErrors err = FindWalletTx(pwallet, vTxHash, vWtx); | ||||
if (err != DB_LOAD_OK) return err; | if (err != DB_LOAD_OK) return err; | ||||
// Erase each wallet TX. | // Erase each wallet TX. | ||||
for (uint256 &hash : vTxHash) { | for (uint256 &hash : vTxHash) { | ||||
if (!EraseTx(hash)) return DB_CORRUPT; | if (!EraseTx(hash)) return DB_CORRUPT; | ||||
Show All 23 Lines | while (true) { | ||||
} | } | ||||
if (nLastFlushed != CWalletDB::GetUpdateCounter() && | if (nLastFlushed != CWalletDB::GetUpdateCounter() && | ||||
GetTime() - nLastWalletUpdate >= 2) { | GetTime() - nLastWalletUpdate >= 2) { | ||||
TRY_LOCK(bitdb.cs_db, lockDb); | TRY_LOCK(bitdb.cs_db, lockDb); | ||||
if (lockDb) { | if (lockDb) { | ||||
// Don't do this if any databases are in use. | // Don't do this if any databases are in use. | ||||
int nRefCount = 0; | int nRefCount = 0; | ||||
std::map<std::string, int>::iterator mi = bitdb.mapFileUseCount.begin(); | std::map<std::string, int>::iterator mi = | ||||
bitdb.mapFileUseCount.begin(); | |||||
while (mi != bitdb.mapFileUseCount.end()) { | while (mi != bitdb.mapFileUseCount.end()) { | ||||
nRefCount += (*mi).second; | nRefCount += (*mi).second; | ||||
mi++; | mi++; | ||||
} | } | ||||
if (nRefCount == 0) { | if (nRefCount == 0) { | ||||
boost::this_thread::interruption_point(); | boost::this_thread::interruption_point(); | ||||
const std::string &strFile = pwalletMain->strWalletFile; | const std::string &strFile = pwalletMain->strWalletFile; | ||||
▲ Show 20 Lines • Show All 128 Lines • Show Last 20 Lines |