@@ -10,7 +10,7 @@ use super::{
1010 SchemeProvider ,
1111} ;
1212use crate :: {
13- marshal:: ingress:: mailbox:: Identifier as BlockID ,
13+ marshal:: { ingress:: mailbox:: Identifier as BlockID , Update } ,
1414 simplex:: {
1515 signing_scheme:: Scheme ,
1616 types:: { Finalization , Notarization } ,
@@ -35,7 +35,6 @@ use governor::clock::Clock as GClock;
3535use prometheus_client:: metrics:: gauge:: Gauge ;
3636use rand:: { CryptoRng , Rng } ;
3737use std:: {
38- cmp:: max,
3938 collections:: { btree_map:: Entry , BTreeMap } ,
4039 time:: Instant ,
4140} ;
@@ -95,6 +94,8 @@ pub struct Actor<
9594 // ---------- State ----------
9695 // Last view processed
9796 last_processed_round : Round ,
97+ // Highest known finalized height
98+ tip : u64 ,
9899 // Outstanding subscriptions for blocks
99100 block_subscriptions : BTreeMap < B :: Commitment , BlockSubscription < B > > ,
100101
@@ -238,6 +239,7 @@ impl<
238239 block_codec_config : config. block_codec_config ,
239240 partition_prefix : config. partition_prefix ,
240241 last_processed_round : Round :: new ( 0 , 0 ) ,
242+ tip : 0 ,
241243 block_subscriptions : BTreeMap :: new ( ) ,
242244 cache,
243245 finalizations_by_height,
@@ -252,7 +254,7 @@ impl<
252254 /// Start the actor.
253255 pub fn start < R , K > (
254256 mut self ,
255- application : impl Reporter < Activity = B > ,
257+ application : impl Reporter < Activity = Update < B > > ,
256258 buffer : buffered:: Mailbox < K , B > ,
257259 resolver : ( mpsc:: Receiver < handler:: Message < B > > , R ) ,
258260 ) -> Handle < ( ) >
@@ -266,7 +268,7 @@ impl<
266268 /// Run the application actor.
267269 async fn run < R , K > (
268270 mut self ,
269- application : impl Reporter < Activity = B > ,
271+ mut application : impl Reporter < Activity = Update < B > > ,
270272 mut buffer : buffered:: Mailbox < K , B > ,
271273 ( mut resolver_rx, mut resolver) : ( mpsc:: Receiver < handler:: Message < B > > , R ) ,
272274 ) where
@@ -280,7 +282,7 @@ impl<
280282 let finalizer = Finalizer :: new (
281283 self . context . with_label ( "finalizer" ) ,
282284 format ! ( "{}-finalizer" , self . partition_prefix. clone( ) ) ,
283- application,
285+ application. clone ( ) ,
284286 orchestrator,
285287 notifier_rx,
286288 )
@@ -290,6 +292,14 @@ impl<
290292 // Create a local pool for waiter futures
291293 let mut waiters = AbortablePool :: < ( B :: Commitment , B ) > :: default ( ) ;
292294
295+ // Get tip and send to application
296+ let tip = self . get_latest ( ) . await ;
297+ if let Some ( ( height, commitment) ) = tip {
298+ application. report ( Update :: Tip ( height, commitment) ) . await ;
299+ self . tip = height;
300+ self . finalized_height . set ( height as i64 ) ;
301+ }
302+
293303 // Handle messages
294304 loop {
295305 // Remove any dropped subscribers. If all subscribers dropped, abort the waiter.
@@ -369,7 +379,7 @@ impl<
369379 if let Some ( block) = self . find_block( & mut buffer, commitment) . await {
370380 // If found, persist the block
371381 let height = block. height( ) ;
372- self . finalize( height, commitment, block, Some ( finalization) , & mut notifier_tx) . await ;
382+ self . finalize( height, commitment, block, Some ( finalization) , & mut notifier_tx, & mut application ) . await ;
373383 debug!( ?round, height, "finalized block stored" ) ;
374384 } else {
375385 // Otherwise, fetch the block from the network.
@@ -504,7 +514,7 @@ impl<
504514 let commitment = cursor. parent( ) ;
505515 if let Some ( block) = self . find_block( & mut buffer, commitment) . await {
506516 let finalization = self . cache. get_finalization_for( commitment) . await ;
507- self . finalize( block. height( ) , commitment, block. clone( ) , finalization, & mut notifier_tx) . await ;
517+ self . finalize( block. height( ) , commitment, block. clone( ) , finalization, & mut notifier_tx, & mut application ) . await ;
508518 debug!( height = block. height( ) , "repaired block" ) ;
509519 cursor = block;
510520 } else {
@@ -595,7 +605,7 @@ impl<
595605 // Persist the block, also persisting the finalization if we have it
596606 let height = block. height( ) ;
597607 let finalization = self . cache. get_finalization_for( commitment) . await ;
598- self . finalize( height, commitment, block, finalization, & mut notifier_tx) . await ;
608+ self . finalize( height, commitment, block, finalization, & mut notifier_tx, & mut application ) . await ;
599609 debug!( ?commitment, height, "received block" ) ;
600610 let _ = response. send( true ) ;
601611 } ,
@@ -629,7 +639,7 @@ impl<
629639 // Valid finalization received
630640 debug!( height, "received finalization" ) ;
631641 let _ = response. send( true ) ;
632- self . finalize( height, block. commitment( ) , block, Some ( finalization) , & mut notifier_tx) . await ;
642+ self . finalize( height, block. commitment( ) , block, Some ( finalization) , & mut notifier_tx, & mut application ) . await ;
633643 } ,
634644 Request :: Notarized { round } => {
635645 let Some ( scheme) = self . scheme_provider. scheme( round. epoch( ) ) else {
@@ -670,7 +680,7 @@ impl<
670680 // the request for the block.
671681 let height = block. height( ) ;
672682 if let Some ( finalization) = self . cache. get_finalization_for( commitment) . await {
673- self . finalize( height, commitment, block. clone( ) , Some ( finalization) , & mut notifier_tx) . await ;
683+ self . finalize( height, commitment, block. clone( ) , Some ( finalization) , & mut notifier_tx, & mut application ) . await ;
674684 }
675685
676686 // Cache the notarization and block
@@ -746,6 +756,7 @@ impl<
746756 block : B ,
747757 finalization : Option < Finalization < S , B :: Commitment > > ,
748758 notifier : & mut mpsc:: Sender < ( ) > ,
759+ application : & mut impl Reporter < Activity = Update < B > > ,
749760 ) {
750761 self . notify_subscribers ( commitment, & block) . await ;
751762
@@ -766,13 +777,15 @@ impl<
766777 panic ! ( "failed to finalize: {e}" ) ;
767778 }
768779
769- // Update metrics
770- let new_value: i64 = height as i64 ;
771- let old_value: i64 = self . finalized_height . get ( ) ;
772- self . finalized_height . set ( max ( new_value, old_value) ) ;
773-
774780 // Notify the finalizer
775781 let _ = notifier. try_send ( ( ) ) ;
782+
783+ // Update metrics and send tip update to application
784+ if height > self . tip {
785+ application. report ( Update :: Tip ( height, commitment) ) . await ;
786+ self . tip = height;
787+ self . finalized_height . set ( height as i64 ) ;
788+ }
776789 }
777790
778791 /// Get the latest finalized block information (height and commitment tuple).
0 commit comments