Browse Source

Disallow memos to t-addresses

checkpoints
Aditya Kulkarni 5 years ago
parent
commit
3e3f445ca3
  1. 10
      lib/src/commands.rs
  2. 19
      lib/src/lightwallet.rs
  3. 33
      lib/src/lightwallet/tests.rs

10
lib/src/commands.rs

@ -2,6 +2,7 @@ use std::collections::HashMap;
use json::{object};
use crate::lightclient::LightClient;
use crate::lightwallet::LightWallet;
pub trait Command {
fn help(&self) -> String;
@ -487,6 +488,8 @@ impl Command for SendCommand {
Err(s) => { return format!("Error: {}\n{}", s, self.help()); }
}
} else if args.len() == 2 || args.len() == 3 {
let address = args[0].to_string();
// Make sure we can parse the amount
let value = match args[1].parse::<u64>() {
Ok(amt) => amt,
@ -495,7 +498,12 @@ impl Command for SendCommand {
}
};
let memo = if args.len() == 3 { Some(args[2].to_string()) } else {None};
let memo = if args.len() == 3 { Some(args[2].to_string()) } else { None };
// Memo has to be None if not sending to a shileded address
if memo.is_some() && !LightWallet::is_shielded_address(&address, &lightclient.config) {
return format!("Can't send a memo to the non-shielded address {}", address);
}
vec![(args[0].to_string(), value, memo)]
} else {

19
lib/src/lightwallet.rs

@ -166,6 +166,16 @@ impl LightWallet {
(extsk, extfvk, address)
}
pub fn is_shielded_address(addr: &String, config: &LightClientConfig) -> bool {
match address::RecipientAddress::from_str(addr,
config.hrp_sapling_address(),
config.base58_pubkey_address(),
config.base58_script_address()) {
Some(address::RecipientAddress::Shielded(_)) => true,
_ => false,
}
}
pub fn new(seed_phrase: Option<String>, config: &LightClientConfig, latest_block: u64) -> io::Result<Self> {
// This is the source entropy that corresponds to the 24-word seed phrase
let mut seed_bytes = [0u8; 32];
@ -1572,7 +1582,14 @@ impl LightWallet {
value: *amt,
memo: match maybe_memo {
None => Memo::default(),
Some(s) => Memo::from_str(&s).unwrap(),
Some(s) => {
// If the address is not a z-address, then drop the memo
if LightWallet::is_shielded_address(&addr.to_string(), &self.config) {
Memo::from_str(s).unwrap()
} else {
Memo::default()
}
}
},
}
}).collect::<Vec<_>>();

33
lib/src/lightwallet/tests.rs

@ -922,7 +922,6 @@ fn test_z_spend_to_taddr() {
cb3.add_tx(&sent_tx);
wallet.scan_block(&cb3.as_bytes()).unwrap();
// Now this new Spent tx should be in, so the note should be marked confirmed spent
{
let txs = wallet.txs.read().unwrap();
@ -950,6 +949,38 @@ fn test_z_spend_to_taddr() {
assert_eq!(txs[&sent_txid].outgoing_metadata[0].value, AMOUNT_SENT);
assert_eq!(txs[&sent_txid].total_shielded_value_spent, AMOUNT1);
}
// Create a new Tx, but this time with a memo.
let raw_tx = wallet.send_to_address(branch_id, &ss, &so,
vec![(&taddr, AMOUNT_SENT, Some("T address memo".to_string()))]).unwrap();
let sent_tx = Transaction::read(&raw_tx[..]).unwrap();
let sent_txid2 = sent_tx.txid();
// There should be a mempool Tx, but the memo should be dropped, because it was sent to a
// t address
{
let txs = wallet.mempool_txs.read().unwrap();
assert_eq!(txs[&sent_txid2].outgoing_metadata.len(), 1);
assert_eq!(txs[&sent_txid2].outgoing_metadata[0].address, taddr);
assert_eq!(txs[&sent_txid2].outgoing_metadata[0].value, AMOUNT_SENT);
assert_eq!(LightWallet::memo_str(&Some(txs[&sent_txid2].outgoing_metadata[0].memo.clone())), None);
}
// Now add the block
let mut cb4 = FakeCompactBlock::new(3, cb3.hash());
cb4.add_tx(&sent_tx);
wallet.scan_block(&cb4.as_bytes()).unwrap();
wallet.scan_full_tx(&sent_tx, 3, 0);
// Check Outgoing Metadata for t address, but once again there should be no memo
{
let txs = wallet.txs.read().unwrap();
assert_eq!(txs[&sent_txid2].outgoing_metadata.len(), 1);
assert_eq!(txs[&sent_txid2].outgoing_metadata[0].address, taddr);
assert_eq!(txs[&sent_txid2].outgoing_metadata[0].value, AMOUNT_SENT);
assert_eq!(LightWallet::memo_str(&Some(txs[&sent_txid2].outgoing_metadata[0].memo.clone())), None);
}
}
#[test]

Loading…
Cancel
Save