@@ -35,7 +35,8 @@ impl ETHHeaders {
3535 let current_epoch_block_number = self . target . current_epoch_block_number ( ) ?;
3636 let checkpoint = current_epoch_block_number + previous_epoch. checkpoint ( ) ;
3737
38- let ( n_val, next_checkpoint) = self . verify_header_size ( checkpoint, current_epoch) ?;
38+ let ( n_val, next_checkpoint) =
39+ self . verify_header_size ( checkpoint, current_epoch, current_epoch_block_number) ?;
3940
4041 // Ensure all the headers are successfully chained.
4142 self . verify_cascading_fields ( ) ?;
@@ -139,29 +140,73 @@ impl ETHHeaders {
139140 /// checkpoint range and ensures that they meet the size requirements for the current and next epochs.
140141 fn verify_header_size (
141142 & self ,
142- checkpoint : u64 ,
143+ current_checkpoint : u64 ,
143144 current_epoch : & EitherEpoch ,
145+ current_epoch_block_number : BlockNumber ,
144146 ) -> Result < ( Option < Epoch > , Option < BlockNumber > ) , Error > {
145- let after_checkpoint: Vec < & ETHHeader > =
146- self . all . iter ( ) . filter ( |h| h. number >= checkpoint) . collect ( ) ;
147-
148- let find_next_epoch = |hs : & Vec < & ETHHeader > , height_to_checkpoint : u64 | {
149- for h in hs. iter ( ) {
150- if let Ok ( next_epoch) = get_validator_bytes_and_turn_length ( & h. extra_data ) {
151- let next_epoch = Epoch :: new ( next_epoch. 0 . into ( ) , next_epoch. 1 ) ;
152- let next_checkpoint = h. number + height_to_checkpoint;
153- return ( Some ( next_epoch) , Some ( next_checkpoint) ) ;
147+ let after_checkpoint: Vec < & ETHHeader > = self
148+ . all
149+ . iter ( )
150+ . filter ( |h| h. number >= current_checkpoint)
151+ . collect ( ) ;
152+
153+ let find_next_epoch =
154+ |hs : & Vec < & ETHHeader > ,
155+ height_to_checkpoint : u64 ,
156+ expected_prev_epoch_number : BlockNumber | {
157+ for h in hs. iter ( ) {
158+ let self_current_epoch_number =
159+ h. current_epoch_block_number ( ) . map_err ( |e| {
160+ Error :: UnexpectedMissingForkSpecInCurrentEpochCalculation (
161+ h. number ,
162+ alloc:: boxed:: Box :: new ( e) ,
163+ )
164+ } ) ?;
165+ if self_current_epoch_number == h. number {
166+ return if let Some ( next_epoch) = & h. epoch {
167+ let self_previous_epoch_number =
168+ h. previous_epoch_block_number ( ) . map_err ( |e| {
169+ Error :: UnexpectedMissingForkSpecInPreviousEpochCalculation (
170+ h. number ,
171+ alloc:: boxed:: Box :: new ( e) ,
172+ )
173+ } ) ?;
174+ if self_previous_epoch_number != expected_prev_epoch_number {
175+ return Err ( Error :: UnexpectedPreviousEpochInCalculatingNextEpoch (
176+ h. number ,
177+ self_previous_epoch_number,
178+ expected_prev_epoch_number,
179+ current_epoch_block_number,
180+ ) ) ;
181+ }
182+ let next_checkpoint = h. number + height_to_checkpoint;
183+ Ok ( (
184+ Some ( next_epoch. clone ( ) ) ,
185+ Some ( next_checkpoint) ,
186+ Some ( self_current_epoch_number) ,
187+ ) )
188+ } else {
189+ Err ( Error :: MissingEpochInfo ( h. number ) )
190+ } ;
191+ } else if h. is_epoch ( ) {
192+ return Err ( Error :: UnexpectedEpochInfo (
193+ h. number ,
194+ self_current_epoch_number,
195+ ) ) ;
196+ }
154197 }
155- }
156- ( None , None )
157- } ;
198+ Ok ( ( None , None , None ) )
199+ } ;
158200
159201 match current_epoch {
160202 // ex) t=200 then 200 <= h < 411 (at least 1 honest c_val(200)' can be in p_val)
161203 Untrusted ( _) => {
162204 // Ensure headers are before the next_checkpoint
163- let ( next_epoch, next_checkpoint) =
164- find_next_epoch ( & after_checkpoint, current_epoch. checkpoint ( ) ) ;
205+ let ( next_epoch, next_checkpoint, _) = find_next_epoch (
206+ & after_checkpoint,
207+ current_epoch. checkpoint ( ) ,
208+ current_epoch_block_number,
209+ ) ?;
165210 if let Some ( next_checkpoint) = next_checkpoint {
166211 if after_checkpoint. iter ( ) . any ( |h| h. number >= next_checkpoint) {
167212 return Err ( Error :: UnexpectedNextCheckpointHeader (
@@ -175,28 +220,31 @@ impl ETHHeaders {
175220 // ex) t=201 then 201 <= h < 611 (at least 1 honest n_val(400) can be in c_val(200))
176221 Trusted ( _) => {
177222 // Get next_epoch if epoch after checkpoint ex) 400
178- let ( next_epoch, next_checkpoint) =
179- find_next_epoch ( & after_checkpoint, current_epoch. checkpoint ( ) ) ;
223+ let ( next_epoch, next_checkpoint, next_epoch_block_number) = find_next_epoch (
224+ & after_checkpoint,
225+ current_epoch. checkpoint ( ) ,
226+ current_epoch_block_number,
227+ ) ?;
180228 let next_checkpoint = match next_checkpoint {
181229 None => return Ok ( ( next_epoch, next_checkpoint) ) ,
182230 Some ( v) => v,
183231 } ;
184232
185233 // Finish if no headers over next checkpoint were found
186- let after_next_checkpoint: Vec < & ETHHeader > = self
187- . all
188- . iter ( )
234+ let after_next_checkpoint: Vec < & ETHHeader > = after_checkpoint
235+ . into_iter ( )
189236 . filter ( |h| h. number >= next_checkpoint)
190237 . collect ( ) ;
191238 if after_next_checkpoint. is_empty ( ) {
192239 return Ok ( ( next_epoch, Some ( next_checkpoint) ) ) ;
193240 }
194241
195242 // Ensure headers are before the next_next_checkpoint
196- let ( _, next_next_checkpoint) = find_next_epoch (
243+ let ( _, next_next_checkpoint, _ ) = find_next_epoch (
197244 & after_next_checkpoint,
198245 next_epoch. clone ( ) . unwrap ( ) . checkpoint ( ) ,
199- ) ;
246+ next_epoch_block_number. unwrap ( ) ,
247+ ) ?;
200248 if let Some ( next_next_checkpoint) = next_next_checkpoint {
201249 if after_next_checkpoint
202250 . iter ( )
0 commit comments