Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/walletdb.cpp
Show First 20 Lines • Show All 539 Lines • ▼ Show 20 Lines | try { | ||||
return DB_TOO_NEW; | return DB_TOO_NEW; | ||||
} | } | ||||
pwallet->LoadMinVersion(nMinVersion); | pwallet->LoadMinVersion(nMinVersion); | ||||
} | } | ||||
// Get cursor | // Get cursor | ||||
Dbc *pcursor = batch.GetCursor(); | Dbc *pcursor = batch.GetCursor(); | ||||
if (!pcursor) { | if (!pcursor) { | ||||
LogPrintf("Error getting wallet database cursor\n"); | LogPrint(BCLog::DB, "Error getting wallet database cursor\n"); | ||||
return DB_CORRUPT; | return DB_CORRUPT; | ||||
} | } | ||||
while (true) { | while (true) { | ||||
// Read next record | // Read next record | ||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION); | CDataStream ssKey(SER_DISK, CLIENT_VERSION); | ||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION); | CDataStream ssValue(SER_DISK, CLIENT_VERSION); | ||||
int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue); | int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue); | ||||
if (ret == DB_NOTFOUND) { | if (ret == DB_NOTFOUND) { | ||||
break; | break; | ||||
} | } | ||||
if (ret != 0) { | if (ret != 0) { | ||||
LogPrintf("Error reading next record from wallet database\n"); | LogPrint(BCLog::DB, | ||||
"Error reading next record from wallet database\n"); | |||||
return DB_CORRUPT; | return DB_CORRUPT; | ||||
} | } | ||||
// Try to be tolerant of single corrupt records: | // Try to be tolerant of single corrupt records: | ||||
std::string strType, strErr; | std::string strType, strErr; | ||||
if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) { | if (!ReadKeyValue(pwallet, ssKey, ssValue, wss, strType, strErr)) { | ||||
// losing keys is considered a catastrophic error, anything else | // losing keys is considered a catastrophic error, anything else | ||||
// we assume the user can live with: | // we assume the user can live with: | ||||
if (IsKeyType(strType) || strType == "defaultkey") { | if (IsKeyType(strType) || strType == "defaultkey") { | ||||
result = DB_CORRUPT; | result = DB_CORRUPT; | ||||
} else { | } else { | ||||
// Leave other errors alone, if we try to fix them we might | // Leave other errors alone, if we try to fix them we might | ||||
// make things worse. But do warn the user there is | // make things worse. But do warn the user there is | ||||
// something wrong. | // something wrong. | ||||
fNoncriticalErrors = true; | fNoncriticalErrors = true; | ||||
if (strType == "tx") { | if (strType == "tx") { | ||||
// Rescan if there is a bad transaction record: | // Rescan if there is a bad transaction record: | ||||
gArgs.SoftSetBoolArg("-rescan", true); | gArgs.SoftSetBoolArg("-rescan", true); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
if (!strErr.empty()) { | if (!strErr.empty()) { | ||||
LogPrintf("%s\n", strErr); | LogPrint(BCLog::DB, "%s\n", strErr); | ||||
} | } | ||||
} | } | ||||
pcursor->close(); | pcursor->close(); | ||||
} catch (const boost::thread_interrupted &) { | } catch (const boost::thread_interrupted &) { | ||||
throw; | throw; | ||||
} catch (...) { | } catch (...) { | ||||
result = DB_CORRUPT; | result = DB_CORRUPT; | ||||
} | } | ||||
if (fNoncriticalErrors && result == DB_LOAD_OK) { | if (fNoncriticalErrors && result == DB_LOAD_OK) { | ||||
result = DB_NONCRITICAL_ERROR; | result = DB_NONCRITICAL_ERROR; | ||||
} | } | ||||
// Any wallet corruption at all: skip any rewriting or upgrading, we don't | // Any wallet corruption at all: skip any rewriting or upgrading, we don't | ||||
// want to make it worse. | // want to make it worse. | ||||
if (result != DB_LOAD_OK) { | if (result != DB_LOAD_OK) { | ||||
return result; | return result; | ||||
} | } | ||||
LogPrintf("nFileVersion = %d\n", wss.nFileVersion); | LogPrint(BCLog::DB, "nFileVersion = %d\n", wss.nFileVersion); | ||||
LogPrintf("Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n", | LogPrint(BCLog::DB, | ||||
"Keys: %u plaintext, %u encrypted, %u w/ metadata, %u total\n", | |||||
wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys); | wss.nKeys, wss.nCKeys, wss.nKeyMeta, wss.nKeys + wss.nCKeys); | ||||
// nTimeFirstKey is only reliable if all keys have metadata | // nTimeFirstKey is only reliable if all keys have metadata | ||||
if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta) { | if ((wss.nKeys + wss.nCKeys + wss.nWatchKeys) != wss.nKeyMeta) { | ||||
pwallet->UpdateTimeFirstKey(1); | pwallet->UpdateTimeFirstKey(1); | ||||
} | } | ||||
for (const TxId &txid : wss.vWalletUpgrade) { | for (const TxId &txid : wss.vWalletUpgrade) { | ||||
WriteTx(pwallet->mapWallet[txid]); | WriteTx(pwallet->mapWallet[txid]); | ||||
Show All 35 Lines | try { | ||||
if (nMinVersion > CLIENT_VERSION) { | if (nMinVersion > CLIENT_VERSION) { | ||||
return DB_TOO_NEW; | return DB_TOO_NEW; | ||||
} | } | ||||
} | } | ||||
// Get cursor | // Get cursor | ||||
Dbc *pcursor = batch.GetCursor(); | Dbc *pcursor = batch.GetCursor(); | ||||
if (!pcursor) { | if (!pcursor) { | ||||
LogPrintf("Error getting wallet database cursor\n"); | LogPrint(BCLog::DB, "Error getting wallet database cursor\n"); | ||||
return DB_CORRUPT; | return DB_CORRUPT; | ||||
} | } | ||||
while (true) { | while (true) { | ||||
// Read next record | // Read next record | ||||
CDataStream ssKey(SER_DISK, CLIENT_VERSION); | CDataStream ssKey(SER_DISK, CLIENT_VERSION); | ||||
CDataStream ssValue(SER_DISK, CLIENT_VERSION); | CDataStream ssValue(SER_DISK, CLIENT_VERSION); | ||||
int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue); | int ret = batch.ReadAtCursor(pcursor, ssKey, ssValue); | ||||
if (ret == DB_NOTFOUND) { | if (ret == DB_NOTFOUND) { | ||||
break; | break; | ||||
} | } | ||||
if (ret != 0) { | if (ret != 0) { | ||||
LogPrintf("Error reading next record from wallet database\n"); | LogPrint(BCLog::DB, | ||||
"Error reading next record from wallet database\n"); | |||||
return DB_CORRUPT; | return DB_CORRUPT; | ||||
} | } | ||||
std::string strType; | std::string strType; | ||||
ssKey >> strType; | ssKey >> strType; | ||||
if (strType == "tx") { | if (strType == "tx") { | ||||
TxId txid; | TxId txid; | ||||
ssKey >> txid; | ssKey >> txid; | ||||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | bool fReadOK; | ||||
LOCK(dummyWallet->cs_wallet); | LOCK(dummyWallet->cs_wallet); | ||||
fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue, dummyWss, strType, | fReadOK = ReadKeyValue(dummyWallet, ssKey, ssValue, dummyWss, strType, | ||||
strErr); | strErr); | ||||
} | } | ||||
if (!IsKeyType(strType) && strType != "hdchain") { | if (!IsKeyType(strType) && strType != "hdchain") { | ||||
return false; | return false; | ||||
} | } | ||||
if (!fReadOK) { | if (!fReadOK) { | ||||
LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, | LogPrint(BCLog::DB, "WARNING: CWalletDB::Recover skipping %s: %s\n", | ||||
strErr); | strType, strErr); | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
bool CWalletDB::VerifyEnvironment(const std::string &walletFile, | bool CWalletDB::VerifyEnvironment(const std::string &walletFile, | ||||
const fs::path &dataDir, | const fs::path &dataDir, | ||||
▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines |