|
|
@ -1477,47 +1477,84 @@ pub fn start_mempool_monitor(lc: Arc<LightClient>) -> Result<(), String> { |
|
|
|
}
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
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> { |
|
|
|
// 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<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() |
|
|
|
.map(|a| a.clone()) |
|
|
|
.cloned() |
|
|
|
.collect::<Vec<String>>(); |
|
|
|
|
|
|
|
// 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::<Result<Vec<()>, String>>() |
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
crx.iter().take(num_addresses).collect() |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|