Write note witness cache atomically to disk to avoid corruption

Closes #1378
This commit is contained in:
Jack Grigg 2016-09-13 16:46:48 +12:00
parent c470cdf70b
commit 56fb1bb8e4
2 changed files with 29 additions and 10 deletions

View File

@ -654,11 +654,7 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
nWitnessCacheSize += 1;
}
if (fFileBacked) {
CWalletDB walletdb(strWalletFile);
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
walletdb.WriteTx(wtxItem.first, wtxItem.second);
}
walletdb.WriteWitnessCacheSize(nWitnessCacheSize);
WriteWitnessCache();
}
}
}
@ -679,15 +675,37 @@ void CWallet::DecrementNoteWitnesses()
// TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302)
assert(nWitnessCacheSize > 0);
if (fFileBacked) {
CWalletDB walletdb(strWalletFile);
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
walletdb.WriteTx(wtxItem.first, wtxItem.second);
}
walletdb.WriteWitnessCacheSize(nWitnessCacheSize);
WriteWitnessCache();
}
}
}
void CWallet::WriteWitnessCache() {
CWalletDB walletdb(strWalletFile);
if (!walletdb.TxnBegin()) {
// This needs to be done atomically, so don't do it at all
LogPrintf("WriteWitnessCache(): Couldn't start atomic write\n");
return;
}
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
if (!walletdb.WriteTx(wtxItem.first, wtxItem.second)) {
LogPrintf("WriteWitnessCache(): Failed to write CWalletTx, aborting atomic write\n");
walletdb.TxnAbort();
return;
}
}
if (!walletdb.WriteWitnessCacheSize(nWitnessCacheSize)) {
LogPrintf("WriteWitnessCache(): Failed to write nWitnessCacheSize, aborting atomic write\n");
walletdb.TxnAbort();
return;
}
if (!walletdb.TxnCommit()) {
// Couldn't commit all to db, but in-memory state is fine
LogPrintf("WriteWitnessCache(): Couldn't commit atomic write\n");
return;
}
}
bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase)
{
if (IsCrypted())

View File

@ -603,6 +603,7 @@ protected:
const CBlock* pblock,
ZCIncrementalMerkleTree tree);
void DecrementNoteWitnesses();
void WriteWitnessCache();
private:
template <class T>