diff --git a/consensus/vbft/block_pool.go b/consensus/vbft/block_pool.go index 871361cdd4..3af96680af 100644 --- a/consensus/vbft/block_pool.go +++ b/consensus/vbft/block_pool.go @@ -495,7 +495,7 @@ func (pool *BlockPool) commitDone(blkNum uint32, C uint32, N uint32) (uint32, bo } // check consensus with commit msgs - proposer, forEmpty := getCommitConsensus(candidate.CommitMsgs, int(C)) + proposer, forEmpty := getCommitConsensus(candidate.CommitMsgs, int(C), int(N)) // enforce signature quorum if checking commit-consensus base on signature count // if C <= (N-1)/3, N-1-C >= 2*C diff --git a/consensus/vbft/node_utils.go b/consensus/vbft/node_utils.go index d5724f0ca4..c09078b6a8 100644 --- a/consensus/vbft/node_utils.go +++ b/consensus/vbft/node_utils.go @@ -319,11 +319,10 @@ func calcParticipant(vrf vconfig.VRFValue, dposTable []uint32, k uint32) uint32 // @ consensused proposer // @ consensused for empty commit // -func getCommitConsensus(commitMsgs []*blockCommitMsg, C int) (uint32, bool) { - commitCount := make(map[uint32]int) // proposer -> #commit-msg - endorseCount := make(map[uint32]map[uint32]struct{}) // proposer -> []endorsers +func getCommitConsensus(commitMsgs []*blockCommitMsg, C int, N int) (uint32, bool) { emptyCommitCount := 0 emptyCommit := false + signCount := make(map[uint32]map[uint32]int) for _, c := range commitMsgs { if c.CommitForEmpty { emptyCommitCount++ @@ -332,21 +331,15 @@ func getCommitConsensus(commitMsgs []*blockCommitMsg, C int) (uint32, bool) { emptyCommit = true } } - - commitCount[c.BlockProposer] += 1 - if commitCount[c.BlockProposer] > C { - return c.BlockProposer, emptyCommit + if _, present := signCount[c.BlockProposer]; !present { + signCount[c.BlockProposer] = make(map[uint32]int) } - + signCount[c.BlockProposer][c.Committer] += 1 for endorser := range c.EndorsersSig { - if _, present := endorseCount[c.BlockProposer]; !present { - endorseCount[c.BlockProposer] = make(map[uint32]struct{}) - } - - endorseCount[c.BlockProposer][endorser] = struct{}{} - if len(endorseCount[c.BlockProposer]) > C+1 { - return c.BlockProposer, c.CommitForEmpty - } + signCount[c.BlockProposer][endorser] += 1 + } + if len(signCount[c.BlockProposer])+1 >= N-(N-1)/3 { + return c.BlockProposer, emptyCommit } } diff --git a/consensus/vbft/node_utils_test.go b/consensus/vbft/node_utils_test.go index b815e770e2..3aa28ec85c 100644 --- a/consensus/vbft/node_utils_test.go +++ b/consensus/vbft/node_utils_test.go @@ -147,6 +147,6 @@ func TestGetCommitConsensus(t *testing.T) { } var commitMsgs []*blockCommitMsg commitMsgs = append(commitMsgs, blockcommitmsg) - blockproposer, flag := getCommitConsensus(commitMsgs, 2) + blockproposer, flag := getCommitConsensus(commitMsgs, 2, 7) t.Logf("TestGetCommitConsensus %d ,%v", blockproposer, flag) } diff --git a/consensus/vbft/service.go b/consensus/vbft/service.go index 1762b2fa6d..8353f5b612 100644 --- a/consensus/vbft/service.go +++ b/consensus/vbft/service.go @@ -243,7 +243,7 @@ func (self *Server) CheckSubmitBlock(blkNum uint32, stateRoot common.Uint256) bo } } } - m := len(self.config.Peers) - (len(self.config.Peers)*3)/7 + m := self.config.N - (self.config.N-1)/3 if stateRootCnt < uint32(m) { return false } @@ -1426,6 +1426,7 @@ func (self *Server) actionLoop() { for { blkNum := self.GetCurrentBlockNo() C := int(self.config.C) + N := int(self.config.N) if err := self.updateParticipantConfig(); err != nil { log.Errorf("server %d update config failed in forwarding: %s", self.Index, err) @@ -1466,7 +1467,7 @@ func (self *Server) actionLoop() { } // check if consensused - proposer, forEmpty := getCommitConsensus(commitMsgs, C) + proposer, forEmpty := getCommitConsensus(commitMsgs, C, N) if proposer == math.MaxUint32 { if err := self.catchConsensus(blkNum); err != nil { log.Infof("server %d fastforward done, catch consensus: %s", self.Index, err) @@ -1886,7 +1887,9 @@ func (self *Server) processHeartbeatMsg(peerIdx uint32, msg *peerHeartbeatMsg) { func (self *Server) endorseBlock(proposal *blockProposalMsg, forEmpty bool) error { // for each round, one node can only endorse one block, or empty block - + if proposal.Block.getProposer() == self.Index { + return nil + } blkNum := proposal.GetBlockNum() // check if has endorsed @@ -1944,7 +1947,9 @@ func (self *Server) endorseBlock(proposal *blockProposalMsg, forEmpty bool) erro func (self *Server) commitBlock(proposal *blockProposalMsg, forEmpty bool) error { // for each round, we can only commit one block - + if proposal.Block.getProposer() == self.Index { + return nil + } blkNum := proposal.GetBlockNum() if self.blockPool.committedForBlock(blkNum) { return nil diff --git a/consensus/vbft/state_mgmt.go b/consensus/vbft/state_mgmt.go index a826f8071d..0d67e9dbce 100644 --- a/consensus/vbft/state_mgmt.go +++ b/consensus/vbft/state_mgmt.go @@ -450,6 +450,7 @@ func (self *StateMgr) canFastForward(targetBlkNum uint32) bool { } C := int(self.server.config.C) + N := int(self.server.config.N) // one block less than targetBlkNum is also acceptable for fastforward for blkNum := self.server.GetCurrentBlockNo(); blkNum <= targetBlkNum; blkNum++ { // check if pending messages for targetBlkNum reached consensus @@ -459,7 +460,7 @@ func (self *StateMgr) canFastForward(targetBlkNum uint32) bool { commitMsgs = append(commitMsgs, c) } } - proposer, _ := getCommitConsensus(commitMsgs, C) + proposer, _ := getCommitConsensus(commitMsgs, C, N) if proposer == math.MaxUint32 { log.Infof("server %d check fastforward false, no consensus in %d commit msg for block %d", self.server.Index, len(commitMsgs), blkNum)