Skip to content

Commit 37887fd

Browse files
committed
Use the header cache across listeners during initial disconnect
In `lightning-blocksync::init::synchronize_listeners`, we may have many listeners we want to do a chain diff on. When doing so, we should make sure we utilize our header cache, rather than querying our chain source for every header we need for each listener. Here we do so, inserting into the cache as we do chain diffs. On my node with a bitcoind on localhost, this brings the calculate-differences step of `init::synchronize_listeners` from ~500ms to under 150ms.
1 parent 60ceba7 commit 37887fd

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

  • lightning-block-sync/src

lightning-block-sync/src/lib.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ impl HeaderCache {
206206
self.headers.get(block_hash)
207207
}
208208

209-
210209
/// Called when a block has been connected to the best chain to ensure it is available to be
211210
/// disconnected later if needed.
212211
pub(crate) fn block_connected(
@@ -219,6 +218,19 @@ impl HeaderCache {
219218
self.headers.retain(|_, header| header.height >= cutoff_height);
220219
}
221220

221+
/// Inserts the given block header during a find_difference operation, implying it might not be
222+
/// the best header.
223+
pub(crate) fn insert_during_diff(
224+
&mut self, block_hash: BlockHash, block_header: ValidatedBlockHeader,
225+
) {
226+
self.headers.insert(block_hash, block_header);
227+
228+
// Remove headers older than our newest header minus a week.
229+
let best_height = self.headers.iter().map(|(_, header)| header.height).max().unwrap_or(0);
230+
let cutoff_height = best_height.saturating_sub(HEADER_CACHE_LIMIT);
231+
self.headers.retain(|_, header| header.height >= cutoff_height);
232+
}
233+
222234
/// Called when blocks have been disconnected from the best chain. Only the fork point
223235
/// (best common ancestor) is provided.
224236
///
@@ -351,7 +363,7 @@ impl<'a, L: chain::Listen + ?Sized> ChainNotifier<'a, L> {
351363
/// First resolves `prev_best_block` to a `ValidatedBlockHeader` using the `previous_blocks`
352364
/// field as fallback if needed, then finds the common ancestor.
353365
async fn find_difference_from_best_block<P: Poll>(
354-
&self, current_header: ValidatedBlockHeader, prev_best_block: BestBlock,
366+
&mut self, current_header: ValidatedBlockHeader, prev_best_block: BestBlock,
355367
chain_poller: &mut P,
356368
) -> BlockSourceResult<ChainDifference> {
357369
// Try to resolve the header for the previous best block. First try the block_hash,
@@ -376,6 +388,7 @@ impl<'a, L: chain::Listen + ?Sized> ChainNotifier<'a, L> {
376388
)?;
377389
if let Ok(header) = chain_poller.get_header(block_hash, Some(height)).await {
378390
found_header = Some(header);
391+
self.header_cache.insert_during_diff(*block_hash, header);
379392
break;
380393
}
381394
}

0 commit comments

Comments
 (0)