@@ -526,27 +526,36 @@ pub(crate) async fn update_shared_state<
526
526
) ;
527
527
} ;
528
528
529
- let ( Some ( parent_state) , _ ) = validated_view. state_and_delta ( ) else {
529
+ let ( Some ( parent_state) , maybe_parent_delta ) = validated_view. state_and_delta ( ) else {
530
530
bail ! ( "Parent state not found! Consensus internally inconsistent" ) ;
531
531
} ;
532
532
533
- let version = upgrade_lock. version ( view_number) . await ?;
534
-
535
- let ( validated_state, state_delta) = parent_state
536
- . validate_and_apply_header (
537
- & instance_state,
538
- & parent,
539
- & proposed_leaf. block_header ( ) . clone ( ) ,
540
- vid_share. data . vid_common_ref ( ) . clone ( ) ,
541
- version,
542
- * view_number,
543
- )
544
- . await
545
- . wrap ( )
546
- . context ( warn ! ( "Block header doesn't extend the proposal!" ) ) ?;
533
+ let ( state, delta) = if is_last_block_in_epoch ( proposed_leaf. height ( ) , epoch_height)
534
+ && proposed_leaf. height ( ) == parent. height ( )
535
+ && maybe_parent_delta. is_some ( )
536
+ {
537
+ // This is an epoch transition. We do not want to call `validate_and_apply_header` second
538
+ // time for the same block. Just grab the state and delta from the parent and update the shared
539
+ // state with those.
540
+ ( parent_state, maybe_parent_delta. unwrap ( ) )
541
+ } else {
542
+ let version = upgrade_lock. version ( view_number) . await ?;
543
+
544
+ let ( validated_state, state_delta) = parent_state
545
+ . validate_and_apply_header (
546
+ & instance_state,
547
+ & parent,
548
+ & proposed_leaf. block_header ( ) . clone ( ) ,
549
+ vid_share. data . vid_common_ref ( ) . clone ( ) ,
550
+ version,
551
+ * view_number,
552
+ )
553
+ . await
554
+ . wrap ( )
555
+ . context ( warn ! ( "Block header doesn't extend the proposal!" ) ) ?;
547
556
548
- let state = Arc :: new ( validated_state) ;
549
- let delta = Arc :: new ( state_delta ) ;
557
+ ( Arc :: new ( validated_state) , Arc :: new ( state_delta ) )
558
+ } ;
550
559
551
560
// Now that we've rounded everyone up, we need to update the shared state
552
561
let mut consensus_writer = consensus. write ( ) . await ;
0 commit comments