@@ -100,8 +100,8 @@ impl Default for DataStoreConfig {
100100 max_proposals_pending : 80_000 ,
101101 max_messages_pending : 40_000 ,
102102 available_proposals_cache_capacity : NonZeroUsize :: new ( 8000 ) . unwrap ( ) ,
103- periodic_maintenance_interval : Duration :: from_secs ( 25 ) ,
104- request_block_after : Duration :: from_secs ( 20 ) ,
103+ periodic_maintenance_interval : Duration :: from_secs ( 10 ) ,
104+ request_block_after : Duration :: from_secs ( 5 ) ,
105105 }
106106 }
107107}
@@ -151,7 +151,8 @@ impl Display for Error {
151151// In case any of them is not, the message `m` receives a fresh `MessageId` and the message and all the pending
152152// proposals are added to our "pending list". The dependencies between the message and the proposals it waits for
153153// are also tracked. At the very first moment when the last pending proposal of the message becomes available, the
154- // message is removed from the pending list and is output on "the other side" of DataStore.
154+ // message is removed from the pending list and is output on "the other side" of DataStore. We
155+ // also immediately request any missing blocks.
155156// 3) It is crucial for DataStore to use a bounded amount of memory, which is perhaps the hardest challenge when implementing it.
156157// There are constants in the `DataStoreConfig` that determine maximum possible amounts of messages and proposals that
157158// can be pending at the same time. When any of the limits is exceeded, we keep dropping messages (starting from
@@ -304,6 +305,31 @@ where
304305 self . on_block_finalized ( highest_finalized) ;
305306 }
306307
308+ fn acquire_highest_block (
309+ & mut self ,
310+ proposal : & AlephProposal < H :: Unverified > ,
311+ time_waiting : & Duration ,
312+ ) -> bool {
313+ let header = proposal. top_block_header ( ) ;
314+ let block_id = proposal. top_block ( ) ;
315+ if self . chain_info_provider . is_block_imported ( & block_id) {
316+ return false ;
317+ }
318+ debug ! (
319+ target: LOG_TARGET ,
320+ "Requesting a block {:?} after it has been missing for {:?} secs." ,
321+ block_id,
322+ time_waiting. as_secs( )
323+ ) ;
324+ if let Err ( e) = self . block_requester . request_block ( header) {
325+ warn ! (
326+ target: LOG_TARGET ,
327+ "Error requesting block {:?}, {}." , block_id, e
328+ ) ;
329+ }
330+ true
331+ }
332+
307333 fn run_maintenance ( & mut self ) {
308334 self . update_highest_finalized ( ) ;
309335
@@ -343,21 +369,9 @@ where
343369 _ => continue ,
344370 } ;
345371
346- let header = proposal. top_block_header ( ) ;
347- let block_id = proposal. top_block ( ) ;
348- if !self . chain_info_provider . is_block_imported ( & block_id) {
349- debug ! (
350- target: LOG_TARGET ,
351- "Requesting a block {:?} after it has been missing for {:?} secs." ,
352- block_id,
353- time_waiting. as_secs( )
354- ) ;
355- if let Err ( e) = self . block_requester . request_block ( header) {
356- warn ! (
357- target: LOG_TARGET ,
358- "Error requesting block {:?}, {}." , block_id, e
359- ) ;
360- }
372+ if self . acquire_highest_block ( & proposal, & time_waiting) {
373+ // We need the highest block in this proposal and have just now sent a request for
374+ // it.
361375 continue ;
362376 }
363377 // The top block (thus the whole branch, in the honest case) has been imported. What's holding us
@@ -565,6 +579,8 @@ where
565579 let status = self . check_proposal_availability ( proposal, None ) ;
566580 match & status {
567581 Pending ( PendingTopBlock ) => {
582+ // Immediately request the missing block.
583+ self . acquire_highest_block ( proposal, & Duration :: ZERO ) ;
568584 self . pending_proposals
569585 . insert ( proposal. clone ( ) , PendingProposalInfo :: new ( status) ) ;
570586 self . register_block_import_trigger ( proposal, & proposal. top_block ( ) ) ;
0 commit comments