diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2e1449fc..662135c4 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -654,11 +654,7 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, nWitnessCacheSize += 1; } if (fFileBacked) { - CWalletDB walletdb(strWalletFile); - for (std::pair& 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& 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& 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()) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1bfb7579..d3ec546d 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -603,6 +603,7 @@ protected: const CBlock* pblock, ZCIncrementalMerkleTree tree); void DecrementNoteWitnesses(); + void WriteWitnessCache(); private: template