@@ -202,9 +202,11 @@ pub trait Cache {
202202 /// disconnected later if needed.
203203 fn block_connected ( & mut self , block_hash : BlockHash , block_header : ValidatedBlockHeader ) ;
204204
205- /// Called when a block has been disconnected from the best chain. Once disconnected, a block's
206- /// header is no longer needed and thus can be removed.
207- fn block_disconnected ( & mut self , block_hash : & BlockHash ) -> Option < ValidatedBlockHeader > ;
205+ /// Called when blocks have been disconnected from the best chain. Only the fork point
206+ /// (best comon ancestor) is provided.
207+ ///
208+ /// Once disconnected, a block's header is no longer needed and thus can be removed.
209+ fn blocks_disconnected ( & mut self , fork_point : & ValidatedBlockHeader ) ;
208210}
209211
210212/// Unbounded cache of block headers keyed by block hash.
@@ -219,8 +221,8 @@ impl Cache for UnboundedCache {
219221 self . insert ( block_hash, block_header) ;
220222 }
221223
222- fn block_disconnected ( & mut self , block_hash : & BlockHash ) -> Option < ValidatedBlockHeader > {
223- self . remove ( block_hash )
224+ fn blocks_disconnected ( & mut self , fork_point : & ValidatedBlockHeader ) {
225+ self . retain ( |_ , block_info| block_info . height < fork_point . height ) ;
224226 }
225227}
226228
@@ -315,9 +317,6 @@ struct ChainDifference {
315317 /// If there are any disconnected blocks, this is where the chain forked.
316318 common_ancestor : ValidatedBlockHeader ,
317319
318- /// Blocks that were disconnected from the chain since the last poll.
319- disconnected_blocks : Vec < ValidatedBlockHeader > ,
320-
321320 /// Blocks that were connected to the chain since the last poll.
322321 connected_blocks : Vec < ValidatedBlockHeader > ,
323322}
@@ -341,7 +340,9 @@ where
341340 . find_difference ( new_header, old_header, chain_poller)
342341 . await
343342 . map_err ( |e| ( e, None ) ) ?;
344- self . disconnect_blocks ( difference. disconnected_blocks ) ;
343+ if difference. common_ancestor != * old_header {
344+ self . disconnect_blocks ( difference. common_ancestor ) ;
345+ }
345346 self . connect_blocks ( difference. common_ancestor , difference. connected_blocks , chain_poller)
346347 . await
347348 }
@@ -354,7 +355,6 @@ where
354355 & self , current_header : ValidatedBlockHeader , prev_header : & ValidatedBlockHeader ,
355356 chain_poller : & mut P ,
356357 ) -> BlockSourceResult < ChainDifference > {
357- let mut disconnected_blocks = Vec :: new ( ) ;
358358 let mut connected_blocks = Vec :: new ( ) ;
359359 let mut current = current_header;
360360 let mut previous = * prev_header;
@@ -369,7 +369,6 @@ where
369369 let current_height = current. height ;
370370 let previous_height = previous. height ;
371371 if current_height <= previous_height {
372- disconnected_blocks. push ( previous) ;
373372 previous = self . look_up_previous_header ( chain_poller, & previous) . await ?;
374373 }
375374 if current_height >= previous_height {
@@ -379,7 +378,7 @@ where
379378 }
380379
381380 let common_ancestor = current;
382- Ok ( ChainDifference { common_ancestor, disconnected_blocks , connected_blocks } )
381+ Ok ( ChainDifference { common_ancestor, connected_blocks } )
383382 }
384383
385384 /// Returns the previous header for the given header, either by looking it up in the cache or
@@ -394,16 +393,10 @@ where
394393 }
395394
396395 /// Notifies the chain listeners of disconnected blocks.
397- fn disconnect_blocks ( & mut self , disconnected_blocks : Vec < ValidatedBlockHeader > ) {
398- for header in disconnected_blocks. iter ( ) {
399- if let Some ( cached_header) = self . header_cache . block_disconnected ( & header. block_hash ) {
400- assert_eq ! ( cached_header, * header) ;
401- }
402- }
403- if let Some ( block) = disconnected_blocks. last ( ) {
404- let fork_point = BestBlock :: new ( block. header . prev_blockhash , block. height - 1 ) ;
405- self . chain_listener . blocks_disconnected ( fork_point) ;
406- }
396+ fn disconnect_blocks ( & mut self , fork_point : ValidatedBlockHeader ) {
397+ self . header_cache . blocks_disconnected ( & fork_point) ;
398+ let best_block = BestBlock :: new ( fork_point. block_hash , fork_point. height ) ;
399+ self . chain_listener . blocks_disconnected ( best_block) ;
407400 }
408401
409402 /// Notifies the chain listeners of connected blocks.
0 commit comments