diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 4f53169..09d8882 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -1477,47 +1477,84 @@ pub fn start_mempool_monitor(lc: Arc) -> Result<(), String> { } } } - - fn scan_taddress_txids(&self, pool: &ThreadPool, block_times: Arc>>, start_height: u64, end_height: u64, no_cert: bool) -> Result, String> { - // Copy over addresses so as to not lock up the wallet, which we'll use inside the callback below. - let addresses = self.wallet.read().unwrap() + fn scan_taddress_txids( + &self, + pool: &ThreadPool, + block_times: Arc>>, + start_height: u64, + end_height: u64, + no_cert: bool + ) -> Result, String> { + let addresses = self.wallet.read() + .map_err(|e| format!("Failed to read wallet: {:?}", e))? .get_all_taddresses().iter() - .map(|a| a.clone()) + .cloned() .collect::>(); - - // Create a channel so the fetch_transparent_txids can send the results back + let (ctx, crx) = channel(); let num_addresses = addresses.len(); - + for address in addresses { + let address_clone = address.clone(); let wallet = self.wallet.clone(); - let pool = pool.clone(); let server_uri = self.get_server_uri(); let ctx = ctx.clone(); - let block_times = block_times.clone(); - + pool.execute(move || { - // Fetch the transparent transactions for this address, and send the results - // via the channel - let r = fetch_transparent_txids(&server_uri, address, start_height, end_height,no_cert, - move |tx_bytes: &[u8], height: u64| { - let tx = Transaction::read(tx_bytes).unwrap(); - - // Scan this Tx for transparent inputs and outputs - let datetime = block_times.read().unwrap().get(&height).map(|v| *v).unwrap_or(0); - wallet.read().unwrap().scan_full_tx(&tx, height as i32, datetime as u64); - }); - ctx.send(r).unwrap(); + println!("Fetching transactions for address: {}", address_clone); + + let r = fetch_transparent_txids( + &server_uri, + address, + start_height, + end_height, + no_cert, + move |tx_bytes: &[u8], height: u64| { + let tx_result = Transaction::read(tx_bytes) + .map_err(|e| format!("Failed to read transaction: {:?}", e)); + + match tx_result { + Ok(tx) => { + let datetime_result = block_times.read() + .map_err(|e| format!("Failed to read block times: {:?}", e)) + .and_then(|bt| bt.get(&height).cloned().ok_or_else(|| format!("No datetime for height: {}", height))); + + match datetime_result { + Ok(datetime) => { + match wallet.read().map_err(|e| format!("Failed to read wallet: {:?}", e)) { + Ok(w) => { + w.scan_full_tx(&tx, height as i32, datetime as u64); + }, + Err(e) => { + println!("Error reading wallet: {}", e); + }, + } + }, + Err(e) => { + println!("Error processing transaction: {}", e); + }, + } + }, + Err(e) => { + println!("Error reading transaction: {}", e); + }, + } + } + ); + + match ctx.send(r) { + Ok(_) => println!("Successfully sent data for address: {}", address_clone), + Err(e) => println!("Failed to send data for address: {}: {:?}", address_clone, e), + } }); } - - // Collect all results from the transparent fetches, and make sure everything was OK. - // If it was not, we return an error, which will go back to the retry - crx.iter().take(num_addresses).collect::, String>>() - } - + + crx.iter().take(num_addresses).collect() + } + + fn scan_fill_fulltxs(&self, pool: &ThreadPool, decoy_txids: Vec<(TxId, i32)>) -> Result, String> { // We need to first copy over the Txids from the wallet struct, because