From 8ff6d15e3286d8685fcdee8a1a99fb34cbcf8569 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Fri, 6 Sep 2019 15:25:08 -0700 Subject: [PATCH] Add more fields to sapling note data --- rust-lightclient/src/lightclient.rs | 31 ++++++++--------- rust-lightclient/src/lightwallet.rs | 53 +++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 23 deletions(-) diff --git a/rust-lightclient/src/lightclient.rs b/rust-lightclient/src/lightclient.rs index 35e21f6..169f495 100644 --- a/rust-lightclient/src/lightclient.rs +++ b/rust-lightclient/src/lightclient.rs @@ -232,22 +232,21 @@ impl LightClient { }); }; - // Print all the memos for fun. - let memos = self.wallet.txs.read().unwrap() - .values().flat_map(|wtx| { - wtx.notes.iter().map(|nd| nd.memo.clone() ).collect::>>() - }) - .map( |m| match m { - Some(memo) => { - match memo.to_utf8() { - Some(Ok(memo_str)) => Some(memo_str), - _ => None - } - } - _ => None - }) - .collect::>>(); - + // // Print all the memos for fun. + // let memos = self.wallet.txs.read().unwrap() + // .values().flat_map(|wtx| { + // wtx.notes.iter().map(|nd| nd.memo.clone() ).collect::>>() + // }) + // .map( |m| match m { + // Some(memo) => { + // match memo.to_utf8() { + // Some(Ok(memo_str)) => Some(memo_str), + // _ => None + // } + // } + // _ => None + // }) + // .collect::>>(); //println!("All Wallet Txns {:?}", memos); } diff --git a/rust-lightclient/src/lightwallet.rs b/rust-lightclient/src/lightwallet.rs index 2f9811c..2671ec0 100644 --- a/rust-lightclient/src/lightwallet.rs +++ b/rust-lightclient/src/lightwallet.rs @@ -95,11 +95,12 @@ pub struct SaplingNoteData { account: usize, extfvk: ExtendedFullViewingKey, // Technically, this should be recoverable from the account number, but we're going to refactor this in the future, so I'll write it again here. diversifier: Diversifier, - note: Note, + pub note: Note, witnesses: Vec>, nullifier: [u8; 32], - spent: Option, - pub memo: Option + pub spent: Option, + pub memo: Option, + pub is_change: bool, } @@ -160,7 +161,8 @@ impl SaplingNoteData { witnesses: vec![witness], nullifier: nf, spent: None, - memo: None + memo: None, + is_change: output.is_change, } } @@ -208,6 +210,8 @@ impl SaplingNoteData { } })?; + let is_change: bool = reader.read_u8()? > 0; + Ok(SaplingNoteData { account, extfvk, @@ -216,7 +220,8 @@ impl SaplingNoteData { witnesses, nullifier, spent, - memo + memo, + is_change, }) } @@ -245,30 +250,54 @@ impl SaplingNoteData { Optional::write(&mut writer, &self.memo, |w, m| w.write_all(m.as_bytes()))?; + writer.write_u8(if self.is_change {1} else {0})?; + Ok(()) } } pub struct WalletTx { - block: i32, + pub block: i32, + + // Txid of this transcation. It's duplicated here (It is also the Key in the HashMap that points to this + // WalletTx in LightWallet::txs) + pub txid: TxId, + + // List of all notes recieved in this tx. Note that some of these might be change notes. pub notes: Vec, + + // Total shielded value spent in this Tx. Note that this is the value of notes spent, + // the change is returned in the notes above. Subtract the two to get the actual value spent. + // Also note that even after subtraction, you might need to account for transparent inputs and outputs + // to make sure the value is accurate. + pub total_shielded_value_spent: u64, } impl WalletTx { pub fn serialized_version() -> u64 { return 1; } + pub fn read(mut reader: R) -> io::Result { let version = reader.read_u64::()?; assert_eq!(version, WalletTx::serialized_version()); let block = reader.read_i32::()?; + let mut txid_bytes = [0u8; 32]; + reader.read_exact(&mut txid_bytes)?; + + let txid = TxId{0: txid_bytes}; + let notes = Vector::read(&mut reader, |r| SaplingNoteData::read(r))?; + let total_shielded_value_spent = reader.read_u64::()?; + Ok(WalletTx{ block, - notes + txid, + notes, + total_shielded_value_spent }) } @@ -277,8 +306,12 @@ impl WalletTx { writer.write_i32::(self.block)?; + writer.write_all(&self.txid.0)?; + Vector::write(&mut writer, &self.notes, |w, nd| nd.write(w))?; + writer.write_u64::(self.total_shielded_value_spent)?; + Ok(()) } } @@ -613,7 +646,10 @@ impl LightWallet { for tx in new_txs { // Mark notes as spent. + let mut total_shielded_value_spent: u64 = 0; + for spend in &tx.shielded_spends { + // TODO: Add up the spent value here and add it to the WalletTx as a Spent let txid = nfs .iter() .find(|(nf, _, _)| &nf[..] == &spend.nf[..]) @@ -627,13 +663,16 @@ impl LightWallet { .find(|nd| &nd.nullifier[..] == &spend.nf[..]) .unwrap(); spent_note.spent = Some(tx.txid); + total_shielded_value_spent += spent_note.note.value; } // Find the existing transaction entry, or create a new one. if !txs.contains_key(&tx.txid) { let tx_entry = WalletTx { block: block_data.height, + txid: tx.txid, notes: vec![], + total_shielded_value_spent }; txs.insert(tx.txid, tx_entry); }