From 3b1f46e5332661905d25b9c01de82cda0f898c83 Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Sun, 22 Sep 2019 21:19:13 -0700 Subject: [PATCH] transparent receive / spend --- src/lightwallet/mod.rs | 112 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 107 insertions(+), 5 deletions(-) diff --git a/src/lightwallet/mod.rs b/src/lightwallet/mod.rs index daf0189..41a0780 100644 --- a/src/lightwallet/mod.rs +++ b/src/lightwallet/mod.rs @@ -546,7 +546,7 @@ impl LightWallet { match spent_utxo { Some(su) => { info!("Spent utxo from {} was spent in {}", txid, tx.txid()); - su.spent = Some(txid.clone()); + su.spent = Some(tx.txid().clone()); su.unconfirmed_spent = None; total_transparent_spend += su.value; @@ -1098,14 +1098,17 @@ pub mod tests { jubjub::fs::Fs, note_encryption::{Memo, SaplingNoteEncryption}, primitives::{Note, PaymentAddress}, + legacy::{Script, TransparentAddress,}, transaction::{ - TxId, - components::Amount, + TxId, Transaction, TransactionData, + components::{TxOut, TxIn, OutPoint, Amount,}, }, zip32::{ExtendedFullViewingKey, ExtendedSpendingKey}, JUBJUB, }; + use sha2::{Sha256, Digest}; + use super::LightWallet; use crate::LightClientConfig; @@ -1255,7 +1258,6 @@ pub mod tests { cout.set_ciphertext(enc_ciphertext[..52].to_vec()); cout }); - self.block.vtx.push(ctx); @@ -1316,7 +1318,7 @@ pub mod tests { // First, add an incoming transaction const AMOUNT1:u64 = 5; - + let mut cb1 = FakeCompactBlock::new(0, BlockHash([0; 32])); let (nf1, txid1) = cb1.add_tx_paying(wallet.extfvks[0].clone(), AMOUNT1); @@ -1355,4 +1357,104 @@ pub mod tests { assert_eq!(txs[&txid2].notes[0].is_change, true); assert_eq!(txs[&txid2].total_shielded_value_spent, AMOUNT1); } + + #[test] + fn test_t_receive_spend() { + let mut rng = OsRng; + let secp = secp256k1::Secp256k1::new(); + + let wallet = LightWallet::new(None, &LightClientConfig { + server: "0.0.0.0:0".to_string(), + chain_name: "test".to_string(), + sapling_activation_height: 0 + }).unwrap(); + + let pk = secp256k1::PublicKey::from_secret_key(&secp, &wallet.tkeys[0]); + let mut hash160 = ripemd160::Ripemd160::new(); + hash160.input(Sha256::digest(&pk.serialize()[..].to_vec())); + + let taddr_bytes = hash160.result(); + let taddr = wallet.address_from_sk(&wallet.tkeys[0]); + + let mut txid = vec![0; 32]; + rng.fill_bytes(&mut txid); + let txid1 = TxId{0: txid[..].try_into().unwrap()}; + + const AMOUNT1: u64 = 20; + + let mut td = TransactionData::new(); + td.vout.push(TxOut{ + value: Amount::from_u64(AMOUNT1).unwrap(), + script_pubkey: TransparentAddress::PublicKey(taddr_bytes.try_into().unwrap()).script(), + }); + + let tx = Transaction{ + txid: txid1, + data: td, + }; + + wallet.scan_full_tx(&tx, 100); // Pretent it is at height 100 + + { + let txs = wallet.txs.read().unwrap(); + + // Now make sure the t addr was recieved + assert_eq!(txs.len(), 1); + assert_eq!(txs[&txid1].utxos.len(), 1); + assert_eq!(txs[&txid1].utxos[0].address, taddr); + assert_eq!(txs[&txid1].utxos[0].txid, txid1); + assert_eq!(txs[&txid1].utxos[0].output_index, 0); + assert_eq!(txs[&txid1].utxos[0].value, AMOUNT1); + assert_eq!(txs[&txid1].utxos[0].height, 100); + assert_eq!(txs[&txid1].utxos[0].spent, None); + assert_eq!(txs[&txid1].utxos[0].unconfirmed_spent, None); + + assert_eq!(wallet.tbalance(None), AMOUNT1); + assert_eq!(wallet.tbalance(Some(taddr)), AMOUNT1); + } + + // Create a new Tx, spending this taddr + let mut td = TransactionData::new(); + td.vin.push(TxIn{ + prevout: OutPoint{ + hash: txid1.0, + n: 0 + }, + script_sig: Script{0: vec![]}, + sequence: 0, + }); + + // Create a new txid + let mut txid = vec![0; 32]; + rng.fill_bytes(&mut txid); + let txid2 = TxId{0: txid[..].try_into().unwrap()}; + + let tx = Transaction{ + txid: txid2, + data: td, + }; + + wallet.scan_full_tx(&tx, 101); // Pretent it is at height 101 + + { + // Make sure the txid was spent + let txs = wallet.txs.read().unwrap(); + + // Old utxo, that should be spent now + assert_eq!(txs.len(), 2); + assert_eq!(txs[&txid1].utxos.len(), 1); + assert_eq!(txs[&txid1].utxos[0].value, AMOUNT1); + assert_eq!(txs[&txid1].utxos[0].spent, Some(txid2)); + assert_eq!(txs[&txid1].utxos[0].unconfirmed_spent, None); + + assert_eq!(txs[&txid2].block, 101); // The second TxId is at block 101 + assert_eq!(txs[&txid2].utxos.len(), 0); // The second TxId has not UTXOs + assert_eq!(txs[&txid2].total_transparent_value_spent, AMOUNT1); + + + // Make sure there is no t-ZEC left + assert_eq!(wallet.tbalance(None), 0); + } + + } } \ No newline at end of file