From 8e4dd1e964d2a4a61d850909b9a00c160ff793b3 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 4 Apr 2022 15:31:19 -0600 Subject: [PATCH] Only check nWitnessCacheSize on rewind if we've ever witnessed a Sprout or Sapling note. This allows "rollback" for empty Sapling wallets injected into nonempty chain state that is then rolled back. --- src/wallet/wallet.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 8f3751e81..fd5263e1f 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2726,13 +2726,21 @@ void DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t n void CWallet::DecrementNoteWitnesses(const Consensus::Params& consensus, const CBlockIndex* pindex) { LOCK(cs_wallet); + bool hasSprout = false; + bool hasSapling = false; for (std::pair& wtxItem : mapWallet) { + hasSprout |= !wtxItem.second.mapSproutNoteData.empty(); ::DecrementNoteWitnesses(wtxItem.second.mapSproutNoteData, pindex->nHeight, nWitnessCacheSize); + hasSapling |= !wtxItem.second.mapSaplingNoteData.empty(); ::DecrementNoteWitnesses(wtxItem.second.mapSaplingNoteData, pindex->nHeight, nWitnessCacheSize); } - nWitnessCacheSize -= 1; - // TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302) - assert(nWitnessCacheSize > 0); + if (nWitnessCacheSize > 0) { + nWitnessCacheSize -= 1; + } + // TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302); + // however, if we have never observed Sprout or Sapling notes, this is okay + // because then the witness cache size can remain at 0. + assert(!(hasSprout || hasSapling) || nWitnessCacheSize > 0); // ORCHARD: rewind to the last checkpoint. if (consensus.NetworkUpgradeActive(pindex->nHeight, Consensus::UPGRADE_NU5)) {