1
1
use log:: debug;
2
+ use mithril_aggregator:: fake_data;
3
+ use std:: str;
2
4
3
5
use crate :: aggregator:: AggregatorHandler ;
4
6
use crate :: entities:: * ;
5
7
use 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 > ;
6
15
7
16
/// Mithril client wrapper
8
- pub struct Client < R >
9
- where
10
- R : AggregatorHandler ,
11
- {
17
+ pub struct Client {
12
18
pub network : String ,
13
- pub aggregator_handler : Option < Box < R > > ,
19
+ pub aggregator_handler : Option < AggregatorHandlerWrapper > ,
20
+ pub verifier : Option < VerifierWrapper > ,
14
21
}
15
22
16
- impl < R > Client < R >
17
- where
18
- R : AggregatorHandler ,
19
- {
23
+ impl Client {
20
24
/// Client factory
21
25
pub fn new ( network : String ) -> Self {
22
26
Self {
23
27
network,
24
28
aggregator_handler : None ,
29
+ verifier : None ,
25
30
}
26
31
}
27
32
28
33
/// 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) ;
31
45
self
32
46
}
33
- }
34
47
35
- impl < R > Client < R >
36
- where
37
- R : AggregatorHandler ,
38
- {
39
48
/// List snapshots
40
49
pub async fn list_snapshots ( & self ) -> Result < Vec < SnapshotListItem > , String > {
41
50
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 > > ( ) )
52
61
}
53
62
54
63
/// Show a snapshot
55
64
pub async fn show_snapshot ( & self , digest : & str ) -> Result < Vec < SnapshotFieldItem > , String > {
56
65
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
+ ) )
65
74
}
66
75
67
76
/// Download a snapshot by digest
@@ -71,36 +80,46 @@ where
71
80
location_index : isize ,
72
81
) -> Result < ( String , String ) , String > {
73
82
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) ,
91
96
}
92
97
}
93
98
94
99
/// Restore a snapshot by hash
95
100
pub async fn restore_snapshot ( & self , digest : & str ) -> Result < String , String > {
96
101
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
104
123
}
105
124
}
106
125
@@ -143,6 +162,7 @@ mod tests {
143
162
use super :: * ;
144
163
145
164
use crate :: aggregator:: MockAggregatorHandler ;
165
+ use crate :: verifier:: MockVerifier ;
146
166
use mithril_aggregator:: fake_data;
147
167
148
168
#[ tokio:: test]
@@ -155,7 +175,7 @@ mod tests {
155
175
. return_const ( Ok ( fake_snapshots. clone ( ) ) )
156
176
. once ( ) ;
157
177
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) ) ;
159
179
let snapshot_list_items = client. list_snapshots ( ) . await ;
160
180
snapshot_list_items. as_ref ( ) . expect ( "unexpected error" ) ;
161
181
let snapshot_list_items_expected = fake_snapshots
@@ -173,7 +193,7 @@ mod tests {
173
193
. return_const ( Err ( "error occurred" . to_string ( ) ) )
174
194
. once ( ) ;
175
195
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) ) ;
177
197
let snapshot_list_items = client. list_snapshots ( ) . await ;
178
198
assert ! (
179
199
snapshot_list_items. is_err( ) ,
@@ -191,7 +211,7 @@ mod tests {
191
211
. return_const ( Ok ( fake_snapshot. clone ( ) ) )
192
212
. once ( ) ;
193
213
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) ) ;
195
215
let snapshot_item = client. show_snapshot ( digest) . await ;
196
216
snapshot_item. as_ref ( ) . expect ( "unexpected error" ) ;
197
217
let snapshot_item_expected = convert_to_field_items ( & fake_snapshot, "testnet" . to_string ( ) ) ;
@@ -207,8 +227,102 @@ mod tests {
207
227
. return_const ( Err ( "error occurred" . to_string ( ) ) )
208
228
. once ( ) ;
209
229
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) ) ;
211
231
let snapshot_item = client. show_snapshot ( digest) . await ;
212
232
assert ! ( snapshot_item. is_err( ) , "an error should have occurred" ) ;
213
233
}
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
+ }
214
328
}
0 commit comments