@@ -85,8 +85,11 @@ struct Worker {
8585 last_two_thirds_majority : TwoThirdsMajority ,
8686 /// hash of the proposed block, used for seal submission.
8787 proposal : Proposal ,
88- /// The last confirmed view from the commit step.
89- last_confirmed_view : View ,
88+ /// The finalized view of the previous height's block.
89+ /// The signatures for the previous block is signed for the view below.
90+ finalized_view_of_previous_block : View ,
91+ /// The finalized view of the current height's block.
92+ finalized_view_of_current_block : Option < View > ,
9093 /// Set used to determine the current validators.
9194 validators : Arc < DynamicValidator > ,
9295 /// Channel to the network extension, must be set later.
@@ -187,7 +190,8 @@ impl Worker {
187190 signer : Default :: default ( ) ,
188191 last_two_thirds_majority : TwoThirdsMajority :: Empty ,
189192 proposal : Proposal :: None ,
190- last_confirmed_view : 0 ,
193+ finalized_view_of_previous_block : 0 ,
194+ finalized_view_of_current_block : None ,
191195 validators,
192196 extension,
193197 votes_received : MutTrigger :: new ( BitSet :: new ( ) ) ,
@@ -418,7 +422,11 @@ impl Worker {
418422 return false
419423 }
420424
421- let vote_step = VoteStep :: new ( self . height , self . last_confirmed_view , Step :: Precommit ) ;
425+ let vote_step = VoteStep :: new (
426+ self . height ,
427+ self . finalized_view_of_current_block . expect ( "finalized_view_of_current_height is not None in Commit state" ) ,
428+ Step :: Precommit ,
429+ ) ;
422430 if self . step . is_commit_timedout ( ) && self . check_current_block_exists ( ) {
423431 cinfo ! ( ENGINE , "Transition to Propose because best block is changed after commit timeout" ) ;
424432 return true
@@ -597,8 +605,10 @@ impl Worker {
597605 self . client ( ) . update_sealing ( BlockId :: Hash ( parent_block_hash) , true ) ;
598606 }
599607
600- fn save_last_confirmed_view ( & mut self , view : View ) {
601- self . last_confirmed_view = view;
608+ /// Do we need this function?
609+ fn set_finalized_view_in_current_height ( & mut self , view : View ) {
610+ assert_eq ! ( self . finalized_view_of_current_block, None ) ;
611+ self . finalized_view_of_current_block = Some ( view) ;
602612 }
603613
604614 fn increment_view ( & mut self , n : View ) {
@@ -608,14 +618,37 @@ impl Worker {
608618 self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
609619 }
610620
611- fn move_to_height ( & mut self , height : Height ) {
621+ /// Move to the next height.
622+ fn move_to_the_next_height ( & mut self ) {
623+ assert ! (
624+ self . step. is_commit( ) ,
625+ "move_to_the_next_height should be called in Commit state, but the current step is {:?}" ,
626+ self . step
627+ ) ;
628+ cinfo ! ( ENGINE , "Transitioning to height {}." , self . height + 1 ) ;
629+ self . last_two_thirds_majority = TwoThirdsMajority :: Empty ;
630+ self . height += 1 ;
631+ self . view = 0 ;
632+ self . proposal = Proposal :: None ;
633+ self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
634+ self . finalized_view_of_previous_block =
635+ self . finalized_view_of_current_block . expect ( "self.step == Step::Commit" ) ;
636+ self . finalized_view_of_current_block = None ;
637+ }
638+
639+ /// Jump to the height.
640+ /// This function is called when new blocks are received from block sync.
641+ /// This function could be called at any state.
642+ fn jump_to_height ( & mut self , height : Height , finalized_view_of_previous_height : View ) {
612643 assert ! ( height > self . height, "{} < {}" , height, self . height) ;
613644 cinfo ! ( ENGINE , "Transitioning to height {}." , height) ;
614645 self . last_two_thirds_majority = TwoThirdsMajority :: Empty ;
615646 self . height = height;
616647 self . view = 0 ;
617648 self . proposal = Proposal :: None ;
618649 self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
650+ self . finalized_view_of_previous_block = finalized_view_of_previous_height;
651+ self . finalized_view_of_current_block = None ;
619652 }
620653
621654 #[ allow( clippy:: cognitive_complexity) ]
@@ -736,7 +769,7 @@ impl Worker {
736769 Step :: Commit => {
737770 cinfo ! ( ENGINE , "move_to_step: Commit." ) ;
738771 let ( view, block_hash) = state. committed ( ) . expect ( "commit always has committed_view" ) ;
739- self . save_last_confirmed_view ( view) ;
772+ self . set_finalized_view_in_current_height ( view) ;
740773
741774 let proposal_received = self . is_proposal_received ( self . height , view, block_hash) ;
742775 let proposal_imported = self . client ( ) . block ( & block_hash. into ( ) ) . is_some ( ) ;
@@ -850,8 +883,7 @@ impl Worker {
850883 && has_enough_aligned_votes
851884 {
852885 if self . can_move_from_commit_to_propose ( ) {
853- let height = self . height ;
854- self . move_to_height ( height + 1 ) ;
886+ self . move_to_the_next_height ( ) ;
855887 self . move_to_step ( TendermintState :: Propose , is_restoring) ;
856888 return
857889 }
@@ -957,9 +989,11 @@ impl Worker {
957989 _ => { }
958990 } ;
959991 } else if current_height < height {
960- self . move_to_height ( height) ;
961- let prev_block_view = TendermintSealView :: new ( proposal. seal ( ) ) . previous_block_view ( ) . unwrap ( ) ;
962- self . save_last_confirmed_view ( prev_block_view) ;
992+ let finalized_view_of_previous_height =
993+ TendermintSealView :: new ( proposal. seal ( ) ) . previous_block_view ( ) . unwrap ( ) ;
994+
995+ self . jump_to_height ( height, finalized_view_of_previous_height) ;
996+
963997 let proposal_is_for_view0 = self . votes . has_votes_for (
964998 & VoteStep {
965999 height,
@@ -981,8 +1015,8 @@ impl Worker {
9811015 view : & self . view ,
9821016 step : & self . step . to_step ( ) ,
9831017 votes : & self . votes . get_all ( ) ,
984- finalized_view_of_previous_block : & self . last_confirmed_view ,
985- finalized_view_of_current_block : & Some ( self . last_confirmed_view ) ,
1018+ finalized_view_of_previous_block : & self . finalized_view_of_previous_block ,
1019+ finalized_view_of_current_block : & self . finalized_view_of_current_block ,
9861020 } ) ;
9871021 }
9881022
@@ -1002,12 +1036,9 @@ impl Worker {
10021036 self . step = backup_step;
10031037 self . height = backup. height ;
10041038 self . view = backup. view ;
1005- if backup. step == Step :: Commit {
1006- self . last_confirmed_view =
1007- backup. finalized_view_of_current_block . expect ( "In commit step the finalized view exist" )
1008- } else {
1009- self . last_confirmed_view = backup. finalized_view_of_previous_block ;
1010- }
1039+ self . finalized_view_of_previous_block = backup. finalized_view_of_previous_block ;
1040+ self . finalized_view_of_current_block = backup. finalized_view_of_current_block ;
1041+
10111042 if let Some ( proposal) = backup. proposal {
10121043 if client. block ( & BlockId :: Hash ( proposal) ) . is_some ( ) {
10131044 self . proposal = Proposal :: ProposalImported ( proposal) ;
@@ -1045,7 +1076,7 @@ impl Worker {
10451076
10461077 let view = self . view ;
10471078
1048- let last_block_view = & self . last_confirmed_view ;
1079+ let last_block_view = & self . finalized_view_of_previous_block ;
10491080 assert_eq ! ( self . prev_block_hash( ) , parent_hash) ;
10501081
10511082 let ( precommits, precommit_indices) = self
@@ -1305,8 +1336,7 @@ impl Worker {
13051336 return
13061337 }
13071338
1308- let height = self . height ;
1309- self . move_to_height ( height + 1 ) ;
1339+ self . move_to_the_next_height ( ) ;
13101340 TendermintState :: Propose
13111341 }
13121342 TendermintState :: CommitTimedout {
@@ -1374,7 +1404,7 @@ impl Worker {
13741404 // the previous step. So, act as the last precommit step.
13751405 VoteStep {
13761406 height : self . height ,
1377- view : self . last_confirmed_view ,
1407+ view : self . finalized_view_of_current_block . expect ( "self.step == Step::Commit" ) ,
13781408 step : Step :: Precommit ,
13791409 }
13801410 } else {
@@ -1585,8 +1615,7 @@ impl Worker {
15851615 if enacted. first ( ) == Some ( & committed_block_hash) {
15861616 cdebug ! ( ENGINE , "Committed block {} is now the best block" , committed_block_hash) ;
15871617 if self . can_move_from_commit_to_propose ( ) {
1588- let new_height = self . height + 1 ;
1589- self . move_to_height ( new_height) ;
1618+ self . move_to_the_next_height ( ) ;
15901619 self . move_to_step ( TendermintState :: Propose , false ) ;
15911620 return
15921621 }
@@ -1612,11 +1641,10 @@ impl Worker {
16121641 let full_header = header. decode ( ) ;
16131642 if self . height < header. number ( ) {
16141643 cinfo ! ( ENGINE , "Received a commit: {:?}." , header. number( ) ) ;
1615- let prev_block_view = TendermintSealView :: new ( full_header. seal ( ) )
1644+ let finalized_view_of_previous_height = TendermintSealView :: new ( full_header. seal ( ) )
16161645 . previous_block_view ( )
16171646 . expect ( "Imported block already checked" ) ;
1618- self . move_to_height ( header. number ( ) ) ;
1619- self . save_last_confirmed_view ( prev_block_view) ;
1647+ self . jump_to_height ( header. number ( ) , finalized_view_of_previous_height) ;
16201648 }
16211649 }
16221650 if height_at_begin != self . height {
@@ -1809,7 +1837,7 @@ impl Worker {
18091837 // the previous step. So, act as the last precommit step.
18101838 VoteStep {
18111839 height : self . height ,
1812- view : self . last_confirmed_view ,
1840+ view : self . finalized_view_of_current_block . expect ( "self.step == Step::Commit" ) ,
18131841 step : Step :: Precommit ,
18141842 }
18151843 } else {
0 commit comments