11use log:: debug;
2+ use mithril_aggregator:: fake_data;
3+ use std:: str;
24
35use crate :: aggregator:: AggregatorHandler ;
46use crate :: entities:: * ;
57use crate :: errors;
8+ use crate :: verifier:: Verifier ;
9+
10+ /// AggregatorHandlerWrapper wraps an AggregatorHandler
11+ pub type AggregatorHandlerWrapper = Box < dyn AggregatorHandler > ;
12+
13+ /// VerifierWrapper wraps a Verifier
14+ pub type VerifierWrapper = Box < dyn Verifier > ;
615
716/// Mithril client wrapper
8- pub struct Client < R >
9- where
10- R : AggregatorHandler ,
11- {
17+ pub struct Client {
1218 pub network : String ,
13- pub aggregator_handler : Option < Box < R > > ,
19+ pub aggregator_handler : Option < AggregatorHandlerWrapper > ,
20+ pub verifier : Option < VerifierWrapper > ,
1421}
1522
16- impl < R > Client < R >
17- where
18- R : AggregatorHandler ,
19- {
23+ impl Client {
2024 /// Client factory
2125 pub fn new ( network : String ) -> Self {
2226 Self {
2327 network,
2428 aggregator_handler : None ,
29+ verifier : None ,
2530 }
2631 }
2732
2833 /// With AggregatorHandler
29- pub fn with_aggregator_handler ( & mut self , aggregator_handler : R ) -> & mut Self {
30- self . aggregator_handler = Some ( Box :: new ( aggregator_handler) ) ;
34+ pub fn with_aggregator_handler (
35+ & mut self ,
36+ aggregator_handler : AggregatorHandlerWrapper ,
37+ ) -> & mut Self {
38+ self . aggregator_handler = Some ( aggregator_handler) ;
39+ self
40+ }
41+
42+ /// With Verifier
43+ pub fn with_verifier ( & mut self , verifier : VerifierWrapper ) -> & mut Self {
44+ self . verifier = Some ( verifier) ;
3145 self
3246 }
33- }
3447
35- impl < R > Client < R >
36- where
37- R : AggregatorHandler ,
38- {
3948 /// List snapshots
4049 pub async fn list_snapshots ( & self ) -> Result < Vec < SnapshotListItem > , String > {
4150 debug ! ( "List snapshots" ) ;
42- match & self . aggregator_handler {
43- Some ( aggregator_handler ) => match aggregator_handler . list_snapshots ( ) . await {
44- Ok ( snapshots ) => Ok ( snapshots
45- . iter ( )
46- . map ( |snapshot| convert_to_list_item ( snapshot , self . network . clone ( ) ) )
47- . collect :: < Vec < SnapshotListItem > > ( ) ) ,
48- Err ( err ) => Err ( err ) ,
49- } ,
50- None => Err ( errors :: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ,
51- }
51+ let aggregator_handler = & self
52+ . aggregator_handler
53+ . as_ref ( )
54+ . ok_or_else ( || errors :: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ? ;
55+ Ok ( aggregator_handler
56+ . list_snapshots ( )
57+ . await ?
58+ . iter ( )
59+ . map ( |snapshot| convert_to_list_item ( snapshot , self . network . clone ( ) ) )
60+ . collect :: < Vec < SnapshotListItem > > ( ) )
5261 }
5362
5463 /// Show a snapshot
5564 pub async fn show_snapshot ( & self , digest : & str ) -> Result < Vec < SnapshotFieldItem > , String > {
5665 debug ! ( "Show snapshot {}" , digest) ;
57- match & self . aggregator_handler {
58- Some ( aggregator_handler ) => match aggregator_handler . get_snapshot_details ( digest ) . await
59- {
60- Ok ( snapshot ) => Ok ( convert_to_field_items ( & snapshot , self . network . clone ( ) ) ) ,
61- Err ( err ) => Err ( err ) ,
62- } ,
63- None => Err ( errors :: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ,
64- }
66+ let aggregator_handler = & self
67+ . aggregator_handler
68+ . as_ref ( )
69+ . ok_or_else ( || errors :: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ? ;
70+ Ok ( convert_to_field_items (
71+ & aggregator_handler . get_snapshot_details ( digest ) . await ? ,
72+ self . network . clone ( ) ,
73+ ) )
6574 }
6675
6776 /// Download a snapshot by digest
@@ -71,36 +80,46 @@ where
7180 location_index : isize ,
7281 ) -> Result < ( String , String ) , String > {
7382 debug ! ( "Download snapshot {}" , digest) ;
74- match & self . aggregator_handler {
75- Some ( aggregator_handler) => match aggregator_handler. get_snapshot_details ( digest) . await
76- {
77- Ok ( snapshot) => {
78- let from = snapshot
79- . locations
80- . get ( ( location_index - 1 ) as usize )
81- . unwrap ( )
82- . to_owned ( ) ;
83- match aggregator_handler. download_snapshot ( digest, & from) . await {
84- Ok ( to) => Ok ( ( from, to) ) ,
85- Err ( err) => Err ( err) ,
86- }
87- }
88- Err ( err) => Err ( err) ,
89- } ,
90- None => Err ( errors:: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ,
83+ let aggregator_handler = & self
84+ . aggregator_handler
85+ . as_ref ( )
86+ . ok_or_else ( || errors:: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ?;
87+ let snapshot = aggregator_handler. get_snapshot_details ( digest) . await ?;
88+ let from = snapshot
89+ . locations
90+ . get ( ( location_index - 1 ) as usize )
91+ . unwrap ( )
92+ . to_owned ( ) ;
93+ match aggregator_handler. download_snapshot ( digest, & from) . await {
94+ Ok ( to) => Ok ( ( from, to) ) ,
95+ Err ( err) => Err ( err) ,
9196 }
9297 }
9398
9499 /// Restore a snapshot by hash
95100 pub async fn restore_snapshot ( & self , digest : & str ) -> Result < String , String > {
96101 debug ! ( "Restore snapshot {}" , digest) ;
97- match & self . aggregator_handler {
98- Some ( aggregator_handler) => match aggregator_handler. unpack_snapshot ( digest) . await {
99- Ok ( to) => Ok ( to) ,
100- Err ( err) => Err ( err) ,
101- } ,
102- None => Err ( errors:: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ,
103- }
102+ let aggregator_handler = & self
103+ . aggregator_handler
104+ . as_ref ( )
105+ . ok_or_else ( || errors:: MISSING_AGGREGATOR_HANDLER . to_string ( ) ) ?;
106+ let verifier = & self
107+ . verifier
108+ . as_ref ( )
109+ . ok_or_else ( || errors:: MISSING_VERIFIER . to_string ( ) ) ?;
110+ let fake_digest = fake_data:: digest ( ) ;
111+ debug ! ( "Fake digest {:?}" , fake_digest) ;
112+ let certificate_hash = str:: from_utf8 ( & fake_digest) . unwrap ( ) ;
113+ let certificate_details = aggregator_handler
114+ . get_certificate_details ( certificate_hash)
115+ . await ?;
116+ verifier. verify_multi_signature (
117+ & digest. as_bytes ( ) . to_vec ( ) ,
118+ certificate_details. multisignature . as_ref ( ) ,
119+ & certificate_details. participants ,
120+ & certificate_details. protocol_parameters ,
121+ ) ?;
122+ aggregator_handler. unpack_snapshot ( digest) . await
104123 }
105124}
106125
@@ -143,6 +162,7 @@ mod tests {
143162 use super :: * ;
144163
145164 use crate :: aggregator:: MockAggregatorHandler ;
165+ use crate :: verifier:: MockVerifier ;
146166 use mithril_aggregator:: fake_data;
147167
148168 #[ tokio:: test]
@@ -155,7 +175,7 @@ mod tests {
155175 . return_const ( Ok ( fake_snapshots. clone ( ) ) )
156176 . once ( ) ;
157177 let mut client = Client :: new ( network. clone ( ) ) ;
158- client. with_aggregator_handler ( mock_aggregator_handler) ;
178+ client. with_aggregator_handler ( Box :: new ( mock_aggregator_handler) ) ;
159179 let snapshot_list_items = client. list_snapshots ( ) . await ;
160180 snapshot_list_items. as_ref ( ) . expect ( "unexpected error" ) ;
161181 let snapshot_list_items_expected = fake_snapshots
@@ -173,7 +193,7 @@ mod tests {
173193 . return_const ( Err ( "error occurred" . to_string ( ) ) )
174194 . once ( ) ;
175195 let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
176- client. with_aggregator_handler ( mock_aggregator_handler) ;
196+ client. with_aggregator_handler ( Box :: new ( mock_aggregator_handler) ) ;
177197 let snapshot_list_items = client. list_snapshots ( ) . await ;
178198 assert ! (
179199 snapshot_list_items. is_err( ) ,
@@ -191,7 +211,7 @@ mod tests {
191211 . return_const ( Ok ( fake_snapshot. clone ( ) ) )
192212 . once ( ) ;
193213 let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
194- client. with_aggregator_handler ( mock_aggregator_handler) ;
214+ client. with_aggregator_handler ( Box :: new ( mock_aggregator_handler) ) ;
195215 let snapshot_item = client. show_snapshot ( digest) . await ;
196216 snapshot_item. as_ref ( ) . expect ( "unexpected error" ) ;
197217 let snapshot_item_expected = convert_to_field_items ( & fake_snapshot, "testnet" . to_string ( ) ) ;
@@ -207,8 +227,102 @@ mod tests {
207227 . return_const ( Err ( "error occurred" . to_string ( ) ) )
208228 . once ( ) ;
209229 let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
210- client. with_aggregator_handler ( mock_aggregator_handler) ;
230+ client. with_aggregator_handler ( Box :: new ( mock_aggregator_handler) ) ;
211231 let snapshot_item = client. show_snapshot ( digest) . await ;
212232 assert ! ( snapshot_item. is_err( ) , "an error should have occurred" ) ;
213233 }
234+
235+ #[ tokio:: test]
236+ async fn test_restore_snapshot_ok ( ) {
237+ let certificate_hash = "certhash123" ;
238+ let fake_certificate = fake_data:: certificate ( certificate_hash. to_string ( ) ) ;
239+ let mut mock_aggregator_handler = MockAggregatorHandler :: new ( ) ;
240+ let mut mock_verifier = MockVerifier :: new ( ) ;
241+ mock_aggregator_handler
242+ . expect_get_certificate_details ( )
243+ . return_const ( Ok ( fake_certificate. clone ( ) ) )
244+ . once ( ) ;
245+ mock_aggregator_handler
246+ . expect_unpack_snapshot ( )
247+ . return_const ( Ok ( "" . to_string ( ) ) )
248+ . once ( ) ;
249+ mock_verifier
250+ . expect_verify_multi_signature ( )
251+ . return_const ( Ok ( ( ) ) )
252+ . once ( ) ;
253+ let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
254+ client
255+ . with_aggregator_handler ( Box :: new ( mock_aggregator_handler) )
256+ . with_verifier ( Box :: new ( mock_verifier) ) ;
257+ let restore = client. restore_snapshot ( certificate_hash) . await ;
258+ restore. expect ( "unexpected error" ) ;
259+ }
260+
261+ #[ tokio:: test]
262+ async fn test_restore_snapshot_ko_get_certificate_details ( ) {
263+ let certificate_hash = "certhash123" ;
264+ let mut mock_aggregator_handler = MockAggregatorHandler :: new ( ) ;
265+ let mut mock_verifier = MockVerifier :: new ( ) ;
266+ mock_aggregator_handler
267+ . expect_get_certificate_details ( )
268+ . return_const ( Err ( "an error" . to_string ( ) ) )
269+ . once ( ) ;
270+ mock_aggregator_handler. expect_unpack_snapshot ( ) . never ( ) ;
271+ mock_verifier. expect_verify_multi_signature ( ) . never ( ) ;
272+ let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
273+ client
274+ . with_aggregator_handler ( Box :: new ( mock_aggregator_handler) )
275+ . with_verifier ( Box :: new ( mock_verifier) ) ;
276+ let restore = client. restore_snapshot ( certificate_hash) . await ;
277+ assert ! ( restore. is_err( ) , "an error should have occurred" ) ;
278+ }
279+
280+ #[ tokio:: test]
281+ async fn test_restore_snapshot_ko_verify_multi_signature ( ) {
282+ let certificate_hash = "certhash123" ;
283+ let fake_certificate = fake_data:: certificate ( certificate_hash. to_string ( ) ) ;
284+ let mut mock_aggregator_handler = MockAggregatorHandler :: new ( ) ;
285+ let mut mock_verifier = MockVerifier :: new ( ) ;
286+ mock_aggregator_handler
287+ . expect_get_certificate_details ( )
288+ . return_const ( Ok ( fake_certificate. clone ( ) ) )
289+ . once ( ) ;
290+ mock_aggregator_handler. expect_unpack_snapshot ( ) . never ( ) ;
291+ mock_verifier
292+ . expect_verify_multi_signature ( )
293+ . return_const ( Err ( "an error" . to_string ( ) ) )
294+ . once ( ) ;
295+ let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
296+ client
297+ . with_aggregator_handler ( Box :: new ( mock_aggregator_handler) )
298+ . with_verifier ( Box :: new ( mock_verifier) ) ;
299+ let restore = client. restore_snapshot ( certificate_hash) . await ;
300+ assert ! ( restore. is_err( ) , "an error should have occurred" ) ;
301+ }
302+
303+ #[ tokio:: test]
304+ async fn test_restore_unpack_snapshot ( ) {
305+ let certificate_hash = "certhash123" ;
306+ let fake_certificate = fake_data:: certificate ( certificate_hash. to_string ( ) ) ;
307+ let mut mock_aggregator_handler = MockAggregatorHandler :: new ( ) ;
308+ let mut mock_verifier = MockVerifier :: new ( ) ;
309+ mock_aggregator_handler
310+ . expect_get_certificate_details ( )
311+ . return_const ( Ok ( fake_certificate. clone ( ) ) )
312+ . once ( ) ;
313+ mock_aggregator_handler
314+ . expect_unpack_snapshot ( )
315+ . return_const ( Err ( "an error" . to_string ( ) ) )
316+ . once ( ) ;
317+ mock_verifier
318+ . expect_verify_multi_signature ( )
319+ . return_const ( Ok ( ( ) ) )
320+ . once ( ) ;
321+ let mut client = Client :: new ( "testnet" . to_string ( ) ) ;
322+ client
323+ . with_aggregator_handler ( Box :: new ( mock_aggregator_handler) )
324+ . with_verifier ( Box :: new ( mock_verifier) ) ;
325+ let restore = client. restore_snapshot ( certificate_hash) . await ;
326+ assert ! ( restore. is_err( ) , "an error should have occurred" ) ;
327+ }
214328}
0 commit comments