@@ -453,7 +453,7 @@ impl Worker {
453453 self . validators . next_block_proposer ( prev_block_hash, view)
454454 }
455455
456- pub fn proposal_at ( & self , height : Height , view : View ) -> Option < ( SchnorrSignature , usize , Bytes ) > {
456+ pub fn first_proposal_at ( & self , height : Height , view : View ) -> Option < ( SchnorrSignature , usize , Bytes ) > {
457457 let vote_step = VoteStep {
458458 height,
459459 view,
@@ -475,11 +475,9 @@ impl Worker {
475475 step : Step :: Propose ,
476476 } ) ;
477477
478- if let Some ( proposal) = all_votes. first ( ) {
479- proposal. on . block_hash . expect ( "Proposal message always include block hash" ) == block_hash
480- } else {
481- false
482- }
478+ all_votes
479+ . into_iter ( )
480+ . any ( |proposal| proposal. on . block_hash . expect ( "Proposal message always include block hash" ) == block_hash)
483481 }
484482
485483 pub fn vote_step ( & self ) -> VoteStep {
@@ -670,6 +668,7 @@ impl Worker {
670668 match state. to_step ( ) {
671669 Step :: Propose => {
672670 cinfo ! ( ENGINE , "move_to_step: Propose." ) ;
671+ // If there are multiple proposals, use the first proposal.
673672 if let Some ( hash) = self . votes . get_block_hashes ( & vote_step) . first ( ) {
674673 if self . client ( ) . block ( & BlockId :: Hash ( * hash) ) . is_some ( ) {
675674 self . proposal = Proposal :: new_imported ( * hash) ;
@@ -683,9 +682,9 @@ impl Worker {
683682 } else {
684683 let parent_block_hash = self . prev_block_hash ( ) ;
685684 if self . is_signer_proposer ( & parent_block_hash) {
686- if let TwoThirdsMajority :: Lock ( lock_view, _ ) = self . last_two_thirds_majority {
685+ if let TwoThirdsMajority :: Lock ( lock_view, locked_block_hash ) = self . last_two_thirds_majority {
687686 cinfo ! ( ENGINE , "I am a proposer, I'll re-propose a locked block" ) ;
688- match self . locked_proposal_block ( lock_view) {
687+ match self . locked_proposal_block ( lock_view, locked_block_hash ) {
689688 Ok ( block) => self . repropose_block ( block) ,
690689 Err ( error_msg) => cwarn ! ( ENGINE , "{}" , error_msg) ,
691690 }
@@ -796,14 +795,14 @@ impl Worker {
796795 }
797796 }
798797
799- fn locked_proposal_block ( & self , locked_view : View ) -> Result < encoded:: Block , String > {
798+ fn locked_proposal_block ( & self , locked_view : View , locked_proposal_hash : H256 ) -> Result < encoded:: Block , String > {
800799 let vote_step = VoteStep :: new ( self . height , locked_view, Step :: Propose ) ;
801- let locked_proposal_hash = self . votes . get_block_hashes ( & vote_step) . first ( ) . cloned ( ) ;
800+ let received_locked_block = self . votes . has_votes_for ( & vote_step, locked_proposal_hash ) ;
802801
803- let locked_proposal_hash = locked_proposal_hash . ok_or_else ( || {
802+ if !received_locked_block {
804803 self . request_proposal_to_any ( self . height , locked_view) ;
805- format ! ( "Have a lock on {}-{}, but do not received a locked proposal" , self . height, locked_view)
806- } ) ? ;
804+ return Err ( format ! ( "Have a lock on {}-{}, but do not received a locked proposal" , self . height, locked_view) )
805+ }
807806
808807 let locked_proposal_block = self . client ( ) . block ( & BlockId :: Hash ( locked_proposal_hash) ) . ok_or_else ( || {
809808 format ! (
@@ -970,9 +969,9 @@ impl Worker {
970969 } ) ;
971970
972971 let current_height = self . height ;
973- let vote_step = VoteStep :: new ( self . height , self . view , self . step . to_step ( ) ) ;
974- let proposal_at_current_view = self . votes . get_block_hashes ( & vote_step ) . first ( ) . cloned ( ) ;
975- if proposal_at_current_view == Some ( proposal . hash ( ) ) {
972+ let current_vote_step = VoteStep :: new ( self . height , self . view , self . step . to_step ( ) ) ;
973+ let proposal_is_for_current = self . votes . has_votes_for ( & current_vote_step , proposal . hash ( ) ) ;
974+ if proposal_is_for_current {
976975 self . proposal = Proposal :: new_imported ( proposal. hash ( ) ) ;
977976 let current_step = self . step . clone ( ) ;
978977 match current_step {
@@ -1005,16 +1004,15 @@ impl Worker {
10051004 self . move_to_height ( height) ;
10061005 let prev_block_view = TendermintSealView :: new ( proposal. seal ( ) ) . previous_block_view ( ) . unwrap ( ) ;
10071006 self . save_last_confirmed_view ( prev_block_view) ;
1008- let proposal_at_view_0 = self
1009- . votes
1010- . get_block_hashes ( & VoteStep {
1007+ let proposal_is_for_view0 = self . votes . has_votes_for (
1008+ & VoteStep {
10111009 height,
10121010 view : 0 ,
10131011 step : Step :: Propose ,
1014- } )
1015- . first ( )
1016- . cloned ( ) ;
1017- if proposal_at_view_0 == Some ( proposal . hash ( ) ) {
1012+ } ,
1013+ proposal . hash ( ) ,
1014+ ) ;
1015+ if proposal_is_for_view0 {
10181016 self . proposal = Proposal :: new_imported ( proposal. hash ( ) )
10191017 }
10201018 self . move_to_step ( TendermintState :: Prevote , false ) ;
@@ -1896,7 +1894,7 @@ impl Worker {
18961894 return
18971895 }
18981896
1899- if let Some ( ( signature, _signer_index, block) ) = self . proposal_at ( request_height, request_view) {
1897+ if let Some ( ( signature, _signer_index, block) ) = self . first_proposal_at ( request_height, request_view) {
19001898 ctrace ! ( ENGINE , "Send proposal {}-{} to {:?}" , request_height, request_view, token) ;
19011899 self . send_proposal_block ( signature, request_view, block, result) ;
19021900 return
0 commit comments