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.
This commit is contained in:
parent
e85b33a52e
commit
9a2b8ae57f
|
@ -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
|
||||
|
||||
|
|
|
@ -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…
Reference in New Issue