@@ -33,7 +33,7 @@ use reqwest::Response;
3333use reqwest_middleware:: { ClientBuilder , ClientWithMiddleware , RequestBuilder } ;
3434use reqwest_retry:: policies:: ExponentialBackoff ;
3535use reqwest_retry:: { Jitter , RetryTransientMiddleware } ;
36- use serde:: Serialize ;
36+ use serde:: { Deserialize , Serialize } ;
3737use shared_execution_objects:: central_objects:: CentralTransactionExecutionInfo ;
3838use starknet_api:: block:: { BlockHashAndNumber , BlockInfo , BlockNumber , StarknetVersion } ;
3939use starknet_api:: consensus_transaction:: InternalConsensusTransaction ;
@@ -100,6 +100,10 @@ pub trait CendeContext: Send + Sync {
100100 /// This function should return false if the previous height blob is not available.
101101 fn write_prev_height_blob ( & self , current_height : BlockNumber ) -> JoinHandle < bool > ;
102102
103+ /// Returns the latest received block number from the recorder, or `None` if no blocks or on
104+ /// error.
105+ async fn get_latest_received_block ( & self ) -> Option < BlockNumber > ;
106+
103107 // Prepares the previous height blob that will be written in the next height.
104108 async fn prepare_blob_for_next_height (
105109 & self ,
@@ -113,13 +117,23 @@ pub struct CendeAmbassador {
113117 // `None` indicates that there is no blob to write, and therefore, the node can't be the
114118 // proposer.
115119 prev_height_blob : Arc < Mutex < Option < AerospikeBlob > > > ,
116- url : Url ,
120+ write_blob_url : Url ,
121+ get_latest_received_block_url : Url ,
117122 client : ClientWithMiddleware ,
118123 class_manager : SharedClassManagerClient ,
119124}
120125
121126/// The path to write blob in the Recorder.
122127pub const RECORDER_WRITE_BLOB_PATH : & str = "/cende_recorder/write_blob" ;
128+ /// The path to get the latest received block from the Recorder (the next block that will be written
129+ /// to DB. returns null when no blocks exist).
130+ pub const RECORDER_GET_LATEST_RECEIVED_BLOCK_PATH : & str =
131+ "/cende_recorder/get_latest_received_block" ;
132+
133+ #[ derive( Debug , Deserialize ) ]
134+ struct GetLatestReceivedBlockResponse {
135+ block_number : Option < u64 > ,
136+ }
123137
124138impl CendeAmbassador {
125139 pub fn new ( cende_config : CendeConfig , class_manager : SharedClassManagerClient ) -> Self {
@@ -130,12 +144,14 @@ impl CendeAmbassador {
130144
131145 CendeAmbassador {
132146 prev_height_blob : Arc :: new ( Mutex :: new ( None ) ) ,
133- url : {
134- let mut recorder_url = cende_config. recorder_url ;
135- recorder_url =
136- recorder_url. join ( RECORDER_WRITE_BLOB_PATH ) . expect ( "Failed to construct URL" ) ;
137- recorder_url
138- } ,
147+ write_blob_url : cende_config
148+ . recorder_url
149+ . join ( RECORDER_WRITE_BLOB_PATH )
150+ . expect ( "Failed to construct write blob URL" ) ,
151+ get_latest_received_block_url : cende_config
152+ . recorder_url
153+ . join ( RECORDER_GET_LATEST_RECEIVED_BLOCK_PATH )
154+ . expect ( "Failed to construct get latest received block URL" ) ,
139155 client : ClientBuilder :: new ( reqwest:: Client :: new ( ) )
140156 . with ( RetryTransientMiddleware :: new_with_policy ( retry_policy) )
141157 . build ( ) ,
@@ -150,7 +166,7 @@ impl CendeContext for CendeAmbassador {
150166 info ! ( "Start writing to Aerospike previous height blob for height {current_height}." ) ;
151167
152168 let prev_height_blob = self . prev_height_blob . clone ( ) ;
153- let request_builder = self . client . post ( self . url . clone ( ) ) ;
169+ let request_builder = self . client . post ( self . write_blob_url . clone ( ) ) ;
154170
155171 task:: spawn (
156172 async move {
@@ -189,6 +205,33 @@ impl CendeContext for CendeAmbassador {
189205 )
190206 }
191207
208+ async fn get_latest_received_block ( & self ) -> Option < BlockNumber > {
209+ match self . client . get ( self . get_latest_received_block_url . clone ( ) ) . send ( ) . await {
210+ Ok ( response) if response. status ( ) . is_success ( ) => {
211+ match response. json :: < GetLatestReceivedBlockResponse > ( ) . await {
212+ Ok ( resp) => resp. block_number . map ( BlockNumber ) ,
213+ Err ( e) => {
214+ warn ! ( "Failed to parse recorder get_latest_received_block response: {e}" ) ;
215+ None
216+ }
217+ }
218+ }
219+ // Response is not successful: log and return None.
220+ Ok ( response) => {
221+ warn ! (
222+ "Recorder get_latest_received_block returned error status {}: {}" ,
223+ response. status( ) ,
224+ response. text( ) . await . unwrap_or_else( |_| "unparseable" . to_string( ) )
225+ ) ;
226+ None
227+ }
228+ Err ( e) => {
229+ warn ! ( "Failed to request recorder get_latest_received_block: {e}" ) ;
230+ None
231+ }
232+ }
233+ }
234+
192235 #[ sequencer_latency_histogram( CENDE_PREPARE_BLOB_FOR_NEXT_HEIGHT_LATENCY , false ) ]
193236 async fn prepare_blob_for_next_height (
194237 & self ,
0 commit comments