diff --git a/pepper-sync/src/sync.rs b/pepper-sync/src/sync.rs index 1f656797c..7413859df 100644 --- a/pepper-sync/src/sync.rs +++ b/pepper-sync/src/sync.rs @@ -1184,8 +1184,8 @@ where let sync_state = wallet .get_sync_state_mut() .map_err(SyncError::WalletError)?; - let wallet_height = sync_state - .wallet_height() + let highest_scanned_height = sync_state + .highest_scanned_height() .expect("scan ranges should not be empty in this scope"); for transaction in transactions.values() { state::update_found_note_shard_priority( @@ -1220,7 +1220,7 @@ where .update_shard_trees( fetch_request_sender, scan_range, - wallet_height, + highest_scanned_height, sapling_located_trees, orchard_located_trees, ) diff --git a/pepper-sync/src/wallet/traits.rs b/pepper-sync/src/wallet/traits.rs index f8017a275..7821c71a3 100644 --- a/pepper-sync/src/wallet/traits.rs +++ b/pepper-sync/src/wallet/traits.rs @@ -233,12 +233,14 @@ pub trait SyncShardTrees: SyncWallet { /// Get mutable reference to shard trees fn get_shard_trees_mut(&mut self) -> Result<&mut ShardTrees, Self::Error>; - /// Update wallet shard trees with new shard tree data + /// Update wallet shard trees with new shard tree data. + /// + /// `highest_scanned_height` is the height of the highest scanned block in the wallet not including the `scan_range` we are updating. fn update_shard_trees( &mut self, fetch_request_sender: mpsc::UnboundedSender, scan_range: &ScanRange, - wallet_height: BlockHeight, + highest_scanned_height: BlockHeight, sapling_located_trees: Vec>, orchard_located_trees: Vec>, ) -> impl std::future::Future>> + Send @@ -248,18 +250,27 @@ pub trait SyncShardTrees: SyncWallet { async move { let shard_trees = self.get_shard_trees_mut().map_err(SyncError::WalletError)?; - // limit the range that checkpoints are manually added to the top MAX_VERIFICATION_WINDOW blocks for efficiency. + // limit the range that checkpoints are manually added to the top MAX_VERIFICATION_WINDOW scanned blocks for efficiency. // As we sync the chain tip first and have spend-before-sync, we will always choose anchors very close to chain // height and we will also never need to truncate to checkpoints lower than this height. - let verification_window_start = - wallet_height.saturating_sub(MAX_VERIFICATION_WINDOW) + 1; - let checkpoint_range = match ( - scan_range.block_range().start >= verification_window_start, - scan_range.block_range().end > verification_window_start, - ) { - (true, _) => scan_range.block_range().clone(), - (false, true) => verification_window_start..scan_range.block_range().end, - (false, false) => BlockHeight::from_u32(0)..BlockHeight::from_u32(0), + let checkpoint_range = if scan_range.block_range().start > highest_scanned_height { + let verification_window_start = scan_range + .block_range() + .end + .saturating_sub(MAX_VERIFICATION_WINDOW); + + std::cmp::max(scan_range.block_range().start, verification_window_start) + ..scan_range.block_range().end + } else if scan_range.block_range().end + > highest_scanned_height.saturating_sub(MAX_VERIFICATION_WINDOW) + 1 + { + let verification_window_start = + highest_scanned_height.saturating_sub(MAX_VERIFICATION_WINDOW) + 1; + + std::cmp::max(scan_range.block_range().start, verification_window_start) + ..scan_range.block_range().end + } else { + BlockHeight::from_u32(0)..BlockHeight::from_u32(0) }; // in the case that sapling and/or orchard note commitments are not in an entire block there will be no retention