@@ -454,7 +454,8 @@ impl Worker {
454
454
self . validators . next_block_proposer ( prev_block_hash, view)
455
455
}
456
456
457
- pub fn proposal_at ( & self , height : Height , view : View ) -> Option < ( SchnorrSignature , usize , Bytes ) > {
457
+ /// If there are more than one proposals(DoubleVote), send the first.
458
+ pub fn first_proposal_at ( & self , height : Height , view : View ) -> Option < ( SchnorrSignature , usize , Bytes ) > {
458
459
let vote_step = VoteStep {
459
460
height,
460
461
view,
@@ -476,11 +477,9 @@ impl Worker {
476
477
step : Step :: Propose ,
477
478
} ) ;
478
479
479
- if let Some ( proposal) = all_votes. first ( ) {
480
- proposal. on . block_hash . expect ( "Proposal message always include block hash" ) == block_hash
481
- } else {
482
- false
483
- }
480
+ all_votes
481
+ . into_iter ( )
482
+ . any ( |proposal| proposal. on . block_hash . expect ( "Proposal message always include block hash" ) == block_hash)
484
483
}
485
484
486
485
pub fn vote_step ( & self ) -> VoteStep {
@@ -670,6 +669,7 @@ impl Worker {
670
669
match state. to_step ( ) {
671
670
Step :: Propose => {
672
671
cinfo ! ( ENGINE , "move_to_step: Propose." ) ;
672
+ // If there are double voted proposals, use the first proposal.
673
673
if let Some ( hash) = self . votes . get_block_hashes ( & vote_step) . first ( ) {
674
674
if self . client ( ) . block ( & BlockId :: Hash ( * hash) ) . is_some ( ) {
675
675
self . proposal = Proposal :: new_imported ( * hash) ;
@@ -683,9 +683,9 @@ impl Worker {
683
683
} else {
684
684
let parent_block_hash = self . prev_block_hash ( ) ;
685
685
if self . is_signer_proposer ( & parent_block_hash) {
686
- if let TwoThirdsMajority :: Lock ( lock_view, _ ) = self . last_two_thirds_majority {
686
+ if let TwoThirdsMajority :: Lock ( lock_view, locked_block_hash ) = & self . last_two_thirds_majority {
687
687
cinfo ! ( ENGINE , "I am a proposer, I'll re-propose a locked block" ) ;
688
- match self . locked_proposal_block ( lock_view) {
688
+ match self . locked_proposal_block ( * lock_view, * locked_block_hash ) {
689
689
Ok ( block) => self . repropose_block ( block) ,
690
690
Err ( error_msg) => cwarn ! ( ENGINE , "{}" , error_msg) ,
691
691
}
@@ -796,14 +796,15 @@ impl Worker {
796
796
}
797
797
}
798
798
799
- fn locked_proposal_block ( & self , locked_view : View ) -> Result < encoded:: Block , String > {
799
+ fn locked_proposal_block ( & self , locked_view : View , locked_proposal_hash : H256 ) -> Result < encoded:: Block , String > {
800
800
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 ( ) ;
801
+ let received_locked_block =
802
+ self . votes . get_block_hashes ( & vote_step) . into_iter ( ) . any ( |block_hash| block_hash == locked_proposal_hash) ;
802
803
803
- let locked_proposal_hash = locked_proposal_hash . ok_or_else ( || {
804
+ if !received_locked_block {
804
805
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
- } ) ? ;
806
+ return Err ( format ! ( "Have a lock on {}-{}, but do not received a locked proposal" , self . height, locked_view) )
807
+ }
807
808
808
809
let locked_proposal_block = self . client ( ) . block ( & BlockId :: Hash ( locked_proposal_hash) ) . ok_or_else ( || {
809
810
format ! (
@@ -971,8 +972,9 @@ impl Worker {
971
972
972
973
let current_height = self . height ;
973
974
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 ( ) ) {
975
+ let is_current_proposal =
976
+ self . votes . get_block_hashes ( & vote_step) . into_iter ( ) . any ( |block_hash| block_hash == proposal. hash ( ) ) ;
977
+ if is_current_proposal {
976
978
self . proposal = Proposal :: new_imported ( proposal. hash ( ) ) ;
977
979
let current_step = self . step . clone ( ) ;
978
980
match current_step {
@@ -1005,16 +1007,16 @@ impl Worker {
1005
1007
self . move_to_height ( height) ;
1006
1008
let prev_block_view = TendermintSealView :: new ( proposal. seal ( ) ) . previous_block_view ( ) . unwrap ( ) ;
1007
1009
self . save_last_confirmed_view ( prev_block_view) ;
1008
- let proposal_at_view_0 = self
1010
+ let is_view0_proposal = self
1009
1011
. votes
1010
1012
. get_block_hashes ( & VoteStep {
1011
1013
height,
1012
1014
view : 0 ,
1013
1015
step : Step :: Propose ,
1014
1016
} )
1015
- . first ( )
1016
- . cloned ( ) ;
1017
- if proposal_at_view_0 == Some ( proposal . hash ( ) ) {
1017
+ . into_iter ( )
1018
+ . any ( |block_hash| block_hash == proposal . hash ( ) ) ;
1019
+ if is_view0_proposal {
1018
1020
self . proposal = Proposal :: new_imported ( proposal. hash ( ) )
1019
1021
}
1020
1022
self . move_to_step ( TendermintState :: Prevote , false ) ;
@@ -1896,7 +1898,7 @@ impl Worker {
1896
1898
return
1897
1899
}
1898
1900
1899
- if let Some ( ( signature, _signer_index, block) ) = self . proposal_at ( request_height, request_view) {
1901
+ if let Some ( ( signature, _signer_index, block) ) = self . first_proposal_at ( request_height, request_view) {
1900
1902
ctrace ! ( ENGINE , "Send proposal {}-{} to {:?}" , request_height, request_view, token) ;
1901
1903
self . send_proposal_block ( signature, request_view, block, result) ;
1902
1904
return
0 commit comments