From e81c2de753a3f236c19b38040535ed72ff63b0a9 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 15 Sep 2016 22:47:10 +1200 Subject: [PATCH 1/4] Fix test --- src/wallet/gtest/test_wallet.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 6ebaef970..216206fd2 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -592,12 +592,12 @@ TEST(wallet_tests, UpdatedNoteData) { // The txs should initially be different EXPECT_NE(wtx.mapNoteData, wtx2.mapNoteData); - EXPECT_NE(wtx.mapNoteData[jsoutpt].witnesses, wtx2.mapNoteData[jsoutpt].witnesses); + EXPECT_EQ(1, wtx.mapNoteData[jsoutpt].witnesses.size()); // After updating, they should be the same - EXPECT_TRUE(wallet.UpdatedNoteData(wtx, wtx2)); + EXPECT_TRUE(wallet.UpdatedNoteData(wtx2, wtx)); EXPECT_EQ(wtx.mapNoteData, wtx2.mapNoteData); - EXPECT_EQ(wtx.mapNoteData[jsoutpt].witnesses, wtx2.mapNoteData[jsoutpt].witnesses); + EXPECT_EQ(1, wtx.mapNoteData[jsoutpt].witnesses.size()); // TODO: The new note should get witnessed (but maybe not here) (#1350) } From 76b226586e0b20edde86dd9db47382966f292c5d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 16 Sep 2016 18:02:49 +1200 Subject: [PATCH 2/4] Add wallet method to clear the note witness cache --- src/wallet/gtest/test_wallet.cpp | 40 ++++++++++++++++++++++++++++++++ src/wallet/wallet.cpp | 11 +++++++++ src/wallet/wallet.h | 2 ++ 3 files changed, 53 insertions(+) diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index 216206fd2..cebae5385 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -557,6 +557,46 @@ TEST(wallet_tests, cached_witnesses_chain_tip) { } } +TEST(wallet_tests, ClearNoteWitnessCache) { + TestWallet wallet; + + auto sk = libzcash::SpendingKey::random(); + wallet.AddSpendingKey(sk); + + auto wtx = GetValidReceive(sk, 10, true); + auto note = GetNote(sk, wtx, 0, 0); + auto nullifier = note.nullifier(sk); + + mapNoteData_t noteData; + JSOutPoint jsoutpt {wtx.GetHash(), 0, 0}; + JSOutPoint jsoutpt2 {wtx.GetHash(), 0, 1}; + CNoteData nd {sk.address(), nullifier}; + noteData[jsoutpt] = nd; + wtx.SetNoteData(noteData); + + // Pretend we mined the tx by adding a fake witness + ZCIncrementalMerkleTree tree; + wtx.mapNoteData[jsoutpt].witnesses.push_front(tree.witness()); + + wallet.AddToWallet(wtx, true, NULL); + + std::vector notes {jsoutpt, jsoutpt2}; + std::vector> witnesses; + uint256 anchor2; + + // Before clearing, we should have a witness for one note + wallet.GetNoteWitnesses(notes, witnesses, anchor2); + EXPECT_TRUE((bool) witnesses[0]); + EXPECT_FALSE((bool) witnesses[1]); + + // After clearing, we should not have a witness for either note + wallet.ClearNoteWitnessCache(); + witnesses.clear(); + wallet.GetNoteWitnesses(notes, witnesses, anchor2); + EXPECT_FALSE((bool) witnesses[0]); + EXPECT_FALSE((bool) witnesses[1]); +} + TEST(wallet_tests, UpdatedNoteData) { TestWallet wallet; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 2e1449fc2..85e6944c1 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -592,6 +592,17 @@ void CWallet::AddToSpends(const uint256& wtxid) } } +void CWallet::ClearNoteWitnessCache() +{ + LOCK(cs_wallet); + for (std::pair& wtxItem : mapWallet) { + for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) { + CNoteData* nd = &(item.second); + nd->witnesses.clear(); + } + } +} + void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, const CBlock* pblockIn, ZCIncrementalMerkleTree tree) diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 1bfb75792..28feb872e 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -598,6 +598,8 @@ public: */ int64_t nWitnessCacheSize; + void ClearNoteWitnessCache(); + protected: void IncrementNoteWitnesses(const CBlockIndex* pindex, const CBlock* pblock, From 1683b1f58b411a6f889694c88afd662da3fd342c Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 16 Sep 2016 18:43:30 +1200 Subject: [PATCH 3/4] Clear note witness caches on reindex --- src/init.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/init.cpp b/src/init.cpp index a25179612..8c7a227ba 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -532,6 +532,11 @@ void ThreadImport(std::vector vImportFiles) RenameThread("bitcoin-loadblk"); // -reindex if (fReindex) { +#ifdef ENABLE_WALLET + if (pwalletMain) { + pwalletMain->ClearNoteWitnessCache(); + } +#endif CImportingNow imp; int nFile = 0; while (true) { From 40600f5089a57a474c2c5207bbc51726c22822eb Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 30 Sep 2016 15:00:16 +1300 Subject: [PATCH 4/4] Simplify ClearNoteWitnessCache() --- src/wallet/wallet.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 85e6944c1..be101df6d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -597,8 +597,7 @@ void CWallet::ClearNoteWitnessCache() LOCK(cs_wallet); for (std::pair& wtxItem : mapWallet) { for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) { - CNoteData* nd = &(item.second); - nd->witnesses.clear(); + item.second.witnesses.clear(); } } }