@@ -31,7 +31,7 @@ use zcash_primitives::{
3131 consensus:: BlockHeight ,
3232 legacy:: TransparentAddress ,
3333 memo:: Memo ,
34- note_encryption:: { try_sapling_note_decryption, try_sapling_output_recovery} ,
34+ sapling :: note_encryption:: { try_sapling_note_decryption, try_sapling_output_recovery} ,
3535 transaction:: { Transaction , TxId } ,
3636} ;
3737
@@ -163,27 +163,29 @@ impl FetchFullTxns {
163163 let taddrs_set: HashSet < _ > = taddrs. iter ( ) . map ( |t| t. clone ( ) ) . collect ( ) ;
164164
165165 // Step 1: Scan all transparent outputs to see if we recieved any money
166- for ( n, vout) in tx. vout . iter ( ) . enumerate ( ) {
167- match vout. script_pubkey . address ( ) {
168- Some ( TransparentAddress :: PublicKey ( hash) ) => {
169- let output_taddr = hash. to_base58check ( & config. base58_pubkey_address ( ) , & [ ] ) ;
170- if taddrs_set. contains ( & output_taddr) {
171- // This is our address. Add this as an output to the txid
172- wallet_txns. write ( ) . await . add_new_taddr_output (
173- tx. txid ( ) ,
174- output_taddr. clone ( ) ,
175- height. into ( ) ,
176- unconfirmed,
177- block_time as u64 ,
178- & vout,
179- n as u32 ,
180- ) ;
181-
182- // Ensure that we add any new HD addresses
183- keys. write ( ) . await . ensure_hd_taddresses ( & output_taddr) ;
166+ if let Some ( t_bundle) = tx. transparent_bundle ( ) {
167+ for ( n, vout) in t_bundle. vout . iter ( ) . enumerate ( ) {
168+ match vout. script_pubkey . address ( ) {
169+ Some ( TransparentAddress :: PublicKey ( hash) ) => {
170+ let output_taddr = hash. to_base58check ( & config. base58_pubkey_address ( ) , & [ ] ) ;
171+ if taddrs_set. contains ( & output_taddr) {
172+ // This is our address. Add this as an output to the txid
173+ wallet_txns. write ( ) . await . add_new_taddr_output (
174+ tx. txid ( ) ,
175+ output_taddr. clone ( ) ,
176+ height. into ( ) ,
177+ unconfirmed,
178+ block_time as u64 ,
179+ & vout,
180+ n as u32 ,
181+ ) ;
182+
183+ // Ensure that we add any new HD addresses
184+ keys. write ( ) . await . ensure_hd_taddresses ( & output_taddr) ;
185+ }
184186 }
187+ _ => { }
185188 }
186- _ => { }
187189 }
188190 }
189191
@@ -198,21 +200,23 @@ impl FetchFullTxns {
198200
199201 {
200202 let current = & wallet_txns. read ( ) . await . current ;
201- for vin in tx. vin . iter ( ) {
202- // Find the prev txid that was spent
203- let prev_txid = TxId { 0 : * vin. prevout . hash ( ) } ;
204- let prev_n = vin. prevout . n ( ) as u64 ;
205-
206- if let Some ( wtx) = current. get ( & prev_txid) {
207- // One of the tx outputs is a match
208- if let Some ( spent_utxo) = wtx
209- . utxos
210- . iter ( )
211- . find ( |u| u. txid == prev_txid && u. output_index == prev_n)
212- {
213- info ! ( "Spent: utxo from {} was spent in {}" , prev_txid, tx. txid( ) ) ;
214- total_transparent_value_spent += spent_utxo. value ;
215- spent_utxos. push ( ( prev_txid, prev_n as u32 , tx. txid ( ) , height) ) ;
203+ if let Some ( t_bundle) = tx. transparent_bundle ( ) {
204+ for vin in t_bundle. vin . iter ( ) {
205+ // Find the prev txid that was spent
206+ let prev_txid = TxId :: from_bytes ( * vin. prevout . hash ( ) ) ;
207+ let prev_n = vin. prevout . n ( ) as u64 ;
208+
209+ if let Some ( wtx) = current. get ( & prev_txid) {
210+ // One of the tx outputs is a match
211+ if let Some ( spent_utxo) = wtx
212+ . utxos
213+ . iter ( )
214+ . find ( |u| u. txid == prev_txid && u. output_index == prev_n)
215+ {
216+ info ! ( "Spent: utxo from {} was spent in {}" , prev_txid, tx. txid( ) ) ;
217+ total_transparent_value_spent += spent_utxo. value ;
218+ spent_utxos. push ( ( prev_txid, prev_n as u32 , tx. txid ( ) , height) ) ;
219+ }
216220 }
217221 }
218222 }
@@ -246,17 +250,19 @@ impl FetchFullTxns {
246250 // because for txns in the block, we will check the nullifiers from the blockdata
247251 if unconfirmed {
248252 let unspent_nullifiers = wallet_txns. read ( ) . await . get_unspent_nullifiers ( ) ;
249- for s in tx. shielded_spends . iter ( ) {
250- if let Some ( ( nf, value, txid) ) = unspent_nullifiers. iter ( ) . find ( |( nf, _, _) | * nf == s. nullifier ) {
251- wallet_txns. write ( ) . await . add_new_spent (
252- tx. txid ( ) ,
253- height,
254- unconfirmed,
255- block_time,
256- * nf,
257- * value,
258- * txid,
259- ) ;
253+ if let Some ( s_bundle) = tx. sapling_bundle ( ) {
254+ for s in s_bundle. shielded_spends . iter ( ) {
255+ if let Some ( ( nf, value, txid) ) = unspent_nullifiers. iter ( ) . find ( |( nf, _, _) | * nf == s. nullifier ) {
256+ wallet_txns. write ( ) . await . add_new_spent (
257+ tx. txid ( ) ,
258+ height,
259+ unconfirmed,
260+ block_time,
261+ * nf,
262+ * value,
263+ * txid,
264+ ) ;
265+ }
260266 }
261267 }
262268 }
@@ -281,88 +287,76 @@ impl FetchFullTxns {
281287 // a second time by the Full Tx Fetcher
282288 let mut outgoing_metadatas = vec ! [ ] ;
283289
284- for output in tx. shielded_outputs . iter ( ) {
285- let cmu = output. cmu ;
286- let ct = output. enc_ciphertext ;
287-
288- // Search all of our keys
289- for ( i, ivk) in ivks. iter ( ) . enumerate ( ) {
290- let epk_prime = output. ephemeral_key ;
291-
292- let ( note, to, memo_bytes) =
293- match try_sapling_note_decryption ( & config. get_params ( ) , height, & ivk, & epk_prime, & cmu, & ct) {
294- Some ( ret) => ret,
295- None => continue ,
296- } ;
290+ if let Some ( s_bundle) = tx. sapling_bundle ( ) {
291+ for output in s_bundle. shielded_outputs . iter ( ) {
292+ // Search all of our keys
293+ for ( i, ivk) in ivks. iter ( ) . enumerate ( ) {
294+ let ( note, to, memo_bytes) =
295+ match try_sapling_note_decryption ( & config. get_params ( ) , height, & ivk, output) {
296+ Some ( ret) => ret,
297+ None => continue ,
298+ } ;
299+
300+ // info!("A sapling note was received into the wallet in {}", tx.txid());
301+ if unconfirmed {
302+ wallet_txns. write ( ) . await . add_pending_note (
303+ tx. txid ( ) ,
304+ height,
305+ block_time as u64 ,
306+ note. clone ( ) ,
307+ to,
308+ & extfvks. get ( i) . unwrap ( ) ,
309+ ) ;
310+ }
297311
298- // info!("A sapling note was received into the wallet in {}", tx.txid());
299- if unconfirmed {
300- wallet_txns. write ( ) . await . add_pending_note (
301- tx. txid ( ) ,
302- height,
303- block_time as u64 ,
304- note. clone ( ) ,
305- to,
306- & extfvks. get ( i) . unwrap ( ) ,
307- ) ;
312+ let memo = memo_bytes. clone ( ) . try_into ( ) . unwrap_or ( Memo :: Future ( memo_bytes) ) ;
313+ wallet_txns. write ( ) . await . add_memo_to_note ( & tx. txid ( ) , note, memo) ;
308314 }
309315
310- let memo = memo_bytes. clone ( ) . try_into ( ) . unwrap_or ( Memo :: Future ( memo_bytes) ) ;
311- wallet_txns. write ( ) . await . add_memo_to_note ( & tx. txid ( ) , note, memo) ;
312- }
313-
314- // Also scan the output to see if it can be decoded with our OutgoingViewKey
315- // If it can, then we sent this transaction, so we should be able to get
316- // the memo and value for our records
317-
318- // Search all ovks that we have
319- let omds = ovks
320- . iter ( )
321- . filter_map ( |ovk| {
322- match try_sapling_output_recovery (
323- & config. get_params ( ) ,
324- height,
325- & ovk,
326- & output. cv ,
327- & output. cmu ,
328- & output. ephemeral_key ,
329- & output. enc_ciphertext ,
330- & output. out_ciphertext ,
331- ) {
332- Some ( ( note, payment_address, memo_bytes) ) => {
333- // Mark this tx as an outgoing tx, so we can grab all outgoing metadata
334- is_outgoing_tx = true ;
335-
336- let address = encode_payment_address ( config. hrp_sapling_address ( ) , & payment_address) ;
337-
338- // Check if this is change, and if it also doesn't have a memo, don't add
339- // to the outgoing metadata.
340- // If this is change (i.e., funds sent to ourself) AND has a memo, then
341- // presumably the users is writing a memo to themself, so we will add it to
342- // the outgoing metadata, even though it might be confusing in the UI, but hopefully
343- // the user can make sense of it.
344- match Memo :: try_from ( memo_bytes) {
345- Err ( _) => None ,
346- Ok ( memo) => {
347- if z_addresses. contains ( & address) && memo == Memo :: Empty {
348- None
349- } else {
350- Some ( OutgoingTxMetadata {
351- address,
352- value : note. value ,
353- memo,
354- } )
316+ // Also scan the output to see if it can be decoded with our OutgoingViewKey
317+ // If it can, then we sent this transaction, so we should be able to get
318+ // the memo and value for our records
319+
320+ // Search all ovks that we have
321+ let omds = ovks
322+ . iter ( )
323+ . filter_map ( |ovk| {
324+ match try_sapling_output_recovery ( & config. get_params ( ) , height, & ovk, & output) {
325+ Some ( ( note, payment_address, memo_bytes) ) => {
326+ // Mark this tx as an outgoing tx, so we can grab all outgoing metadata
327+ is_outgoing_tx = true ;
328+
329+ let address = encode_payment_address ( config. hrp_sapling_address ( ) , & payment_address) ;
330+
331+ // Check if this is change, and if it also doesn't have a memo, don't add
332+ // to the outgoing metadata.
333+ // If this is change (i.e., funds sent to ourself) AND has a memo, then
334+ // presumably the users is writing a memo to themself, so we will add it to
335+ // the outgoing metadata, even though it might be confusing in the UI, but hopefully
336+ // the user can make sense of it.
337+ match Memo :: try_from ( memo_bytes) {
338+ Err ( _) => None ,
339+ Ok ( memo) => {
340+ if z_addresses. contains ( & address) && memo == Memo :: Empty {
341+ None
342+ } else {
343+ Some ( OutgoingTxMetadata {
344+ address,
345+ value : note. value ,
346+ memo,
347+ } )
348+ }
355349 }
356350 }
357351 }
352+ None => None ,
358353 }
359- None => None ,
360- }
361- } )
362- . collect :: < Vec < _ > > ( ) ;
354+ } )
355+ . collect :: < Vec < _ > > ( ) ;
363356
364- // Add it to the overall outgoing metadatas
365- outgoing_metadatas. extend ( omds) ;
357+ // Add it to the overall outgoing metadatas
358+ outgoing_metadatas. extend ( omds) ;
359+ }
366360 }
367361
368362 // Step 5. Process t-address outputs
@@ -373,22 +367,24 @@ impl FetchFullTxns {
373367 }
374368
375369 if is_outgoing_tx {
376- for vout in & tx. vout {
377- let taddr = keys. read ( ) . await . address_from_pubkeyhash ( vout. script_pubkey . address ( ) ) ;
378-
379- if taddr. is_some ( ) && !taddrs_set. contains ( taddr. as_ref ( ) . unwrap ( ) ) {
380- outgoing_metadatas. push ( OutgoingTxMetadata {
381- address : taddr. unwrap ( ) ,
382- value : vout. value . into ( ) ,
383- memo : Memo :: Empty ,
384- } ) ;
370+ if let Some ( t_bundle) = tx. transparent_bundle ( ) {
371+ for vout in & t_bundle. vout {
372+ let taddr = keys. read ( ) . await . address_from_pubkeyhash ( vout. script_pubkey . address ( ) ) ;
373+
374+ if taddr. is_some ( ) && !taddrs_set. contains ( taddr. as_ref ( ) . unwrap ( ) ) {
375+ outgoing_metadatas. push ( OutgoingTxMetadata {
376+ address : taddr. unwrap ( ) ,
377+ value : vout. value . into ( ) ,
378+ memo : Memo :: Empty ,
379+ } ) ;
380+ }
385381 }
386- }
387382
388- // Also, if this is an outgoing transaction, then mark all the *incoming* sapling notes to this Tx as change.
389- // Note that this is also done in `WalletTxns::add_new_spent`, but that doesn't take into account transparent spends,
390- // so we'll do it again here.
391- wallet_txns. write ( ) . await . check_notes_mark_change ( & tx. txid ( ) ) ;
383+ // Also, if this is an outgoing transaction, then mark all the *incoming* sapling notes to this Tx as change.
384+ // Note that this is also done in `WalletTxns::add_new_spent`, but that doesn't take into account transparent spends,
385+ // so we'll do it again here.
386+ wallet_txns. write ( ) . await . check_notes_mark_change ( & tx. txid ( ) ) ;
387+ }
392388 }
393389
394390 if !outgoing_metadatas. is_empty ( ) {
0 commit comments