|
14 | 14 | // You should have received a copy of the GNU Affero General Public License |
15 | 15 | // along with this program. If not, see <https://www.gnu.org/licenses/>. |
16 | 16 |
|
| 17 | +use std::cmp::Ordering; |
17 | 18 | use std::iter::Iterator; |
18 | 19 | use std::mem; |
19 | 20 | use std::sync::{Arc, Weak}; |
@@ -690,34 +691,33 @@ impl Worker { |
690 | 691 | cinfo!(ENGINE, "move_to_step: Propose."); |
691 | 692 | // If there are multiple proposals, use the first proposal. |
692 | 693 | if let Some(hash) = self.votes.get_block_hashes(&vote_step).first() { |
693 | | - if self.client().block(&BlockId::Hash(*hash)).is_some() { |
694 | | - self.proposal = Proposal::new_imported(*hash); |
695 | | - self.move_to_step(TendermintState::Prevote, is_restoring); |
696 | | - } else { |
| 694 | + if self.client().block(&BlockId::Hash(*hash)).is_none() { |
697 | 695 | cwarn!(ENGINE, "Proposal is received but not imported"); |
698 | 696 | // Proposal is received but is not verified yet. |
699 | 697 | // Wait for verification. |
700 | 698 | return |
701 | 699 | } |
702 | | - } else { |
703 | | - let parent_block_hash = self.prev_block_hash(); |
704 | | - if self.is_signer_proposer(&parent_block_hash) { |
705 | | - if let TwoThirdsMajority::Lock(lock_view, locked_block_hash) = self.last_two_thirds_majority { |
706 | | - cinfo!(ENGINE, "I am a proposer, I'll re-propose a locked block"); |
707 | | - match self.locked_proposal_block(lock_view, locked_block_hash) { |
708 | | - Ok(block) => self.repropose_block(block), |
709 | | - Err(error_msg) => cwarn!(ENGINE, "{}", error_msg), |
710 | | - } |
711 | | - } else { |
712 | | - cinfo!(ENGINE, "I am a proposer, I'll create a block"); |
713 | | - self.update_sealing(parent_block_hash); |
714 | | - self.step = TendermintState::ProposeWaitBlockGeneration { |
715 | | - parent_hash: parent_block_hash, |
716 | | - }; |
717 | | - } |
718 | | - } else { |
719 | | - self.request_proposal_to_any(vote_step.height, vote_step.view); |
| 700 | + self.proposal = Proposal::new_imported(*hash); |
| 701 | + self.move_to_step(TendermintState::Prevote, is_restoring); |
| 702 | + return |
| 703 | + } |
| 704 | + let parent_block_hash = self.prev_block_hash(); |
| 705 | + if !self.is_signer_proposer(&parent_block_hash) { |
| 706 | + self.request_proposal_to_any(vote_step.height, vote_step.view); |
| 707 | + return |
| 708 | + } |
| 709 | + if let TwoThirdsMajority::Lock(lock_view, locked_block_hash) = self.last_two_thirds_majority { |
| 710 | + cinfo!(ENGINE, "I am a proposer, I'll re-propose a locked block"); |
| 711 | + match self.locked_proposal_block(lock_view, locked_block_hash) { |
| 712 | + Ok(block) => self.repropose_block(block), |
| 713 | + Err(error_msg) => cwarn!(ENGINE, "{}", error_msg), |
720 | 714 | } |
| 715 | + } else { |
| 716 | + cinfo!(ENGINE, "I am a proposer, I'll create a block"); |
| 717 | + self.update_sealing(parent_block_hash); |
| 718 | + self.step = TendermintState::ProposeWaitBlockGeneration { |
| 719 | + parent_hash: parent_block_hash, |
| 720 | + }; |
721 | 721 | } |
722 | 722 | } |
723 | 723 | Step::Prevote => { |
@@ -1562,7 +1562,7 @@ impl Worker { |
1562 | 1562 | on, |
1563 | 1563 | }; |
1564 | 1564 |
|
1565 | | - self.votes.collect(vote.clone()).expect("Must not attempt double vote on proposal");; |
| 1565 | + self.votes.collect(vote.clone()).expect("Must not attempt double vote on proposal"); |
1566 | 1566 | cinfo!(ENGINE, "Voted {:?} as {}th proposer.", vote, signer_index); |
1567 | 1567 | Ok(vote) |
1568 | 1568 | } |
@@ -1811,7 +1811,7 @@ impl Worker { |
1811 | 1811 | ); |
1812 | 1812 | } |
1813 | 1813 |
|
1814 | | - if let Err(double) = self.votes.collect(message.clone()) { |
| 1814 | + if let Err(double) = self.votes.collect(message) { |
1815 | 1815 | cerror!(ENGINE, "Double Vote found {:?}", double); |
1816 | 1816 | self.report_double_vote(&double); |
1817 | 1817 | return None |
@@ -1869,17 +1869,15 @@ impl Worker { |
1869 | 1869 |
|
1870 | 1870 | let current_step = current_vote_step.step; |
1871 | 1871 | if current_step == Step::Prevote || current_step == Step::Precommit { |
1872 | | - let peer_known_votes = if current_vote_step == peer_vote_step { |
1873 | | - peer_known_votes |
1874 | | - } else if current_vote_step < peer_vote_step { |
| 1872 | + let peer_known_votes = match current_vote_step.cmp(&peer_vote_step) { |
| 1873 | + Ordering::Equal => peer_known_votes, |
1875 | 1874 | // We don't know which votes peer has. |
1876 | 1875 | // However the peer knows more than 2/3 of votes. |
1877 | 1876 | // So request all votes. |
1878 | | - BitSet::all_set() |
1879 | | - } else { |
| 1877 | + Ordering::Less => BitSet::all_set(), |
1880 | 1878 | // If peer's state is less than my state, |
1881 | 1879 | // the peer does not know any useful votes. |
1882 | | - BitSet::new() |
| 1880 | + Ordering::Greater => BitSet::new(), |
1883 | 1881 | }; |
1884 | 1882 |
|
1885 | 1883 | let difference = &peer_known_votes - &self.votes_received; |
@@ -1969,45 +1967,47 @@ impl Worker { |
1969 | 1967 | return |
1970 | 1968 | } |
1971 | 1969 |
|
1972 | | - if height == self.height - 1 { |
1973 | | - let block = self.client().block(&height.into()).expect("Parent block should exist"); |
1974 | | - let block_hash = block.hash(); |
1975 | | - let finalized_view = self.finalized_view_of_previous_block; |
1976 | | - |
1977 | | - let votes = self |
1978 | | - .votes |
1979 | | - .get_all_votes_in_round(&VoteStep { |
1980 | | - height, |
1981 | | - view: finalized_view, |
1982 | | - step: Step::Precommit, |
1983 | | - }) |
1984 | | - .into_iter() |
1985 | | - .filter(|vote| vote.on.block_hash == Some(block_hash)) |
1986 | | - .collect(); |
1987 | | - |
1988 | | - self.send_commit(block, votes, &result); |
1989 | | - } else if height < self.height - 1 { |
1990 | | - let block = self.client().block(&height.into()).expect("Parent block should exist"); |
1991 | | - let child_block = self.client().block(&(height + 1).into()).expect("Parent block should exist"); |
1992 | | - let child_block_header_seal = child_block.header().seal(); |
1993 | | - let child_block_seal_view = TendermintSealView::new(&child_block_header_seal); |
1994 | | - let parent_block_finalized_view = |
1995 | | - child_block_seal_view.parent_block_finalized_view().expect("Verified block"); |
1996 | | - let on = VoteOn { |
1997 | | - step: VoteStep::new(height, parent_block_finalized_view, Step::Precommit), |
1998 | | - block_hash: Some(block.hash()), |
1999 | | - }; |
2000 | | - let mut votes = Vec::new(); |
2001 | | - for (index, signature) in child_block_seal_view.signatures().expect("The block is verified") { |
2002 | | - let message = ConsensusMessage { |
2003 | | - signature, |
2004 | | - signer_index: index, |
2005 | | - on: on.clone(), |
| 1970 | + match height.cmp(&(self.height - 1)) { |
| 1971 | + Ordering::Equal => { |
| 1972 | + let block = self.client().block(&height.into()).expect("Parent block should exist"); |
| 1973 | + let block_hash = block.hash(); |
| 1974 | + let finalized_view = self.finalized_view_of_previous_block; |
| 1975 | + |
| 1976 | + let votes = self |
| 1977 | + .votes |
| 1978 | + .get_all_votes_in_round(&VoteStep { |
| 1979 | + height, |
| 1980 | + view: finalized_view, |
| 1981 | + step: Step::Precommit, |
| 1982 | + }) |
| 1983 | + .into_iter() |
| 1984 | + .filter(|vote| vote.on.block_hash == Some(block_hash)) |
| 1985 | + .collect(); |
| 1986 | + |
| 1987 | + self.send_commit(block, votes, &result); |
| 1988 | + } |
| 1989 | + Ordering::Less => { |
| 1990 | + let block = self.client().block(&height.into()).expect("Parent block should exist"); |
| 1991 | + let child_block = self.client().block(&(height + 1).into()).expect("Parent block should exist"); |
| 1992 | + let child_block_header_seal = child_block.header().seal(); |
| 1993 | + let child_block_seal_view = TendermintSealView::new(&child_block_header_seal); |
| 1994 | + let parent_block_finalized_view = |
| 1995 | + child_block_seal_view.parent_block_finalized_view().expect("Verified block"); |
| 1996 | + let on = VoteOn { |
| 1997 | + step: VoteStep::new(height, parent_block_finalized_view, Step::Precommit), |
| 1998 | + block_hash: Some(block.hash()), |
2006 | 1999 | }; |
2007 | | - votes.push(message); |
| 2000 | + let mut votes = Vec::new(); |
| 2001 | + for (index, signature) in child_block_seal_view.signatures().expect("The block is verified") { |
| 2002 | + let message = ConsensusMessage { |
| 2003 | + signature, |
| 2004 | + signer_index: index, |
| 2005 | + on: on.clone(), |
| 2006 | + }; |
| 2007 | + votes.push(message); |
| 2008 | + } |
2008 | 2009 | } |
2009 | | - |
2010 | | - self.send_commit(block, votes, &result); |
| 2010 | + Ordering::Greater => {} |
2011 | 2011 | } |
2012 | 2012 | } |
2013 | 2013 |
|
@@ -2049,23 +2049,27 @@ impl Worker { |
2049 | 2049 | return None |
2050 | 2050 | } |
2051 | 2051 |
|
2052 | | - if commit_height < self.height { |
2053 | | - cdebug!( |
2054 | | - ENGINE, |
2055 | | - "Received commit message is old. Current height is {} but commit messages is for height {}", |
2056 | | - self.height, |
2057 | | - commit_height, |
2058 | | - ); |
2059 | | - return None |
2060 | | - } else if commit_height > self.height { |
2061 | | - cwarn!( |
2062 | | - ENGINE, |
2063 | | - "Invalid commit message received: precommit on height {} but current height is {}", |
2064 | | - commit_height, |
2065 | | - self.height |
2066 | | - ); |
2067 | | - return None |
2068 | | - } |
| 2052 | + match commit_height.cmp(&self.height) { |
| 2053 | + Ordering::Less => { |
| 2054 | + cdebug!( |
| 2055 | + ENGINE, |
| 2056 | + "Received commit message is old. Current height is {} but commit messages is for height {}", |
| 2057 | + self.height, |
| 2058 | + commit_height, |
| 2059 | + ); |
| 2060 | + return None |
| 2061 | + } |
| 2062 | + Ordering::Greater => { |
| 2063 | + cwarn!( |
| 2064 | + ENGINE, |
| 2065 | + "Invalid commit message received: precommit on height {} but current height is {}", |
| 2066 | + commit_height, |
| 2067 | + self.height |
| 2068 | + ); |
| 2069 | + return None |
| 2070 | + } |
| 2071 | + Ordering::Equal => {} |
| 2072 | + }; |
2069 | 2073 |
|
2070 | 2074 | let prev_block_hash = self |
2071 | 2075 | .client() |
|
0 commit comments