github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/consensus/dbft/core/commit.go (about) 1 package core 2 3 import ( 4 "reflect" 5 6 "github.com/quickchainproject/quickchain/common" 7 bft "github.com/quickchainproject/quickchain/consensus/dbft" 8 ) 9 10 func (c *core) sendCommit() { 11 sub := c.current.Subject() 12 c.broadcastCommit(sub) 13 } 14 15 func (c *core) sendCommitForOldBlock(view *bft.View, digest common.Hash) { 16 sub := &bft.Subject{ 17 View: view, 18 Digest: digest, 19 } 20 c.broadcastCommit(sub) 21 } 22 23 func (c *core) broadcastCommit(sub *bft.Subject) { 24 logger := c.logger.New("state", c.state) 25 26 encodedSubject, err := Encode(sub) 27 if err != nil { 28 logger.Error("Failed to encode", "subject", sub) 29 return 30 } 31 c.broadcast(&message{ 32 Code: msgCommit, 33 Msg: encodedSubject, 34 }) 35 } 36 37 func (c *core) handleCommit(msg *message, src bft.Validator) error { 38 // Decode COMMIT message 39 var commit *bft.Subject 40 err := msg.Decode(&commit) 41 if err != nil { 42 return errFailedDecodeCommit 43 } 44 45 if err := c.checkMessage(msgCommit, commit.View); err != nil { 46 return err 47 } 48 49 if err := c.verifyCommit(commit, src); err != nil { 50 return err 51 } 52 53 c.acceptCommit(msg, src) 54 55 // Commit the proposal once we have enough COMMIT messages and we are not in the Committed state. 56 // 57 // If we already have a proposal, we may have chance to speed up the consensus process 58 // by committing the proposal without PREPARE messages. 59 if c.current.Commits.Size() > 2*c.valSet.F() && c.state.Cmp(StateCommitted) < 0 { 60 // Still need to call LockHash here since state can skip Prepared state and jump directly to the Committed state. 61 c.current.LockHash() 62 c.commit() 63 } 64 65 return nil 66 } 67 68 // verifyCommit verifies if the received COMMIT message is equivalent to our subject 69 func (c *core) verifyCommit(commit *bft.Subject, src bft.Validator) error { 70 logger := c.logger.New("from", src, "state", c.state) 71 72 sub := c.current.Subject() 73 if !reflect.DeepEqual(commit, sub) { 74 logger.Warn("Inconsistent subjects between commit and proposal", "expected", sub, "got", commit) 75 return errInconsistentSubject 76 } 77 78 return nil 79 } 80 81 func (c *core) acceptCommit(msg *message, src bft.Validator) error { 82 logger := c.logger.New("from", src, "state", c.state) 83 84 // Add the COMMIT message to current round state 85 if err := c.current.Commits.Add(msg); err != nil { 86 logger.Error("Failed to record commit message", "msg", msg, "err", err) 87 return err 88 } 89 90 return nil 91 }