Fix change output detection using IVK instead of static address list
Some checks failed
Rust / Build on macOS-latest (push) Has been cancelled
Rust / Build on ubuntu-16.04 (push) Has been cancelled
Rust / Build on windows-latest (push) Has been cancelled
Rust / Linux ARMv7 (push) Has been cancelled
Rust / Linux ARM64 (push) Has been cancelled
Rust / Build on ubuntu-latest (push) Has been cancelled
Some checks failed
Rust / Build on macOS-latest (push) Has been cancelled
Rust / Build on ubuntu-16.04 (push) Has been cancelled
Rust / Build on windows-latest (push) Has been cancelled
Rust / Linux ARMv7 (push) Has been cancelled
Rust / Linux ARM64 (push) Has been cancelled
Rust / Build on ubuntu-latest (push) Has been cancelled
- Use try_sapling_note_decryption with IVKs to detect wallet-owned outputs - Correctly identifies change sent to diversified addresses - Prevents change outputs from appearing as external recipients in tx history
This commit is contained in:
@@ -1452,11 +1452,12 @@ pub fn scan_full_tx(&self, tx: &Transaction, height: i32, datetime: u64) {
|
|||||||
// Also scan the output to see if it can be decoded with our OutgoingViewKey
|
// Also scan the output to see if it can be decoded with our OutgoingViewKey
|
||||||
// If it can, then we sent this transaction, so we should be able to get
|
// If it can, then we sent this transaction, so we should be able to get
|
||||||
// the memo and value for our records
|
// the memo and value for our records
|
||||||
// First, collect all our z addresses, to check for change
|
|
||||||
// Collect z addresses
|
// Collect IVKs to detect change outputs to diversified addresses
|
||||||
let z_addresses = self.zkeys.read().unwrap().iter().map( |zk| {
|
let ivks_for_change: Vec<_> = self.zkeys.read().unwrap().iter()
|
||||||
encode_payment_address(self.config.hrp_sapling_address(), &zk.zaddress)
|
.map(|zk| zk.extfvk.fvk.vk.ivk())
|
||||||
}).collect::<HashSet<String>>();
|
.collect();
|
||||||
|
|
||||||
// Search all ovks that we have
|
// Search all ovks that we have
|
||||||
let ovks: Vec<_> = self.zkeys.read().unwrap().iter()
|
let ovks: Vec<_> = self.zkeys.read().unwrap().iter()
|
||||||
.map(|zk| zk.extfvk.fvk.ovk.clone())
|
.map(|zk| zk.extfvk.fvk.ovk.clone())
|
||||||
@@ -1472,13 +1473,18 @@ pub fn scan_full_tx(&self, tx: &Transaction, height: i32, datetime: u64) {
|
|||||||
Some((note, payment_address, memo)) => {
|
Some((note, payment_address, memo)) => {
|
||||||
let address = encode_payment_address(self.config.hrp_sapling_address(),
|
let address = encode_payment_address(self.config.hrp_sapling_address(),
|
||||||
&payment_address);
|
&payment_address);
|
||||||
// Check if this is change, and if it also doesn't have a memo, don't add
|
|
||||||
// to the outgoing metadata.
|
// Check if this output belongs to our wallet using IVK decryption.
|
||||||
// If this is change (i.e., funds sent to ourself) AND has a memo, then
|
// This correctly detects change sent to diversified addresses,
|
||||||
// presumably the users is writing a memo to themself, so we will add it to
|
// not just the wallet's default z-address.
|
||||||
// the outgoing metadata, even though it might be confusing in the UI, but hopefully
|
let epk_prime = output.ephemeral_key.as_prime_order(&JUBJUB).unwrap();
|
||||||
// the user can make sense of it.
|
let is_to_self = ivks_for_change.iter().any(|ivk| {
|
||||||
if z_addresses.contains(&address) && memo.to_utf8().is_none() {
|
try_sapling_note_decryption(ivk, &epk_prime, &output.cmu, &output.enc_ciphertext).is_some()
|
||||||
|
});
|
||||||
|
|
||||||
|
// If this is change (funds to ourself) without a memo, skip it.
|
||||||
|
// If the user sent a memo to themselves, keep it in outgoing metadata.
|
||||||
|
if is_to_self && memo.to_utf8().is_none() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// Update the WalletTx
|
// Update the WalletTx
|
||||||
|
|||||||
Reference in New Issue
Block a user