@@ -153,13 +153,13 @@ mod tests {
153153 use multihash:: { Code , MultihashDigest } ;
154154
155155 /// Helper function to create a mock F3 certificate
156- fn create_test_certificate ( instance_id : u64 , epoch : i64 ) -> F3Certificate {
156+ fn create_test_certificate ( instance_id : u64 , finalized_epochs : Vec < i64 > ) -> F3Certificate {
157157 // Create a dummy CID for power table
158158 let power_table_cid = Cid :: new_v1 ( 0x55 , Code :: Blake2b256 . digest ( b"test_power_table" ) ) ;
159159
160160 F3Certificate {
161161 instance_id,
162- epoch ,
162+ finalized_epochs ,
163163 power_table_cid,
164164 signature : vec ! [ 1 , 2 , 3 , 4 ] , // Dummy signature
165165 certificate_data : vec ! [ 5 , 6 , 7 , 8 ] , // Dummy certificate data
@@ -224,7 +224,7 @@ mod tests {
224224 #[ test]
225225 fn test_constructor_with_genesis_data ( ) {
226226 let power_entries = create_test_power_entries ( ) ;
227- let genesis_cert = create_test_certificate ( 1 , 100 ) ;
227+ let genesis_cert = create_test_certificate ( 1 , vec ! [ 100 , 101 , 102 ] ) ;
228228
229229 let _rt = construct_and_verify ( 1 , power_entries, Some ( genesis_cert) ) ;
230230 // Constructor test passed if we get here without panicking
@@ -238,7 +238,7 @@ mod tests {
238238 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
239239 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
240240
241- let new_cert = create_test_certificate ( 1 , 200 ) ;
241+ let new_cert = create_test_certificate ( 1 , vec ! [ 200 , 201 , 202 ] ) ;
242242 let update_params = UpdateCertificateParams {
243243 certificate : new_cert. clone ( ) ,
244244 } ;
@@ -258,14 +258,14 @@ mod tests {
258258
259259 #[ test]
260260 fn test_update_certificate_non_advancing_height ( ) {
261- let genesis_cert = create_test_certificate ( 1 , 100 ) ;
261+ let genesis_cert = create_test_certificate ( 1 , vec ! [ 100 , 101 , 102 ] ) ;
262262 let rt = construct_and_verify ( 1 , vec ! [ ] , Some ( genesis_cert) ) ;
263263
264264 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
265265 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
266266
267- // Try to update with same or lower height
268- let same_height_cert = create_test_certificate ( 1 , 100 ) ; // Same height
267+ // Try to update with same or lower height (highest epoch is 102, try with 102 or lower)
268+ let same_height_cert = create_test_certificate ( 1 , vec ! [ 100 , 101 , 102 ] ) ; // Same highest
269269 let update_params = UpdateCertificateParams {
270270 certificate : same_height_cert,
271271 } ;
@@ -290,7 +290,7 @@ mod tests {
290290 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , unauthorized_caller) ;
291291 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
292292
293- let new_cert = create_test_certificate ( 1 , 200 ) ;
293+ let new_cert = create_test_certificate ( 1 , vec ! [ 200 , 201 , 202 ] ) ;
294294 let update_params = UpdateCertificateParams {
295295 certificate : new_cert,
296296 } ;
@@ -325,7 +325,7 @@ mod tests {
325325
326326 #[ test]
327327 fn test_get_certificate_with_data ( ) {
328- let genesis_cert = create_test_certificate ( 1 , 100 ) ;
328+ let genesis_cert = create_test_certificate ( 1 , vec ! [ 100 , 101 , 102 ] ) ;
329329 let rt = construct_and_verify ( 1 , vec ! [ ] , Some ( genesis_cert. clone ( ) ) ) ;
330330
331331 rt. expect_validate_caller_any ( ) ;
@@ -337,7 +337,7 @@ mod tests {
337337
338338 let response = result. deserialize :: < GetCertificateResponse > ( ) . unwrap ( ) ;
339339 assert_eq ! ( response. certificate, Some ( genesis_cert) ) ;
340- assert_eq ! ( response. latest_finalized_height, 100 ) ;
340+ assert_eq ! ( response. latest_finalized_height, 102 ) ; // Highest epoch
341341 }
342342
343343 #[ test]
@@ -366,7 +366,7 @@ mod tests {
366366 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
367367 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
368368
369- let cert1 = create_test_certificate ( 1 , 100 ) ;
369+ let cert1 = create_test_certificate ( 1 , vec ! [ 100 , 101 , 102 ] ) ;
370370 let update_params1 = UpdateCertificateParams {
371371 certificate : cert1. clone ( ) ,
372372 } ;
@@ -382,7 +382,7 @@ mod tests {
382382 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
383383 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
384384
385- let cert2 = create_test_certificate ( 1 , 200 ) ;
385+ let cert2 = create_test_certificate ( 1 , vec ! [ 200 , 201 , 202 ] ) ;
386386 let update_params2 = UpdateCertificateParams {
387387 certificate : cert2. clone ( ) ,
388388 } ;
@@ -398,14 +398,14 @@ mod tests {
398398
399399 #[ test]
400400 fn test_instance_id_progression_next_instance ( ) {
401- let genesis_cert = create_test_certificate ( 100 , 50 ) ;
401+ let genesis_cert = create_test_certificate ( 100 , vec ! [ 50 , 51 , 52 ] ) ;
402402 let rt = construct_and_verify ( 100 , vec ! [ ] , Some ( genesis_cert) ) ;
403403
404404 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
405405 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
406406
407407 // Update to next instance (100 -> 101) should succeed
408- let next_instance_cert = create_test_certificate ( 101 , 10 ) ; // Epoch can be any value
408+ let next_instance_cert = create_test_certificate ( 101 , vec ! [ 10 , 11 , 12 ] ) ; // Epoch can be any value
409409 let update_params = UpdateCertificateParams {
410410 certificate : next_instance_cert,
411411 } ;
@@ -420,14 +420,14 @@ mod tests {
420420
421421 #[ test]
422422 fn test_instance_id_skip_rejected ( ) {
423- let genesis_cert = create_test_certificate ( 100 , 50 ) ;
423+ let genesis_cert = create_test_certificate ( 100 , vec ! [ 50 , 51 , 52 ] ) ;
424424 let rt = construct_and_verify ( 100 , vec ! [ ] , Some ( genesis_cert) ) ;
425425
426426 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
427427 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
428428
429429 // Try to skip instance (100 -> 102) should fail
430- let skipped_cert = create_test_certificate ( 102 , 100 ) ;
430+ let skipped_cert = create_test_certificate ( 102 , vec ! [ 100 , 101 , 102 ] ) ;
431431 let update_params = UpdateCertificateParams {
432432 certificate : skipped_cert,
433433 } ;
@@ -444,14 +444,14 @@ mod tests {
444444
445445 #[ test]
446446 fn test_instance_id_backward_rejected ( ) {
447- let genesis_cert = create_test_certificate ( 100 , 50 ) ;
447+ let genesis_cert = create_test_certificate ( 100 , vec ! [ 50 , 51 , 52 ] ) ;
448448 let rt = construct_and_verify ( 100 , vec ! [ ] , Some ( genesis_cert) ) ;
449449
450450 rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
451451 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
452452
453453 // Try to go backward (100 -> 99) should fail
454- let backward_cert = create_test_certificate ( 99 , 100 ) ;
454+ let backward_cert = create_test_certificate ( 99 , vec ! [ 100 , 101 , 102 ] ) ;
455455 let update_params = UpdateCertificateParams {
456456 certificate : backward_cert,
457457 } ;
@@ -475,7 +475,7 @@ mod tests {
475475 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
476476
477477 // First certificate must match genesis_instance_id (50) or be next (51)
478- let matching_cert = create_test_certificate ( 50 , 100 ) ;
478+ let matching_cert = create_test_certificate ( 50 , vec ! [ 100 , 101 , 102 ] ) ;
479479 let update_params = UpdateCertificateParams {
480480 certificate : matching_cert,
481481 } ;
@@ -497,7 +497,7 @@ mod tests {
497497 rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
498498
499499 // First certificate can also be genesis + 1 (51)
500- let next_instance_cert = create_test_certificate ( 51 , 100 ) ;
500+ let next_instance_cert = create_test_certificate ( 51 , vec ! [ 100 , 101 , 102 ] ) ;
501501 let update_params = UpdateCertificateParams {
502502 certificate : next_instance_cert,
503503 } ;
@@ -509,4 +509,83 @@ mod tests {
509509
510510 assert ! ( result. is_ok( ) ) ;
511511 }
512+
513+ #[ test]
514+ fn test_certificate_with_multiple_epochs ( ) {
515+ let rt = construct_and_verify ( 1 , vec ! [ ] , None ) ;
516+
517+ rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
518+ rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
519+
520+ // Certificate covering epochs 100-110
521+ let multi_epoch_cert = create_test_certificate (
522+ 1 ,
523+ vec ! [ 100 , 101 , 102 , 103 , 104 , 105 , 106 , 107 , 108 , 109 , 110 ] ,
524+ ) ;
525+ let update_params = UpdateCertificateParams {
526+ certificate : multi_epoch_cert,
527+ } ;
528+
529+ let result = rt. call :: < F3CertManagerActor > (
530+ Method :: UpdateCertificate as u64 ,
531+ IpldBlock :: serialize_cbor ( & update_params) . unwrap ( ) ,
532+ ) ;
533+
534+ assert ! ( result. is_ok( ) ) ;
535+ rt. reset ( ) ;
536+
537+ // Query to verify latest_finalized_height is the highest epoch
538+ rt. expect_validate_caller_any ( ) ;
539+ let result = rt
540+ . call :: < F3CertManagerActor > ( Method :: GetCertificate as u64 , None )
541+ . unwrap ( )
542+ . unwrap ( ) ;
543+
544+ let response = result. deserialize :: < GetCertificateResponse > ( ) . unwrap ( ) ;
545+ assert_eq ! ( response. latest_finalized_height, 110 ) ; // Highest epoch
546+ }
547+
548+ #[ test]
549+ fn test_certificate_empty_epochs_rejected ( ) {
550+ let rt = construct_and_verify ( 1 , vec ! [ ] , None ) ;
551+
552+ rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
553+ rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
554+
555+ // Try to update with empty finalized_epochs
556+ let invalid_cert = create_test_certificate ( 1 , vec ! [ ] ) ;
557+ let update_params = UpdateCertificateParams {
558+ certificate : invalid_cert,
559+ } ;
560+
561+ let result = rt. call :: < F3CertManagerActor > (
562+ Method :: UpdateCertificate as u64 ,
563+ IpldBlock :: serialize_cbor ( & update_params) . unwrap ( ) ,
564+ ) ;
565+
566+ assert ! ( result. is_err( ) ) ;
567+ let err = result. unwrap_err ( ) ;
568+ assert_eq ! ( err. exit_code( ) , ExitCode :: USR_ILLEGAL_ARGUMENT ) ;
569+ }
570+
571+ #[ test]
572+ fn test_certificate_single_epoch ( ) {
573+ let rt = construct_and_verify ( 1 , vec ! [ ] , None ) ;
574+
575+ rt. set_caller ( * SYSTEM_ACTOR_CODE_ID , SYSTEM_ACTOR_ADDR ) ;
576+ rt. expect_validate_caller_addr ( vec ! [ SYSTEM_ACTOR_ADDR ] ) ;
577+
578+ // Certificate with only one epoch should work
579+ let single_epoch_cert = create_test_certificate ( 1 , vec ! [ 100 ] ) ;
580+ let update_params = UpdateCertificateParams {
581+ certificate : single_epoch_cert,
582+ } ;
583+
584+ let result = rt. call :: < F3CertManagerActor > (
585+ Method :: UpdateCertificate as u64 ,
586+ IpldBlock :: serialize_cbor ( & update_params) . unwrap ( ) ,
587+ ) ;
588+
589+ assert ! ( result. is_ok( ) ) ;
590+ }
512591}
0 commit comments