diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 02c3362e0..9c6092683 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -402,7 +402,8 @@ TEST(wallet_tests, cached_witnesses_chain_tip) { witnesses.clear(); wallet.GetNoteWitnesses(notes, witnesses, anchor3); EXPECT_FALSE((bool) witnesses[0]); - EXPECT_EQ(anchor1, anchor3); + // Should not equal first anchor because none of these notes had witnesses + EXPECT_NE(anchor1, anchor3); // Re-incrementing with the same block should give the same result uint256 anchor4; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dd229310b..9a1c86abd 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -649,12 +649,11 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, } } } - vAnchorCache.push_front(tree.root()); - if (vAnchorCache.size() > WITNESS_CACHE_SIZE) { - vAnchorCache.pop_back(); + if (nWitnessCacheSize < WITNESS_CACHE_SIZE) { + nWitnessCacheSize += 1; } if (fFileBacked) { - CWalletDB(strWalletFile).WriteAnchorCache(vAnchorCache); + CWalletDB(strWalletFile).WriteWitnessCacheSize(nWitnessCacheSize); } } } @@ -671,12 +670,11 @@ void CWallet::DecrementNoteWitnesses() } } } - if (vAnchorCache.size() > 0) { - vAnchorCache.pop_front(); - } - // TODO: If vAnchorCache is empty, we need to regenerate the caches (#1302) + nWitnessCacheSize -= 1; + // TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302) + assert(nWitnessCacheSize > 0); if (fFileBacked) { - CWalletDB(strWalletFile).WriteAnchorCache(vAnchorCache); + CWalletDB(strWalletFile).WriteWitnessCacheSize(nWitnessCacheSize); } } } @@ -1070,18 +1068,24 @@ void CWallet::GetNoteWitnesses(std::vector notes, { LOCK(cs_wallet); witnesses.resize(notes.size()); + boost::optional rt; int i = 0; for (JSOutPoint note : notes) { if (mapWallet.count(note.hash) && mapWallet[note.hash].mapNoteData.count(note) && mapWallet[note.hash].mapNoteData[note].witnesses.size() > 0) { witnesses[i] = mapWallet[note.hash].mapNoteData[note].witnesses.front(); + if (!rt) { + rt = witnesses[i]->root(); + } else { + assert(*rt == witnesses[i]->root()); + } } i++; } - // vAnchorCache should only be empty here before the genesis block (so, never) - if (vAnchorCache.size() > 0) { - final_anchor = vAnchorCache.front(); + // All returned witnesses have the same anchor + if (rt) { + final_anchor = *rt; } } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 8b6f3db8e..ae2d3edc6 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -580,10 +580,11 @@ private: public: /* - * Cached anchors corresponding to the cached incremental witnesses for the - * notes in our wallet. + * Size of the incremental witness cache for the notes in our wallet. + * This will always be greater than or equal to the size of the largest + * incremental witness cache in any transaction in mapWallet. */ - std::list vAnchorCache; + int64_t nWitnessCacheSize; protected: void IncrementNoteWitnesses(const CBlockIndex* pindex, diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 7a165eeaa..e72ee5e3e 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -162,10 +162,10 @@ bool CWalletDB::WriteDefaultKey(const CPubKey& vchPubKey) return Write(std::string("defaultkey"), vchPubKey); } -bool CWalletDB::WriteAnchorCache(const std::list& vAnchorCache) +bool CWalletDB::WriteWitnessCacheSize(int64_t nWitnessCacheSize) { nWalletDBUpdated++; - return Write(std::string("anchorcache"), vAnchorCache); + return Write(std::string("witnesscachesize"), nWitnessCacheSize); } bool CWalletDB::ReadPool(int64_t nPool, CKeyPool& keypool) @@ -637,9 +637,9 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, return false; } } - else if (strType == "anchorcache") + else if (strType == "witnesscachesize") { - ssValue >> pwallet->vAnchorCache; + ssValue >> pwallet->nWitnessCacheSize; } } catch (...) { diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 81e3b094e..317f71304 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -106,7 +106,7 @@ public: bool WriteDefaultKey(const CPubKey& vchPubKey); - bool WriteAnchorCache(const std::list& vAnchorCache); + bool WriteWitnessCacheSize(int64_t nWitnessCacheSize); bool ReadPool(int64_t nPool, CKeyPool& keypool); bool WritePool(int64_t nPool, const CKeyPool& keypool);