@@ -10,9 +10,9 @@ use thiserror::Error;
1010use mithril_common:: {
1111 MITHRIL_API_VERSION_HEADER , MITHRIL_SIGNER_VERSION_HEADER , StdError ,
1212 api_version:: APIVersionProvider ,
13- entities:: { ClientError , ServerError } ,
13+ entities:: { ClientError , Epoch , ServerError } ,
1414 logging:: LoggerExtensions ,
15- messages:: { AggregatorFeaturesMessage , EpochSettingsMessage } ,
15+ messages:: { AggregatorFeaturesMessage , EpochSettingsMessage , ProtocolConfigurationMessage } ,
1616} ;
1717
1818/// HTTP request timeout duration in milliseconds
@@ -125,6 +125,12 @@ pub trait AggregatorClient: Sync + Send {
125125 async fn retrieve_aggregator_features (
126126 & self ,
127127 ) -> Result < AggregatorFeaturesMessage , AggregatorClientError > ;
128+
129+ /// Retrieves protocol configuration for a given epoch from the aggregator
130+ async fn retrieve_protocol_configuration (
131+ & self ,
132+ epoch : Epoch ,
133+ ) -> Result < ProtocolConfigurationMessage , AggregatorClientError > ;
128134}
129135
130136/// AggregatorHTTPClient is a http client for an aggregator
@@ -271,6 +277,35 @@ impl AggregatorClient for AggregatorHTTPClient {
271277 Err ( err) => Err ( AggregatorClientError :: RemoteServerUnreachable ( anyhow ! ( err) ) ) ,
272278 }
273279 }
280+
281+ async fn retrieve_protocol_configuration (
282+ & self ,
283+ epoch : Epoch ,
284+ ) -> Result < ProtocolConfigurationMessage , AggregatorClientError > {
285+ debug ! ( self . logger, "Retrieve protocol configuration" ) ;
286+ let url = format ! (
287+ "{}/protocol-configuration/{}" ,
288+ self . aggregator_endpoint, epoch
289+ ) ;
290+ let response = self
291+ . prepare_request_builder ( self . prepare_http_client ( ) ?. get ( url. clone ( ) ) )
292+ . send ( )
293+ . await ;
294+
295+ match response {
296+ Ok ( response) => match response. status ( ) {
297+ StatusCode :: OK => {
298+ self . warn_if_api_version_mismatch ( & response) ;
299+ match response. json :: < ProtocolConfigurationMessage > ( ) . await {
300+ Ok ( message) => Ok ( message) ,
301+ Err ( err) => Err ( AggregatorClientError :: JsonParseFailed ( anyhow ! ( err) ) ) ,
302+ }
303+ }
304+ _ => Err ( AggregatorClientError :: from_response ( response) . await ) ,
305+ } ,
306+ Err ( err) => Err ( AggregatorClientError :: RemoteServerUnreachable ( anyhow ! ( err) ) ) ,
307+ }
308+ }
274309}
275310
276311#[ cfg( test) ]
@@ -363,6 +398,38 @@ mod tests {
363398 } ;
364399 }
365400
401+ mod protocol_configuration {
402+
403+ use super :: * ;
404+
405+ #[ tokio:: test]
406+ async fn test_protocol_configuration_ok_200 ( ) {
407+ let ( server, client) = setup_server_and_client ( ) ;
408+ let message_expected = ProtocolConfigurationMessage :: dummy ( ) ;
409+ let _server_mock = server. mock ( |when, then| {
410+ when. path ( "/protocol-configuration/42" ) ;
411+ then. status ( 200 ) . body ( json ! ( message_expected) . to_string ( ) ) ;
412+ } ) ;
413+
414+ let message = client. retrieve_protocol_configuration ( Epoch ( 42 ) ) . await . unwrap ( ) ;
415+
416+ assert_eq ! ( message_expected, message) ;
417+ }
418+
419+ #[ tokio:: test]
420+ async fn test_protocol_configuration_ko_500 ( ) {
421+ let ( server, client) = setup_server_and_client ( ) ;
422+ let _server_mock = server. mock ( |when, then| {
423+ when. path ( "/protocol-configuration/42" ) ;
424+ then. status ( 500 ) . body ( "an error occurred" ) ;
425+ } ) ;
426+
427+ let error = client. retrieve_protocol_configuration ( Epoch ( 42 ) ) . await . unwrap_err ( ) ;
428+
429+ assert_is_error ! ( error, AggregatorClientError :: RemoteServerTechnical ( _) ) ;
430+ }
431+ }
432+
366433 mod epoch_settings {
367434 use super :: * ;
368435
0 commit comments