@@ -821,45 +821,15 @@ impl Worker {
821821 }
822822
823823 fn generate_and_broadcast_message ( & mut self , block_hash : Option < BlockHash > , is_restoring : bool ) {
824- if let Some ( message) = self . generate_message ( block_hash, is_restoring) {
824+ if let Some ( message) = self . vote_on_block_hash ( block_hash) . expect ( "Error while vote" ) {
825+ self . handle_valid_message ( & message, is_restoring) ;
825826 if !is_restoring {
826827 self . backup ( ) ;
827828 }
828829 self . broadcast_message ( message) ;
829830 }
830831 }
831832
832- fn generate_message ( & mut self , block_hash : Option < BlockHash > , is_restoring : bool ) -> Option < ConsensusMessage > {
833- let height = self . height ;
834- let r = self . view ;
835- let on = VoteOn {
836- step : VoteStep :: new ( height, r, self . step . to_step ( ) ) ,
837- block_hash,
838- } ;
839- let signer_index = self . signer_index ( ) . or_else ( || {
840- ctrace ! ( ENGINE , "No message, since there is no engine signer." ) ;
841- None
842- } ) ?;
843- let signature = self
844- . sign ( & on)
845- . map_err ( |error| {
846- ctrace ! ( ENGINE , "{}th validator could not sign the message {}" , signer_index, error) ;
847- error
848- } )
849- . ok ( ) ?;
850- let message = ConsensusMessage {
851- signature,
852- signer_index,
853- on,
854- } ;
855- self . votes_received . set ( signer_index) ;
856- self . votes . vote ( message. clone ( ) ) ;
857- cinfo ! ( ENGINE , "Generated {:?} as {}th validator." , message, signer_index) ;
858- self . handle_valid_message ( & message, is_restoring) ;
859-
860- Some ( message)
861- }
862-
863833 fn handle_valid_message ( & mut self , message : & ConsensusMessage , is_restoring : bool ) {
864834 let vote_step = & message. on . step ;
865835 let is_newer_than_lock = match self . last_two_thirds_majority . view ( ) {
@@ -1117,7 +1087,6 @@ impl Worker {
11171087 }
11181088
11191089 let header = sealed_block. header ( ) ;
1120- let hash = header. hash ( ) ;
11211090 let parent_hash = header. parent_hash ( ) ;
11221091
11231092 if let TendermintState :: ProposeWaitBlockGeneration {
@@ -1137,19 +1106,9 @@ impl Worker {
11371106 ) ;
11381107 return
11391108 }
1140- let prev_proposer_idx = self . block_proposer_idx ( * parent_hash) . expect ( "Prev block must exists" ) ;
1141-
11421109 debug_assert_eq ! ( Ok ( self . view) , TendermintSealView :: new( header. seal( ) ) . consensus_view( ) ) ;
11431110
1144- let vote_on = VoteOn {
1145- step : VoteStep :: new ( header. number ( ) as Height , self . view , Step :: Propose ) ,
1146- block_hash : Some ( hash) ,
1147- } ;
1148- let signature = self . sign ( & vote_on) . expect ( "I am proposer" ) ;
1149- self . votes . vote (
1150- ConsensusMessage :: new_proposal ( signature, & * self . validators , header, self . view , prev_proposer_idx)
1151- . expect ( "I am proposer" ) ,
1152- ) ;
1111+ self . vote_on_header_for_proposal ( & header) . expect ( "I'm a proposer" ) ;
11531112
11541113 self . step = TendermintState :: ProposeWaitImported {
11551114 block : Box :: new ( sealed_block. clone ( ) ) ,
@@ -1499,18 +1458,7 @@ impl Worker {
14991458
15001459 fn repropose_block ( & mut self , block : encoded:: Block ) {
15011460 let header = block. decode_header ( ) ;
1502- let vote_on = VoteOn {
1503- step : VoteStep :: new ( header. number ( ) as Height , self . view , Step :: Propose ) ,
1504- block_hash : Some ( header. hash ( ) ) ,
1505- } ;
1506- let parent_hash = header. parent_hash ( ) ;
1507- let prev_proposer_idx = self . block_proposer_idx ( * parent_hash) . expect ( "Prev block must exists" ) ;
1508- let signature = self . sign ( & vote_on) . expect ( "I am proposer" ) ;
1509- self . votes . vote (
1510- ConsensusMessage :: new_proposal ( signature, & * self . validators , & header, self . view , prev_proposer_idx)
1511- . expect ( "I am proposer" ) ,
1512- ) ;
1513-
1461+ self . vote_on_header_for_proposal ( & header) . expect ( "I am proposer" ) ;
15141462 self . proposal = Proposal :: new_imported ( header. hash ( ) ) ;
15151463 self . broadcast_proposal_block ( self . view , block) ;
15161464 }
@@ -1538,8 +1486,76 @@ impl Worker {
15381486 self . signer . set_to_keep_decrypted_account ( ap, address) ;
15391487 }
15401488
1541- fn sign ( & self , vote_on : & VoteOn ) -> Result < SchnorrSignature , Error > {
1542- self . signer . sign ( vote_on. hash ( ) ) . map_err ( Into :: into)
1489+ fn vote_on_block_hash ( & mut self , block_hash : Option < BlockHash > ) -> Result < Option < ConsensusMessage > , Error > {
1490+ let signer_index = if let Some ( signer_index) = self . signer_index ( ) {
1491+ signer_index
1492+ } else {
1493+ ctrace ! ( ENGINE , "No message, since there is no engine signer." ) ;
1494+ return Ok ( None )
1495+ } ;
1496+
1497+ let on = VoteOn {
1498+ step : VoteStep :: new ( self . height , self . view , self . step . to_step ( ) ) ,
1499+ block_hash,
1500+ } ;
1501+ let signature = self . signer . sign ( on. hash ( ) ) ?;
1502+
1503+ let vote = ConsensusMessage {
1504+ signature,
1505+ signer_index,
1506+ on,
1507+ } ;
1508+
1509+ self . votes_received . set ( vote. signer_index ) ;
1510+ self . votes . vote ( vote. clone ( ) ) ;
1511+ cinfo ! ( ENGINE , "Voted {:?} as {}th validator." , vote, signer_index) ;
1512+ Ok ( Some ( vote) )
1513+ }
1514+
1515+ fn vote_on_header_for_proposal ( & mut self , header : & Header ) -> Result < ConsensusMessage , Error > {
1516+ assert ! ( header. number( ) == self . height) ;
1517+
1518+ let parent_hash = header. parent_hash ( ) ;
1519+ let prev_proposer_idx = self . block_proposer_idx ( * parent_hash) . expect ( "Prev block must exists" ) ;
1520+ let signer_index = self . validators . proposer_index ( * parent_hash, prev_proposer_idx, self . view as usize ) ;
1521+
1522+ let on = VoteOn {
1523+ step : VoteStep :: new ( self . height , self . view , Step :: Propose ) ,
1524+ block_hash : Some ( * header. parent_hash ( ) ) ,
1525+ } ;
1526+ let signature = self . signer . sign ( on. hash ( ) ) ?;
1527+
1528+ let vote = ConsensusMessage {
1529+ signature,
1530+ signer_index,
1531+ on,
1532+ } ;
1533+
1534+ self . votes . vote ( vote. clone ( ) ) ;
1535+ cinfo ! ( ENGINE , "Voted {:?} as {}th proposer." , vote, signer_index) ;
1536+ Ok ( vote)
1537+ }
1538+
1539+ fn recover_proposal_vote (
1540+ & self ,
1541+ header : & Header ,
1542+ proposed_view : View ,
1543+ signature : SchnorrSignature ,
1544+ ) -> Option < ConsensusMessage > {
1545+ let prev_proposer_idx = self . block_proposer_idx ( * header. parent_hash ( ) ) ?;
1546+ let signer_index =
1547+ self . validators . proposer_index ( * header. parent_hash ( ) , prev_proposer_idx, proposed_view as usize ) ;
1548+
1549+ let on = VoteOn {
1550+ step : VoteStep :: new ( header. number ( ) , proposed_view, Step :: Propose ) ,
1551+ block_hash : Some ( header. hash ( ) ) ,
1552+ } ;
1553+
1554+ Some ( ConsensusMessage {
1555+ signature,
1556+ signer_index,
1557+ on,
1558+ } )
15431559 }
15441560
15451561 fn signer_index ( & self ) -> Option < usize > {
@@ -1703,27 +1719,14 @@ impl Worker {
17031719 return None
17041720 }
17051721 }
1706-
1707- let prev_proposer_idx = match self . block_proposer_idx ( * parent_hash) {
1708- Some ( idx) => idx,
1722+ let message = match self . recover_proposal_vote ( & header_view, proposed_view, signature) {
1723+ Some ( vote) => vote,
17091724 None => {
17101725 cwarn ! ( ENGINE , "Prev block proposer does not exist for height {}" , number) ;
17111726 return None
17121727 }
17131728 } ;
17141729
1715- let message = ConsensusMessage :: new_proposal (
1716- signature,
1717- & * self . validators ,
1718- & header_view,
1719- proposed_view,
1720- prev_proposer_idx,
1721- )
1722- . map_err ( |err| {
1723- cwarn ! ( ENGINE , "Invalid proposal received: {:?}" , err) ;
1724- } )
1725- . ok ( ) ?;
1726-
17271730 // If the proposal's height is current height + 1 and the proposal has valid precommits,
17281731 // we should import it and increase height
17291732 if number > ( self . height + 1 ) as u64 {
0 commit comments