@@ -6,6 +6,7 @@ use serde::de::DeserializeOwned;
66use crate :: {
77 CardanoDatabaseSnapshot , CardanoDatabaseSnapshotListItem , MithrilResult ,
88 aggregator_client:: { AggregatorClient , AggregatorClientError , AggregatorRequest } ,
9+ common:: Epoch ,
910} ;
1011
1112pub struct InternalArtifactRetriever {
@@ -20,15 +21,42 @@ impl InternalArtifactRetriever {
2021
2122 /// Fetch a list of signed CardanoDatabase
2223 pub async fn list ( & self ) -> MithrilResult < Vec < CardanoDatabaseSnapshotListItem > > {
23- let response = self
24- . aggregator_client
25- . get_content ( AggregatorRequest :: ListCardanoDatabaseSnapshots )
24+ self . fetch_list_with_aggregator_request ( AggregatorRequest :: ListCardanoDatabaseSnapshots )
2625 . await
27- . with_context ( || "CardanoDatabase client can not get the artifact list" ) ?;
28- let items = serde_json:: from_str :: < Vec < CardanoDatabaseSnapshotListItem > > ( & response)
29- . with_context ( || "CardanoDatabase client can not deserialize artifact list" ) ?;
26+ }
27+
28+ /// Fetch a list of signed CardanoDatabase for a given epoch
29+ pub async fn list_by_epoch (
30+ & self ,
31+ epoch : Epoch ,
32+ ) -> MithrilResult < Vec < CardanoDatabaseSnapshotListItem > > {
33+ self . fetch_list_with_aggregator_request (
34+ AggregatorRequest :: ListCardanoDatabaseSnapshotByEpoch { epoch } ,
35+ )
36+ . await
37+ }
3038
31- Ok ( items)
39+ /// Fetch a list of signed CardanoDatabase for the latest epoch
40+ pub async fn list_for_latest_epoch (
41+ & self ,
42+ ) -> MithrilResult < Vec < CardanoDatabaseSnapshotListItem > > {
43+ self . fetch_list_with_aggregator_request (
44+ AggregatorRequest :: ListCardanoDatabaseSnapshotForLatestEpoch { offset : None } ,
45+ )
46+ . await
47+ }
48+
49+ /// Fetch a list of signed CardanoDatabase for the latest epoch minus the given offset
50+ pub async fn list_for_latest_epoch_with_offset (
51+ & self ,
52+ offset : u64 ,
53+ ) -> MithrilResult < Vec < CardanoDatabaseSnapshotListItem > > {
54+ self . fetch_list_with_aggregator_request (
55+ AggregatorRequest :: ListCardanoDatabaseSnapshotForLatestEpoch {
56+ offset : Some ( offset) ,
57+ } ,
58+ )
59+ . await
3260 }
3361
3462 /// Get the given Cardano database data by hash.
@@ -40,7 +68,7 @@ impl InternalArtifactRetriever {
4068 }
4169
4270 /// Fetch the given Cardano database data with an aggregator request.
43- /// If it cannot be found, a None is returned.
71+ /// If it cannot be found, None is returned.
4472 async fn fetch_with_aggregator_request < T : DeserializeOwned > (
4573 & self ,
4674 request : AggregatorRequest ,
@@ -56,6 +84,20 @@ impl InternalArtifactRetriever {
5684 Err ( e) => Err ( e. into ( ) ) ,
5785 }
5886 }
87+
88+ async fn fetch_list_with_aggregator_request (
89+ & self ,
90+ request : AggregatorRequest ,
91+ ) -> MithrilResult < Vec < CardanoDatabaseSnapshotListItem > > {
92+ let response = self
93+ . aggregator_client
94+ . get_content ( request)
95+ . await
96+ . with_context ( || "CardanoDatabase client can not get the artifact list" ) ?;
97+
98+ serde_json:: from_str ( & response)
99+ . with_context ( || "CardanoDatabase client can not deserialize artifact list" )
100+ }
59101}
60102
61103#[ cfg( test) ]
@@ -68,10 +110,19 @@ mod tests {
68110 use mithril_common:: entities:: { CardanoDbBeacon , Epoch } ;
69111 use mithril_common:: test:: double:: Dummy ;
70112
113+ use crate :: aggregator_client;
71114 use crate :: cardano_database_client:: CardanoDatabaseClientDependencyInjector ;
72115
73116 use super :: * ;
74117
118+ fn config_aggregator_client_to_always_returns_invalid_json (
119+ http_client : & mut aggregator_client:: MockAggregatorClient ,
120+ ) {
121+ http_client
122+ . expect_get_content ( )
123+ . returning ( move |_| Ok ( "invalid json structure" . to_string ( ) ) ) ;
124+ }
125+
75126 fn fake_messages ( ) -> Vec < CardanoDatabaseSnapshotListItem > {
76127 vec ! [
77128 CardanoDatabaseSnapshotListItem {
@@ -131,16 +182,126 @@ mod tests {
131182 #[ tokio:: test]
132183 async fn list_cardano_database_snapshots_returns_error_when_invalid_json_structure_in_response ( )
133184 {
185+ let client = CardanoDatabaseClientDependencyInjector :: new ( )
186+ . with_aggregator_client_mock_config (
187+ config_aggregator_client_to_always_returns_invalid_json,
188+ )
189+ . build_cardano_database_client ( ) ;
190+
191+ client
192+ . list ( )
193+ . await
194+ . expect_err ( "List Cardano databases should return an error" ) ;
195+ }
196+
197+ #[ tokio:: test]
198+ async fn list_cardano_database_snapshots_by_epoch_returns_messages ( ) {
199+ let message = fake_messages ( ) ;
134200 let client = CardanoDatabaseClientDependencyInjector :: new ( )
135201 . with_aggregator_client_mock_config ( |http_client| {
136202 http_client
137203 . expect_get_content ( )
138- . return_once ( move |_| Ok ( "invalid json structure" . to_string ( ) ) ) ;
204+ . with ( eq ( AggregatorRequest :: ListCardanoDatabaseSnapshotByEpoch {
205+ epoch : Epoch ( 4 ) ,
206+ } ) )
207+ . return_once ( move |_| Ok ( serde_json:: to_string ( & message) . unwrap ( ) ) ) ;
139208 } )
140209 . build_cardano_database_client ( ) ;
141210
211+ let messages = client. list_by_epoch ( Epoch ( 4 ) ) . await . unwrap ( ) ;
212+
213+ assert_eq ! ( 2 , messages. len( ) ) ;
214+ assert_eq ! ( "hash-123" . to_string( ) , messages[ 0 ] . hash) ;
215+ assert_eq ! ( "hash-456" . to_string( ) , messages[ 1 ] . hash) ;
216+ }
217+
218+ #[ tokio:: test]
219+ async fn list_cardano_database_snapshots_returns_by_epoch_error_when_invalid_json_structure_in_response ( )
220+ {
221+ let client = CardanoDatabaseClientDependencyInjector :: new ( )
222+ . with_aggregator_client_mock_config (
223+ config_aggregator_client_to_always_returns_invalid_json,
224+ )
225+ . build_cardano_database_client ( ) ;
226+
142227 client
143- . list ( )
228+ . list_by_epoch ( Epoch ( 4 ) )
229+ . await
230+ . expect_err ( "List Cardano databases should return an error" ) ;
231+ }
232+
233+ #[ tokio:: test]
234+ async fn list_cardano_database_snapshots_for_latest_epoch_returns_messages ( ) {
235+ let message = fake_messages ( ) ;
236+ let client = CardanoDatabaseClientDependencyInjector :: new ( )
237+ . with_aggregator_client_mock_config ( |http_client| {
238+ http_client
239+ . expect_get_content ( )
240+ . with ( eq (
241+ AggregatorRequest :: ListCardanoDatabaseSnapshotForLatestEpoch {
242+ offset : None ,
243+ } ,
244+ ) )
245+ . return_once ( move |_| Ok ( serde_json:: to_string ( & message) . unwrap ( ) ) ) ;
246+ } )
247+ . build_cardano_database_client ( ) ;
248+
249+ let messages = client. list_for_latest_epoch ( ) . await . unwrap ( ) ;
250+
251+ assert_eq ! ( 2 , messages. len( ) ) ;
252+ assert_eq ! ( "hash-123" . to_string( ) , messages[ 0 ] . hash) ;
253+ assert_eq ! ( "hash-456" . to_string( ) , messages[ 1 ] . hash) ;
254+ }
255+
256+ #[ tokio:: test]
257+ async fn list_cardano_database_snapshots_returns_for_latest_epoch_error_when_invalid_json_structure_in_response ( )
258+ {
259+ let client = CardanoDatabaseClientDependencyInjector :: new ( )
260+ . with_aggregator_client_mock_config (
261+ config_aggregator_client_to_always_returns_invalid_json,
262+ )
263+ . build_cardano_database_client ( ) ;
264+
265+ client
266+ . list_for_latest_epoch ( )
267+ . await
268+ . expect_err ( "List Cardano databases should return an error" ) ;
269+ }
270+
271+ #[ tokio:: test]
272+ async fn list_cardano_database_snapshots_for_latest_epoch_with_offset_returns_messages ( ) {
273+ let message = fake_messages ( ) ;
274+ let client = CardanoDatabaseClientDependencyInjector :: new ( )
275+ . with_aggregator_client_mock_config ( |http_client| {
276+ http_client
277+ . expect_get_content ( )
278+ . with ( eq (
279+ AggregatorRequest :: ListCardanoDatabaseSnapshotForLatestEpoch {
280+ offset : Some ( 42 ) ,
281+ } ,
282+ ) )
283+ . return_once ( move |_| Ok ( serde_json:: to_string ( & message) . unwrap ( ) ) ) ;
284+ } )
285+ . build_cardano_database_client ( ) ;
286+
287+ let messages = client. list_for_latest_epoch_with_offset ( 42 ) . await . unwrap ( ) ;
288+
289+ assert_eq ! ( 2 , messages. len( ) ) ;
290+ assert_eq ! ( "hash-123" . to_string( ) , messages[ 0 ] . hash) ;
291+ assert_eq ! ( "hash-456" . to_string( ) , messages[ 1 ] . hash) ;
292+ }
293+
294+ #[ tokio:: test]
295+ async fn list_cardano_database_snapshots_returns_for_latest_epoch_with_offset_error_when_invalid_json_structure_in_response ( )
296+ {
297+ let client = CardanoDatabaseClientDependencyInjector :: new ( )
298+ . with_aggregator_client_mock_config (
299+ config_aggregator_client_to_always_returns_invalid_json,
300+ )
301+ . build_cardano_database_client ( ) ;
302+
303+ client
304+ . list_for_latest_epoch_with_offset ( 42 )
144305 . await
145306 . expect_err ( "List Cardano databases should return an error" ) ;
146307 }
@@ -180,11 +341,9 @@ mod tests {
180341 async fn get_cardano_database_snapshot_returns_error_when_invalid_json_structure_in_response ( )
181342 {
182343 let client = CardanoDatabaseClientDependencyInjector :: new ( )
183- . with_aggregator_client_mock_config ( |http_client| {
184- http_client
185- . expect_get_content ( )
186- . return_once ( move |_| Ok ( "invalid json structure" . to_string ( ) ) ) ;
187- } )
344+ . with_aggregator_client_mock_config (
345+ config_aggregator_client_to_always_returns_invalid_json,
346+ )
188347 . build_cardano_database_client ( ) ;
189348
190349 client
0 commit comments