@@ -85,8 +85,11 @@ struct Worker {
85
85
last_two_thirds_majority : TwoThirdsMajority ,
86
86
/// hash of the proposed block, used for seal submission.
87
87
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 > ,
90
93
/// Set used to determine the current validators.
91
94
validators : Arc < DynamicValidator > ,
92
95
/// Channel to the network extension, must be set later.
@@ -187,7 +190,8 @@ impl Worker {
187
190
signer : Default :: default ( ) ,
188
191
last_two_thirds_majority : TwoThirdsMajority :: Empty ,
189
192
proposal : Proposal :: None ,
190
- last_confirmed_view : 0 ,
193
+ finalized_view_of_previous_block : 0 ,
194
+ finalized_view_of_current_block : None ,
191
195
validators,
192
196
extension,
193
197
votes_received : MutTrigger :: new ( BitSet :: new ( ) ) ,
@@ -418,7 +422,11 @@ impl Worker {
418
422
return false
419
423
}
420
424
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
+ ) ;
422
430
if self . step . is_commit_timedout ( ) && self . check_current_block_exists ( ) {
423
431
cinfo ! ( ENGINE , "Transition to Propose because best block is changed after commit timeout" ) ;
424
432
return true
@@ -597,8 +605,10 @@ impl Worker {
597
605
self . client ( ) . update_sealing ( BlockId :: Hash ( parent_block_hash) , true ) ;
598
606
}
599
607
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) ;
602
612
}
603
613
604
614
fn increment_view ( & mut self , n : View ) {
@@ -608,14 +618,37 @@ impl Worker {
608
618
self . votes_received = MutTrigger :: new ( BitSet :: new ( ) ) ;
609
619
}
610
620
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 ) {
612
643
assert ! ( height > self . height, "{} < {}" , height, self . height) ;
613
644
cinfo ! ( ENGINE , "Transitioning to height {}." , height) ;
614
645
self . last_two_thirds_majority = TwoThirdsMajority :: Empty ;
615
646
self . height = height;
616
647
self . view = 0 ;
617
648
self . proposal = Proposal :: None ;
618
649
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 ;
619
652
}
620
653
621
654
#[ allow( clippy:: cognitive_complexity) ]
@@ -736,7 +769,7 @@ impl Worker {
736
769
Step :: Commit => {
737
770
cinfo ! ( ENGINE , "move_to_step: Commit." ) ;
738
771
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) ;
740
773
741
774
let proposal_received = self . is_proposal_received ( self . height , view, block_hash) ;
742
775
let proposal_imported = self . client ( ) . block ( & block_hash. into ( ) ) . is_some ( ) ;
@@ -850,8 +883,7 @@ impl Worker {
850
883
&& has_enough_aligned_votes
851
884
{
852
885
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 ( ) ;
855
887
self . move_to_step ( TendermintState :: Propose , is_restoring) ;
856
888
return
857
889
}
@@ -957,9 +989,11 @@ impl Worker {
957
989
_ => { }
958
990
} ;
959
991
} 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
+
963
997
let proposal_is_for_view0 = self . votes . has_votes_for (
964
998
& VoteStep {
965
999
height,
@@ -981,8 +1015,8 @@ impl Worker {
981
1015
view : & self . view ,
982
1016
step : & self . step . to_step ( ) ,
983
1017
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 ,
986
1020
} ) ;
987
1021
}
988
1022
@@ -1002,12 +1036,9 @@ impl Worker {
1002
1036
self . step = backup_step;
1003
1037
self . height = backup. height ;
1004
1038
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
+
1011
1042
if let Some ( proposal) = backup. proposal {
1012
1043
if client. block ( & BlockId :: Hash ( proposal) ) . is_some ( ) {
1013
1044
self . proposal = Proposal :: ProposalImported ( proposal) ;
@@ -1045,7 +1076,7 @@ impl Worker {
1045
1076
1046
1077
let view = self . view ;
1047
1078
1048
- let last_block_view = & self . last_confirmed_view ;
1079
+ let last_block_view = & self . finalized_view_of_previous_block ;
1049
1080
assert_eq ! ( self . prev_block_hash( ) , parent_hash) ;
1050
1081
1051
1082
let ( precommits, precommit_indices) = self
@@ -1305,8 +1336,7 @@ impl Worker {
1305
1336
return
1306
1337
}
1307
1338
1308
- let height = self . height ;
1309
- self . move_to_height ( height + 1 ) ;
1339
+ self . move_to_the_next_height ( ) ;
1310
1340
TendermintState :: Propose
1311
1341
}
1312
1342
TendermintState :: CommitTimedout {
@@ -1374,7 +1404,7 @@ impl Worker {
1374
1404
// the previous step. So, act as the last precommit step.
1375
1405
VoteStep {
1376
1406
height : self . height ,
1377
- view : self . last_confirmed_view ,
1407
+ view : self . finalized_view_of_current_block . expect ( "self.step == Step::Commit" ) ,
1378
1408
step : Step :: Precommit ,
1379
1409
}
1380
1410
} else {
@@ -1585,8 +1615,7 @@ impl Worker {
1585
1615
if enacted. first ( ) == Some ( & committed_block_hash) {
1586
1616
cdebug ! ( ENGINE , "Committed block {} is now the best block" , committed_block_hash) ;
1587
1617
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 ( ) ;
1590
1619
self . move_to_step ( TendermintState :: Propose , false ) ;
1591
1620
return
1592
1621
}
@@ -1612,11 +1641,10 @@ impl Worker {
1612
1641
let full_header = header. decode ( ) ;
1613
1642
if self . height < header. number ( ) {
1614
1643
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 ( ) )
1616
1645
. previous_block_view ( )
1617
1646
. 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) ;
1620
1648
}
1621
1649
}
1622
1650
if height_at_begin != self . height {
@@ -1809,7 +1837,7 @@ impl Worker {
1809
1837
// the previous step. So, act as the last precommit step.
1810
1838
VoteStep {
1811
1839
height : self . height ,
1812
- view : self . last_confirmed_view ,
1840
+ view : self . finalized_view_of_current_block . expect ( "self.step == Step::Commit" ) ,
1813
1841
step : Step :: Precommit ,
1814
1842
}
1815
1843
} else {
0 commit comments