Browse Source

Update wallet logic to account for viewing keys

The wallet code previously assumed that an unlocked wallet would always
have a spending key associated with a note decryptor. Viewing keys break
this assumption.
pull/4/head
Jack Grigg 7 years ago
parent
commit
9a2b8ae57f
No known key found for this signature in database GPG Key ID: 665DBCD284F7DAFF
  1. 35
      src/wallet/wallet.cpp
  2. 6
      src/wallet/wallet.h

35
src/wallet/wallet.cpp

@ -977,7 +977,8 @@ void CWallet::MarkDirty()
}
/**
* Ensure that every note in the wallet has a cached nullifier.
* Ensure that every note in the wallet (for which we possess a spending key)
* has a cached nullifier.
*/
bool CWallet::UpdateNullifierNoteMap()
{
@ -991,16 +992,17 @@ bool CWallet::UpdateNullifierNoteMap()
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
if (!item.second.nullifier) {
auto i = item.first.js;
GetNoteDecryptor(item.second.address, dec);
auto hSig = wtxItem.second.vjoinsplit[i].h_sig(
*pzcashParams, wtxItem.second.joinSplitPubKey);
item.second.nullifier = GetNoteNullifier(
wtxItem.second.vjoinsplit[i],
item.second.address,
dec,
hSig,
item.first.n);
if (GetNoteDecryptor(item.second.address, dec)) {
auto i = item.first.js;
auto hSig = wtxItem.second.vjoinsplit[i].h_sig(
*pzcashParams, wtxItem.second.joinSplitPubKey);
item.second.nullifier = GetNoteNullifier(
wtxItem.second.vjoinsplit[i],
item.second.address,
dec,
hSig,
item.first.n);
}
}
}
UpdateNullifierNoteMapWithTx(wtxItem.second);
@ -1262,7 +1264,9 @@ boost::optional<uint256> CWallet::GetNoteNullifier(const JSDescription& jsdesc,
hSig,
(unsigned char) n);
auto note = note_pt.note(address);
// SpendingKeys are only available if the wallet is unlocked
// SpendingKeys are only available if:
// - We have them (this isn't a viewing key)
// - The wallet is unlocked
libzcash::SpendingKey key;
if (GetSpendingKey(address, key)) {
ret = note.nullifier(key);
@ -3639,7 +3643,7 @@ bool CMerkleTx::AcceptToMemoryPool(bool fLimitFree, bool fRejectAbsurdFee)
* Find notes in the wallet filtered by payment address, min depth and ability to spend.
* These notes are decrypted and added to the output parameter vector, outEntries.
*/
void CWallet::GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries, std::string address, int minDepth, bool ignoreSpent)
void CWallet::GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries, std::string address, int minDepth, bool ignoreSpent, bool ignoreUnspendable)
{
bool fFilterAddress = false;
libzcash::PaymentAddress filterPaymentAddress;
@ -3677,6 +3681,11 @@ void CWallet::GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries, st
continue;
}
// skip notes which cannot be spent
if (ignoreUnspendable && !HaveSpendingKey(pa)) {
continue;
}
int i = jsop.js; // Index into CTransaction.vjoinsplit
int j = jsop.n; // Index into JSDescription.ciphertexts

6
src/wallet/wallet.h

@ -1121,7 +1121,11 @@ public:
void SetBroadcastTransactions(bool broadcast) { fBroadcastTransactions = broadcast; }
/* Find notes filtered by payment address, min depth, ability to spend */
void GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries, std::string address, int minDepth=1, bool ignoreSpent=true);
void GetFilteredNotes(std::vector<CNotePlaintextEntry> & outEntries,
std::string address,
int minDepth=1,
bool ignoreSpent=true,
bool ignoreUnspendable=true);
};

Loading…
Cancel
Save