diff --git a/src/keystore.cpp b/src/keystore.cpp index 251e47e26..f32ba0c32 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -89,6 +89,6 @@ bool CBasicKeyStore::AddSpendingKey(const libzcash::SpendingKey &sk) LOCK(cs_SpendingKeyStore); auto address = sk.address(); mapSpendingKeys[address] = sk; - mapNoteDecryptors[address] = ZCNoteDecryption(sk.viewing_key()); + mapNoteDecryptors.insert(std::make_pair(address, ZCNoteDecryption(sk.viewing_key()))); return true; } diff --git a/src/wallet/gtest/test_wallet.cpp b/src/wallet/gtest/test_wallet.cpp index cf418a596..289bd265f 100644 --- a/src/wallet/gtest/test_wallet.cpp +++ b/src/wallet/gtest/test_wallet.cpp @@ -172,7 +172,7 @@ TEST(wallet_tests, set_invalid_note_addrs_in_cwallettx) { CNoteData nd {sk.address(), uint256()}; noteData[jsoutpt] = nd; - EXPECT_THROW(wtx.SetNoteData(noteData), std::runtime_error); + EXPECT_THROW(wtx.SetNoteData(noteData), std::logic_error); } TEST(wallet_tests, find_note_in_tx) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 438de40db..3407df53e 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -601,6 +601,8 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex, for (std::pair& wtxItem : mapWallet) { for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) { CNoteData* nd = &(item.second); + // Check the validity of the cache + assert(nWitnessCacheSize >= nd->witnesses.size()); // Copy the witness for the previous block if we have one if (nd->witnesses.size() > 0) { nd->witnesses.push_front(nd->witnesses.front()); @@ -1060,8 +1062,12 @@ mapNoteData_t CWallet::FindMyNotes(const CTransaction& tx) const CNoteData nd {address, note.nullifier(key)}; noteData.insert(std::make_pair(jsoutpt, nd)); break; - } catch (const std::exception &) { + } catch (const std::runtime_error &) { // Couldn't decrypt with this spending key + } catch (const std::exception &exc) { + // Unexpected failure + LogPrintf("FindMyNotes(): Unexpected error while testing decrypt:\n"); + LogPrintf("%s\n", exc.what()); } } } @@ -1252,7 +1258,7 @@ void CWalletTx::SetNoteData(mapNoteData_t ¬eData) } else { // If FindMyNotes() was used to obtain noteData, // this should never happen - throw std::runtime_error("CWalletTc::SetNoteData(): Invalid note"); + throw std::logic_error("CWalletTx::SetNoteData(): Invalid note"); } } } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 7fa88ab1d..b1c816fac 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -55,7 +55,8 @@ static const CAmount nHighTransactionMaxFeeWarning = 100 * nHighTransactionFeeWa //! Largest (in bytes) free transaction we're willing to create static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; //! Size of witness cache -// Should be large enough that we can expect to never reorg beyond our cache. +// Should be large enough that we can expect not to reorg beyond our cache +// unless there is some exceptional network disruption. static const unsigned int WITNESS_CACHE_SIZE = COINBASE_MATURITY; class CAccountingEntry; diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index d967aef27..58caae772 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -23,8 +23,13 @@ public: READWRITE(pk_enc); } - friend inline bool operator==(const PaymentAddress& a, const PaymentAddress& b) { return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc; } - friend inline bool operator<(const PaymentAddress& a, const PaymentAddress& b) { return a.a_pk < b.a_pk; } + friend inline bool operator==(const PaymentAddress& a, const PaymentAddress& b) { + return a.a_pk == b.a_pk && a.pk_enc == b.pk_enc; + } + friend inline bool operator<(const PaymentAddress& a, const PaymentAddress& b) { + return (a.a_pk < b.a_pk || + (a.a_pk == b.a_pk && a.pk_enc < b.pk_enc)); + } }; class ViewingKey : public uint256 { diff --git a/src/zcash/NoteEncryption.hpp b/src/zcash/NoteEncryption.hpp index bfeb80efa..e1f3718b0 100644 --- a/src/zcash/NoteEncryption.hpp +++ b/src/zcash/NoteEncryption.hpp @@ -61,7 +61,6 @@ public: typedef boost::array Ciphertext; typedef boost::array Plaintext; - // Unused default constructor to make allocators happy NoteDecryption() { } NoteDecryption(uint256 sk_enc); @@ -71,8 +70,13 @@ public: unsigned char nonce ) const; - friend inline bool operator==(const NoteDecryption& a, const NoteDecryption& b) { return a.sk_enc == b.sk_enc && a.pk_enc == b.pk_enc; } - friend inline bool operator<(const NoteDecryption& a, const NoteDecryption& b) { return a.pk_enc < b.pk_enc; } + friend inline bool operator==(const NoteDecryption& a, const NoteDecryption& b) { + return a.sk_enc == b.sk_enc && a.pk_enc == b.pk_enc; + } + friend inline bool operator<(const NoteDecryption& a, const NoteDecryption& b) { + return (a.sk_enc < b.sk_enc || + (a.sk_enc == b.sk_enc && a.pk_enc < b.pk_enc)); + } }; uint256 random_uint256();