state transitions on complete-proposal, 2/3-any, 2/3-one
(mi msgInfo)
| 797 | |
| 798 | // state transitions on complete-proposal, 2/3-any, 2/3-one |
| 799 | func (cs *State) handleMsg(mi msgInfo) { |
| 800 | cs.mtx.Lock() |
| 801 | defer cs.mtx.Unlock() |
| 802 | var ( |
| 803 | added bool |
| 804 | err error |
| 805 | ) |
| 806 | |
| 807 | msg, peerID := mi.Msg, mi.PeerID |
| 808 | |
| 809 | switch msg := msg.(type) { |
| 810 | case *ProposalMessage: |
| 811 | // will not cause transition. |
| 812 | // once proposal is set, we can receive block parts |
| 813 | err = cs.setProposal(msg.Proposal) |
| 814 | |
| 815 | case *BlockPartMessage: |
| 816 | // if the proposal is complete, we'll enterPrevote or tryFinalizeCommit |
| 817 | added, err = cs.addProposalBlockPart(msg, peerID) |
| 818 | |
| 819 | // We unlock here to yield to any routines that need to read the the RoundState. |
| 820 | // Previously, this code held the lock from the point at which the final block |
| 821 | // part was received until the block executed against the application. |
| 822 | // This prevented the reactor from being able to retrieve the most updated |
| 823 | // version of the RoundState. The reactor needs the updated RoundState to |
| 824 | // gossip the now completed block. |
| 825 | // |
| 826 | // This code can be further improved by either always operating on a copy |
| 827 | // of RoundState and only locking when switching out State's copy of |
| 828 | // RoundState with the updated copy or by emitting RoundState events in |
| 829 | // more places for routines depending on it to listen for. |
| 830 | cs.mtx.Unlock() |
| 831 | |
| 832 | cs.mtx.Lock() |
| 833 | if added && cs.ProposalBlockParts.IsComplete() { |
| 834 | cs.handleCompleteProposal(msg.Height) |
| 835 | } |
| 836 | if added { |
| 837 | cs.statsMsgQueue <- mi |
| 838 | } |
| 839 | |
| 840 | if err != nil && msg.Round != cs.Round { |
| 841 | cs.Logger.Debug( |
| 842 | "received block part from wrong round", |
| 843 | "height", cs.Height, |
| 844 | "cs_round", cs.Round, |
| 845 | "block_round", msg.Round, |
| 846 | ) |
| 847 | err = nil |
| 848 | } |
| 849 | |
| 850 | case *VoteMessage: |
| 851 | // attempt to add the vote and dupeout the validator if its a duplicate signature |
| 852 | // if the vote gives us a 2/3-any or 2/3-one, we transition |
| 853 | added, err = cs.tryAddVote(msg.Vote, peerID) |
| 854 | if added { |
| 855 | cs.statsMsgQueue <- mi |
| 856 | } |