Skip to content

Commit 941846a

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 cd1b7e7 commit 941846a

File tree

1 file changed

+18
-2
lines changed
  • lightning-block-sync/src

1 file changed

+18
-2
lines changed

lightning-block-sync/src/lib.rs

Lines changed: 18 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
///
@@ -350,8 +362,11 @@ impl<'a, L: chain::Listen + ?Sized> ChainNotifier<'a, L> {
350362
///
351363
/// First resolves `prev_best_block` to a `ValidatedBlockHeader` using the `previous_blocks`
352364
/// field as fallback if needed, then finds the common ancestor.
365+
///
366+
/// Updates the header cache as it goes, tracking headers needed to find the diff to reuse for
367+
/// other objects that might need similar headers.
353368
async fn find_difference_from_best_block<P: Poll>(
354-
&self, current_header: ValidatedBlockHeader, prev_best_block: BestBlock,
369+
&mut self, current_header: ValidatedBlockHeader, prev_best_block: BestBlock,
355370
chain_poller: &mut P,
356371
) -> BlockSourceResult<ChainDifference> {
357372
// Try to resolve the header for the previous best block. First try the block_hash,
@@ -376,6 +391,7 @@ impl<'a, L: chain::Listen + ?Sized> ChainNotifier<'a, L> {
376391
)?;
377392
if let Ok(header) = chain_poller.get_header(block_hash, Some(height)).await {
378393
found_header = Some(header);
394+
self.header_cache.insert_during_diff(*block_hash, header);
379395
break;
380396
}
381397
}

0 commit comments

Comments
 (0)