From b780587d26e0871ee98334b8f2a118834396edd2 Mon Sep 17 00:00:00 2001 From: DanS Date: Sun, 22 Mar 2026 10:30:04 -0500 Subject: [PATCH] Fix change detection: handle empty memo correctly memo.to_utf8() returns Some(Ok("")) for change outputs with all-zero bytes, not None. The previous check (memo.to_utf8().is_none()) never filtered change outputs because 0x00 < 0xF5 makes to_utf8() treat it as valid text. Now properly checks for empty string as well. --- lib/src/lightwallet.rs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index a2bebb6..f3bf736 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -1482,10 +1482,17 @@ pub fn scan_full_tx(&self, tx: &Transaction, height: i32, datetime: u64) { 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; + // If this is change (funds to ourself) without a meaningful memo, skip it. + // memo.to_utf8() returns Some(Ok("")) for empty memos (all-zero bytes), + // so we must also check for empty strings, not just None. + if is_to_self { + let has_memo = match memo.to_utf8() { + Some(Ok(ref s)) if !s.is_empty() => true, + _ => false, + }; + if !has_memo { + continue; + } } // Update the WalletTx // Do it in a short scope because of the write lock.