@@ -3,6 +3,8 @@ use crate::misc::BlockNumber;
33use parlia_ibc_proto:: ibc:: lightclients:: parlia:: v1:: fork_spec:: HeightOrTimestamp as RawHeightOrTimestamp ;
44use parlia_ibc_proto:: ibc:: lightclients:: parlia:: v1:: ForkSpec as RawForkSpec ;
55
6+ const DEFAULT_EPOCH_LENGTH : u64 = 200 ;
7+
68#[ derive( Clone , Debug , PartialEq , serde:: Serialize , serde:: Deserialize ) ]
79pub enum HeightOrTimestamp {
810 Height ( u64 ) ,
@@ -67,34 +69,44 @@ impl ForkSpec {
6769 /// current_first = 2000
6870 pub fn boundary_epochs ( & self , prev_fork_spec : & ForkSpec ) -> Result < BoundaryEpochs , Error > {
6971 if let HeightOrTimestamp :: Height ( height) = self . height_or_timestamp {
70- let prev_last = height - ( height % prev_fork_spec. epoch_length ) ;
71- let current_first = ( height..) . find ( |& h| h % self . epoch_length == 0 ) . unwrap ( ) ;
72+ if self . epoch_length == 0 || prev_fork_spec. epoch_length == 0 {
73+ return Err ( Error :: UnexpectedEpochLength (
74+ self . epoch_length ,
75+ prev_fork_spec. epoch_length ,
76+ ) ) ;
77+ }
78+ let previous_last = height - ( height % prev_fork_spec. epoch_length ) ;
79+
80+ let current_first = if height % self . epoch_length == 0 {
81+ height
82+ } else {
83+ height + ( self . epoch_length - height % self . epoch_length )
84+ } ;
7285 let mut intermediates = vec ! [ ] ;
7386
7487 // starts 0, 200, 400...epoch_length
75- if prev_last == 0 {
76- const DEFAULT_EPOCH_LENGTH : u64 = 200 ;
88+ if previous_last == 0 {
7789 let additive: u64 = if prev_fork_spec. epoch_length > DEFAULT_EPOCH_LENGTH {
7890 DEFAULT_EPOCH_LENGTH
7991 } else {
8092 prev_fork_spec. epoch_length
8193 } ;
82- let mut mid = prev_last + additive;
94+ let mut mid = previous_last + additive;
8395 while mid < prev_fork_spec. epoch_length {
8496 intermediates. push ( mid) ;
8597 mid += additive;
8698 }
8799 }
88- let mut mid = prev_last + prev_fork_spec. epoch_length ;
100+ let mut mid = previous_last + prev_fork_spec. epoch_length ;
89101 while mid < current_first {
90102 intermediates. push ( mid) ;
91103 mid += prev_fork_spec. epoch_length ;
92104 }
93105 return Ok ( BoundaryEpochs {
94106 previous_fork_spec : prev_fork_spec. clone ( ) ,
95107 current_fork_spec : self . clone ( ) ,
108+ previous_last,
96109 current_first,
97- prev_last,
98110 intermediates,
99111 } ) ;
100112 }
@@ -106,7 +118,7 @@ impl ForkSpec {
106118pub struct BoundaryEpochs {
107119 previous_fork_spec : ForkSpec ,
108120 current_fork_spec : ForkSpec ,
109- prev_last : BlockNumber ,
121+ previous_last : BlockNumber ,
110122 current_first : BlockNumber ,
111123 intermediates : alloc:: vec:: Vec < BlockNumber > ,
112124}
@@ -147,14 +159,14 @@ impl BoundaryEpochs {
147159 return 0 ;
148160 }
149161 // Before HF
150- if current_epoch_block_number <= self . prev_last {
162+ if current_epoch_block_number <= self . previous_last {
151163 return current_epoch_block_number - self . previous_fork_spec . epoch_length ;
152164 }
153165
154166 for ( i, mid) in self . intermediates . iter ( ) . enumerate ( ) {
155167 if current_epoch_block_number == * mid {
156168 if i == 0 {
157- return self . prev_last ;
169+ return self . previous_last ;
158170 } else {
159171 return self . intermediates [ i - 1 ] ;
160172 }
@@ -163,7 +175,7 @@ impl BoundaryEpochs {
163175
164176 if current_epoch_block_number == self . current_first {
165177 if self . intermediates . is_empty ( ) {
166- return self . prev_last ;
178+ return self . previous_last ;
167179 }
168180 return * self . intermediates . last ( ) . unwrap ( ) ;
169181 }
@@ -600,36 +612,76 @@ mod test {
600612 }
601613 }
602614
615+ #[ test]
616+ fn test_error_boundary_epochs_current_epoch_length_zero ( ) {
617+ let current = ForkSpec {
618+ height_or_timestamp : HeightOrTimestamp :: Height ( 0 ) ,
619+ additional_header_item_count : 1 ,
620+ epoch_length : 0 ,
621+ max_turn_length : 64 ,
622+ } ;
623+ match current
624+ . boundary_epochs ( & fork_spec_after_pascal ( ) )
625+ . unwrap_err ( )
626+ {
627+ Error :: UnexpectedEpochLength ( e1, e2) => {
628+ assert_eq ! ( current. epoch_length, e1) ;
629+ assert_ne ! ( current. epoch_length, e2) ;
630+ }
631+ _ => unreachable ! ( "unexpected error" ) ,
632+ }
633+ }
634+
635+ #[ test]
636+ fn test_error_boundary_epochs_previous_epoch_length_zero ( ) {
637+ let previous = ForkSpec {
638+ height_or_timestamp : HeightOrTimestamp :: Height ( 0 ) ,
639+ additional_header_item_count : 1 ,
640+ epoch_length : 0 ,
641+ max_turn_length : 64 ,
642+ } ;
643+ match fork_spec_after_pascal ( )
644+ . boundary_epochs ( & previous)
645+ . unwrap_err ( )
646+ {
647+ Error :: UnexpectedEpochLength ( e1, e2) => {
648+ assert_ne ! ( previous. epoch_length, e1) ;
649+ assert_eq ! ( previous. epoch_length, e2) ;
650+ }
651+ _ => unreachable ! ( "unexpected error" ) ,
652+ }
653+ }
654+
603655 #[ test]
604656 fn test_success_boundary_epochs ( ) {
605657 let mut f1 = fork_spec_after_lorentz ( ) . clone ( ) ;
606658 f1. height_or_timestamp = HeightOrTimestamp :: Height ( 1501 ) ;
607659 let be = f1. boundary_epochs ( & fork_spec_after_pascal ( ) ) . unwrap ( ) ;
608- assert_eq ! ( be. prev_last , 1400 ) ;
660+ assert_eq ! ( be. previous_last , 1400 ) ;
609661 assert_eq ! ( be. intermediates, vec![ 1600 , 1800 ] ) ;
610662 assert_eq ! ( be. current_first, 2000 ) ;
611663
612664 f1. height_or_timestamp = HeightOrTimestamp :: Height ( 1600 ) ;
613665 let be = f1. boundary_epochs ( & fork_spec_after_pascal ( ) ) . unwrap ( ) ;
614- assert_eq ! ( be. prev_last , 1600 ) ;
666+ assert_eq ! ( be. previous_last , 1600 ) ;
615667 assert_eq ! ( be. intermediates, vec![ 1800 ] ) ;
616668 assert_eq ! ( be. current_first, 2000 ) ;
617669
618670 f1. height_or_timestamp = HeightOrTimestamp :: Height ( 1601 ) ;
619671 let be = f1. boundary_epochs ( & fork_spec_after_pascal ( ) ) . unwrap ( ) ;
620- assert_eq ! ( be. prev_last , 1600 ) ;
672+ assert_eq ! ( be. previous_last , 1600 ) ;
621673 assert_eq ! ( be. intermediates, vec![ 1800 ] ) ;
622674 assert_eq ! ( be. current_first, 2000 ) ;
623675
624676 f1. height_or_timestamp = HeightOrTimestamp :: Height ( 1800 ) ;
625677 let be = f1. boundary_epochs ( & fork_spec_after_pascal ( ) ) . unwrap ( ) ;
626- assert_eq ! ( be. prev_last , 1800 ) ;
678+ assert_eq ! ( be. previous_last , 1800 ) ;
627679 assert_eq ! ( be. intermediates, vec![ ] ) ;
628680 assert_eq ! ( be. current_first, 2000 ) ;
629681
630682 f1. height_or_timestamp = HeightOrTimestamp :: Height ( 2000 ) ;
631683 let be = f1. boundary_epochs ( & fork_spec_after_pascal ( ) ) . unwrap ( ) ;
632- assert_eq ! ( be. prev_last , 2000 ) ;
684+ assert_eq ! ( be. previous_last , 2000 ) ;
633685 assert_eq ! ( be. intermediates, vec![ ] ) ;
634686 assert_eq ! ( be. current_first, 2000 ) ;
635687 }
@@ -639,7 +691,7 @@ mod test {
639691 let be = fork_spec_after_lorentz ( )
640692 . boundary_epochs ( & fork_spec_after_pascal ( ) )
641693 . unwrap ( ) ;
642- assert_eq ! ( be. prev_last , 0 ) ;
694+ assert_eq ! ( be. previous_last , 0 ) ;
643695 assert_eq ! ( be. intermediates[ 0 ] , 200 ) ;
644696 assert_eq ! ( be. intermediates[ 1 ] , 400 ) ;
645697 assert_eq ! ( be. current_first, 500 ) ;
@@ -670,7 +722,7 @@ mod test {
670722 let be = fork_spec_after_maxwell ( )
671723 . boundary_epochs ( & fork_spec_after_lorentz ( ) )
672724 . unwrap ( ) ;
673- assert_eq ! ( be. prev_last , 0 ) ;
725+ assert_eq ! ( be. previous_last , 0 ) ;
674726 assert_eq ! ( be. intermediates[ 0 ] , 200 ) ;
675727 assert_eq ! ( be. intermediates[ 1 ] , 400 ) ;
676728 assert_eq ! ( be. intermediates[ 2 ] , 500 ) ;
0 commit comments