prevent unwrap in scan_taddress_txids

This commit is contained in:
Deniod
2024-01-13 21:55:47 +01:00
parent 35ce90eec9
commit feb26dbdfb

View File

@@ -1477,47 +1477,84 @@ pub fn start_mempool_monitor(lc: Arc<LightClient>) -> Result<(), String> {
} }
} }
} }
fn scan_taddress_txids(
fn scan_taddress_txids(&self, pool: &ThreadPool, block_times: Arc<RwLock<HashMap<u64, u32>>>, start_height: u64, end_height: u64, no_cert: bool) -> Result<Vec<()>, String> { &self,
// Copy over addresses so as to not lock up the wallet, which we'll use inside the callback below. pool: &ThreadPool,
let addresses = self.wallet.read().unwrap() block_times: Arc<RwLock<HashMap<u64, u32>>>,
start_height: u64,
end_height: u64,
no_cert: bool
) -> Result<Vec<()>, String> {
let addresses = self.wallet.read()
.map_err(|e| format!("Failed to read wallet: {:?}", e))?
.get_all_taddresses().iter() .get_all_taddresses().iter()
.map(|a| a.clone()) .cloned()
.collect::<Vec<String>>(); .collect::<Vec<String>>();
// Create a channel so the fetch_transparent_txids can send the results back
let (ctx, crx) = channel(); let (ctx, crx) = channel();
let num_addresses = addresses.len(); let num_addresses = addresses.len();
for address in addresses { for address in addresses {
let address_clone = address.clone();
let wallet = self.wallet.clone(); let wallet = self.wallet.clone();
let pool = pool.clone(); let pool = pool.clone();
let server_uri = self.get_server_uri(); let server_uri = self.get_server_uri();
let ctx = ctx.clone(); let ctx = ctx.clone();
let block_times = block_times.clone(); let block_times = block_times.clone();
pool.execute(move || { pool.execute(move || {
// Fetch the transparent transactions for this address, and send the results println!("Fetching transactions for address: {}", address_clone);
// via the channel
let r = fetch_transparent_txids(&server_uri, address, start_height, end_height,no_cert, let r = fetch_transparent_txids(
move |tx_bytes: &[u8], height: u64| { &server_uri,
let tx = Transaction::read(tx_bytes).unwrap(); address,
start_height,
// Scan this Tx for transparent inputs and outputs end_height,
let datetime = block_times.read().unwrap().get(&height).map(|v| *v).unwrap_or(0); no_cert,
wallet.read().unwrap().scan_full_tx(&tx, height as i32, datetime as u64); move |tx_bytes: &[u8], height: u64| {
}); let tx_result = Transaction::read(tx_bytes)
ctx.send(r).unwrap(); .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. crx.iter().take(num_addresses).collect()
// If it was not, we return an error, which will go back to the retry }
crx.iter().take(num_addresses).collect::<Result<Vec<()>, String>>()
}
fn scan_fill_fulltxs(&self, pool: &ThreadPool, decoy_txids: Vec<(TxId, i32)>) -> Result<Vec<()>, String> { fn scan_fill_fulltxs(&self, pool: &ThreadPool, decoy_txids: Vec<(TxId, i32)>) -> Result<Vec<()>, String> {
// We need to first copy over the Txids from the wallet struct, because // We need to first copy over the Txids from the wallet struct, because