From 990026d621d83803487bbd9bc5106793789ab471 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Thu, 3 Oct 2019 11:41:31 -0700 Subject: [PATCH] Store exspk with the SpendableNote --- src/lightwallet.rs | 55 +++++++++++++++++++++-------------------- src/lightwallet/data.rs | 5 +++- 2 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/lightwallet.rs b/src/lightwallet.rs index 089b6db..67386bb 100644 --- a/src/lightwallet.rs +++ b/src/lightwallet.rs @@ -597,20 +597,21 @@ impl LightWallet { None => { let address = self.address_from_pubkeyhash(vout.script_pubkey.address()); if address.is_none() { - println!("Couldn't determine address for output!"); + error!("Couldn't determine address for output!"); + } else { + info!("Added to wallet {}:{}", txid, n); + // Add the utxo + tx_entry.utxos.push(Utxo { + address: address.unwrap(), + txid: txid.clone(), + output_index: n, + script: vout.script_pubkey.0.clone(), + value: vout.value.into(), + height, + spent: None, + unconfirmed_spent: None, + }); } - info!("Added to wallet {}:{}", txid, n); - // Add the utxo - tx_entry.utxos.push(Utxo{ - address: address.unwrap(), - txid: txid.clone(), - output_index: n, - script: vout.script_pubkey.0.clone(), - value: vout.value.into(), - height, - spent: None, - unconfirmed_spent: None, - }); } } } @@ -622,10 +623,6 @@ impl LightWallet { // TODO: Save this object let secp = secp256k1::Secp256k1::new(); - // TODO: Iterate over all transparent addresses. This is currently looking only at - // the first one. - let pubkey = secp256k1::PublicKey::from_secret_key(&secp, &self.tkeys.read().unwrap()[0]).serialize(); - let mut total_transparent_spend: u64 = 0; for vin in tx.vin.iter() { @@ -667,6 +664,9 @@ impl LightWallet { .total_transparent_value_spent = total_transparent_spend; } + // TODO: Iterate over all transparent addresses. This is currently looking only at + // the first one. + let pubkey = secp256k1::PublicKey::from_secret_key(&secp, &self.tkeys.read().unwrap()[0]).serialize(); // Scan for t outputs for (n, vout) in tx.vout.iter().enumerate() { match vout.script_pubkey.address() { @@ -782,10 +782,10 @@ impl LightWallet { } // Update the WalletTx - info!("A sapling output was sent in {}", tx.txid()); + // Do it in a short scope because of the write lock. { - // Do it in a short scope because of the write lock. - + info!("A sapling output was sent in {}", tx.txid()); + let mut txs = self.txs.write().unwrap(); if txs.get(&tx.txid()).unwrap().outgoing_metadata.iter() .find(|om| om.address == address && om.value == note.value) @@ -1059,11 +1059,6 @@ impl LightWallet { to ); - // TODO: This only spends from the first address right now. - let extsk = &self.extsks.read().unwrap()[0]; - let extfvk = &self.extfvks.read().unwrap()[0]; - let ovk = extfvk.fvk.ovk; - let to = match address::RecipientAddress::from_str(to, self.config.hrp_sapling_address(), self.config.base58_pubkey_address(), @@ -1091,7 +1086,9 @@ impl LightWallet { let notes: Vec<_> = self.txs.read().unwrap().iter() .map(|(txid, tx)| tx.notes.iter().map(move |note| (*txid, note))) .flatten() - .filter_map(|(txid, note)| SpendableNote::from(txid, note, anchor_offset)) + .filter_map(|(txid, note)| + SpendableNote::from(txid, note, anchor_offset, &self.extsks.read().unwrap()[note.account]) + ) .scan(0, |running_total, spendable| { let value = spendable.note.value; let ret = if *running_total < u64::from(target_value) { @@ -1160,7 +1157,7 @@ impl LightWallet { for selected in notes.iter() { if let Err(e) = builder.add_sapling_spend( - extsk.clone(), + selected.extsk.clone(), selected.diversifier, selected.note.clone(), selected.witness.clone(), @@ -1183,6 +1180,10 @@ impl LightWallet { let encoded_memo = memo.map(|s| Memo::from_str(&s).unwrap() ); println!("{}: Adding output", now() - start_time); + + // TODO: We're using the first ovk to encrypt outgoing Txns. Is that Ok? + let ovk = self.extfvks.read().unwrap()[0].fvk.ovk; + if let Err(e) = match to { address::RecipientAddress::Shielded(to) => { builder.add_sapling_output(ovk, to.clone(), value, encoded_memo) diff --git a/src/lightwallet/data.rs b/src/lightwallet/data.rs index 2142e19..8ee5c80 100644 --- a/src/lightwallet/data.rs +++ b/src/lightwallet/data.rs @@ -22,6 +22,7 @@ use zcash_primitives::{ fs::{Fs, FsRepr}, } }; +use zcash_primitives::zip32::ExtendedSpendingKey; pub struct BlockData { @@ -468,10 +469,11 @@ pub struct SpendableNote { pub diversifier: Diversifier, pub note: Note, pub witness: IncrementalWitness, + pub extsk: ExtendedSpendingKey, } impl SpendableNote { - pub fn from(txid: TxId, nd: &SaplingNoteData, anchor_offset: usize) -> Option { + pub fn from(txid: TxId, nd: &SaplingNoteData, anchor_offset: usize, extsk: &ExtendedSpendingKey) -> Option { // Include only notes that haven't been spent, or haven't been included in an unconfirmed spend yet. if nd.spent.is_none() && nd.unconfirmed_spent.is_none() { let witness = nd.witnesses.get(nd.witnesses.len() - anchor_offset - 1); @@ -482,6 +484,7 @@ impl SpendableNote { diversifier: nd.diversifier, note: nd.note.clone(), witness: w.clone(), + extsk: extsk.clone(), }) } else { None