From 21e7e20d6ced72d6fbd037a89ac38df9c0d1ec7c Mon Sep 17 00:00:00 2001 From: DenioD <41270280+DenioD@users.noreply.github.com> Date: Thu, 30 Jul 2020 11:30:19 +0200 Subject: [PATCH] Grab sync lock when sending to prevent anchor changes ported from https://github.com/adityapk00/zecwallet-light-cli/commit/5a885adc15fb1aeed4ca16b87286719d45893a7a --- lib/src/lightclient.rs | 14 +++++++++----- lib/src/lightwallet.rs | 11 +++++++++-- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 3b5d0cf..545a4eb 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -1277,11 +1277,15 @@ impl LightClient { info!("Creating transaction"); - let rawtx = self.wallet.write().unwrap().send_to_address( - u32::from_str_radix(&self.config.consensus_branch_id, 16).unwrap(), - &self.sapling_spend, &self.sapling_output, - addrs - ); + let rawtx = { + let _lock = self.sync_lock.lock().unwrap(); + + self.wallet.write().unwrap().send_to_address( + u32::from_str_radix(&self.config.consensus_branch_id, 16).unwrap(), + &self.sapling_spend, &self.sapling_output, + addrs + ) + }; match rawtx { Ok(txbytes) => broadcast_raw_tx(&self.get_server_uri(), self.config.no_cert_verification, txbytes), diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index 71ec362..d959355 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -1802,12 +1802,19 @@ impl LightWallet { // Select notes to cover the target value println!("{}: Selecting notes", now() - start_time); let target_value = Amount::from_u64(total_value).unwrap() + DEFAULT_FEE ; - let notes: Vec<_> = self.txs.read().unwrap().iter() + // Select the candidate notes that are eligible to be spent + let mut candidate_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, &self.extsks.read().unwrap()[note.account]) - ) + ).collect(); + + // Sort by highest value-notes first. + candidate_notes.sort_by(|a, b| b.note.value.cmp(&a.note.value)); + + // Select the minimum number of notes required to satisfy the target value + let notes: Vec<_> = candidate_notes.iter() .scan(0, |running_total, spendable| { let value = spendable.note.value; let ret = if *running_total < u64::from(target_value) {