From 94d3eb3f3862e49101bdecef13de02f71f989fce Mon Sep 17 00:00:00 2001 From: ardocrat Date: Sat, 11 Apr 2026 02:08:51 +0300 Subject: [PATCH] scan: save last scanned block info for initial wallet scanning --- libwallet/src/api_impl/owner.rs | 31 +++++++++++++++++++++++-------- libwallet/src/internal/scan.rs | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 10 deletions(-) diff --git a/libwallet/src/api_impl/owner.rs b/libwallet/src/api_impl/owner.rs index 017bf4e..9fc556a 100644 --- a/libwallet/src/api_impl/owner.rs +++ b/libwallet/src/api_impl/owner.rs @@ -983,6 +983,7 @@ where wallet_inst.clone(), keychain_mask, delete_unconfirmed, + None, start_height, tip.0, status_send_channel, @@ -1110,12 +1111,14 @@ where let last_scanned_block = { wallet_lock!(wallet_inst, w); match w.init_status()? { - WalletInitStatus::InitNeedsScanning => ScannedBlockInfo { - height: 0, - hash: "".to_owned(), - start_pmmr_index: 0, - last_pmmr_index: 0, - }, + WalletInitStatus::InitNeedsScanning => { + w.last_scanned_block().unwrap_or(ScannedBlockInfo { + height: 0, + hash: "".to_owned(), + start_pmmr_index: 0, + last_pmmr_index: 0, + }) + } WalletInitStatus::InitNoScanning => ScannedBlockInfo { height: tip.clone().0, hash: tip.clone().1, @@ -1126,7 +1129,12 @@ where } }; - let start_index = last_scanned_block.height.saturating_sub(100); + let start_height = last_scanned_block.height.saturating_sub(100); + + debug!( + "update_wallet_state: last_scanned_block: {:?}", + last_scanned_block + ); if last_scanned_block.height == 0 { let msg = "This wallet has not been scanned against the current chain. Beginning full scan... (this first scan may take a while, but subsequent scans will be much quicker)".to_string(); @@ -1135,11 +1143,18 @@ where } } + let start_pmmr_index = if last_scanned_block.start_pmmr_index == 0 { + None + } else { + Some(last_scanned_block.start_pmmr_index) + }; + let mut info = scan::scan( wallet_inst.clone(), keychain_mask, false, - start_index, + start_pmmr_index, + start_height, tip.0, status_send_channel, )?; diff --git a/libwallet/src/internal/scan.rs b/libwallet/src/internal/scan.rs index 129e99c..92efceb 100644 --- a/libwallet/src/internal/scan.rs +++ b/libwallet/src/internal/scan.rs @@ -226,7 +226,9 @@ where Ok(vw) } -fn collect_chain_outputs<'a, C, K>( +fn collect_chain_outputs<'a, L, C, K>( + wallet_inst: &Arc>>>, + keychain_mask: &Option<&SecretKey>, keychain: &K, client: C, start_index: u64, @@ -234,6 +236,7 @@ fn collect_chain_outputs<'a, C, K>( status_send_channel: &Option>, ) -> Result<(Vec, u64), Error> where + L: WalletLCProvider<'a, C, K>, C: NodeClient + 'a, K: Keychain + 'a, { @@ -242,6 +245,13 @@ where let mut start_index = start_index; let mut result_vec: Vec = vec![]; let last_retrieved_return_index; + + debug!( + "collect_chain_outputs: start_index {}, end_index {}", + start_index, + end_index.unwrap_or(0) + ); + loop { let (highest_index, last_retrieved_index, outputs) = client.get_outputs_by_pmmr_index(start_index, end_index, batch_size)?; @@ -267,6 +277,21 @@ where perc_complete as u8, )?); + // Save last scanned block info. + { + wallet_lock!(wallet_inst, w); + let mut batch = w.batch(*keychain_mask)?; + batch.save_last_scanned_block(ScannedBlockInfo { + height: 0, + hash: "".to_string(), + start_pmmr_index: start_index, + last_pmmr_index: last_retrieved_index, + })?; + batch.commit()?; + + debug!("collect_chain_outputs: save_last_scanned_block: start_index {}, last_pmmr_index {}", start_index, last_retrieved_index); + } + if highest_index <= last_retrieved_index { last_retrieved_return_index = last_retrieved_index; break; @@ -458,6 +483,7 @@ pub fn scan<'a, L, C, K>( wallet_inst: Arc>>>, keychain_mask: Option<&SecretKey>, delete_unconfirmed: bool, + start_pmmr_index: Option, start_height: u64, end_height: u64, status_send_channel: &Option>, @@ -479,10 +505,13 @@ where // Retrieve the actual PMMR index range we're looking for let pmmr_range = client.height_range_to_pmmr_indices(start_height, Some(end_height))?; + let start_pmmr_index = start_pmmr_index.unwrap_or(pmmr_range.0); let (chain_outs, last_index) = collect_chain_outputs( + &wallet_inst, + &keychain_mask, &keychain, client, - pmmr_range.0, + start_pmmr_index, Some(pmmr_range.1), status_send_channel, )?;