diff options
Diffstat (limited to 'vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go')
-rw-r--r-- | vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go index 97848c5e4..c08518ad8 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go @@ -29,6 +29,13 @@ import ( "github.com/dexon-foundation/dexon-consensus/core/utils" ) +// closedchan is a reusable closed channel. +var closedchan = make(chan struct{}) + +func init() { + close(closedchan) +} + // Errors for agreement module. var ( ErrInvalidVote = fmt.Errorf("invalid vote") @@ -110,6 +117,7 @@ type agreement struct { state agreementState data *agreementData aID *atomic.Value + doneChan chan struct{} notarySet map[types.NodeID]struct{} hasVoteFast bool hasOutput bool @@ -168,9 +176,13 @@ func (a *agreement) restart( a.data.blocks = make(map[types.NodeID]*types.Block) a.data.requiredVote = len(notarySet)/3*2 + 1 a.data.leader.restart(crs) - a.data.lockValue = nullBlockHash + a.data.lockValue = types.NullBlockHash a.data.lockIter = 0 a.data.isLeader = a.data.ID == leader + if a.doneChan != nil { + close(a.doneChan) + } + a.doneChan = make(chan struct{}) a.fastForward = make(chan uint64, 1) a.hasVoteFast = false a.hasOutput = false @@ -340,6 +352,17 @@ func (a *agreement) prepareVote(vote *types.Vote) (err error) { return } +func (a *agreement) updateFilter(filter *utils.VoteFilter) { + a.lock.RLock() + defer a.lock.RUnlock() + a.data.lock.RLock() + defer a.data.lock.RUnlock() + filter.Confirm = a.hasOutput + filter.LockIter = a.data.lockIter + filter.Period = a.data.period + filter.Height = a.agreementID().Height +} + // processVote is the entry point for processing Vote. func (a *agreement) processVote(vote *types.Vote) error { a.lock.Lock() @@ -382,13 +405,16 @@ func (a *agreement) processVote(vote *types.Vote) error { if _, exist := a.data.votes[vote.Period]; !exist { a.data.votes[vote.Period] = newVoteListMap() } + if _, exist := a.data.votes[vote.Period][vote.Type][vote.ProposerID]; exist { + return nil + } a.data.votes[vote.Period][vote.Type][vote.ProposerID] = vote if !a.hasOutput && (vote.Type == types.VoteCom || vote.Type == types.VoteFast || vote.Type == types.VoteFastCom) { if hash, ok := a.data.countVoteNoLock(vote.Period, vote.Type); ok && - hash != skipBlockHash { + hash != types.SkipBlockHash { if vote.Type == types.VoteFast { if !a.hasVoteFast { a.data.recv.ProposeVote( @@ -401,6 +427,8 @@ func (a *agreement) processVote(vote *types.Vote) error { a.hasOutput = true a.data.recv.ConfirmBlock(hash, a.data.votes[vote.Period][vote.Type]) + close(a.doneChan) + a.doneChan = nil } return nil } @@ -413,8 +441,12 @@ func (a *agreement) processVote(vote *types.Vote) error { return nil } if vote.Type == types.VotePreCom { + if vote.Period < a.data.lockIter { + // This PreCom is useless for us. + return nil + } if hash, ok := a.data.countVoteNoLock(vote.Period, vote.Type); ok && - hash != skipBlockHash { + hash != types.SkipBlockHash { // Condition 1. if a.data.period >= vote.Period && vote.Period > a.data.lockIter && vote.BlockHash != a.data.lockValue { @@ -439,7 +471,8 @@ func (a *agreement) processVote(vote *types.Vote) error { hashes := common.Hashes{} addPullBlocks := func(voteType types.VoteType) { for _, vote := range a.data.votes[vote.Period][voteType] { - if vote.BlockHash == nullBlockHash || vote.BlockHash == skipBlockHash { + if vote.BlockHash == types.NullBlockHash || + vote.BlockHash == types.SkipBlockHash { continue } if _, found := a.findCandidateBlockNoLock(vote.BlockHash); !found { @@ -447,7 +480,6 @@ func (a *agreement) processVote(vote *types.Vote) error { } } } - addPullBlocks(types.VoteInit) addPullBlocks(types.VotePreCom) addPullBlocks(types.VoteCom) if len(hashes) > 0 { @@ -462,24 +494,24 @@ func (a *agreement) processVote(vote *types.Vote) error { func (a *agreement) done() <-chan struct{} { a.lock.Lock() defer a.lock.Unlock() + if a.doneChan == nil { + return closedchan + } a.data.lock.Lock() defer a.data.lock.Unlock() - ch := make(chan struct{}, 1) - if a.hasOutput { - ch <- struct{}{} - } else { - select { - case period := <-a.fastForward: - if period <= a.data.period { - break - } - a.data.setPeriod(period) - a.state = newPreCommitState(a.data) - ch <- struct{}{} - default: + select { + case period := <-a.fastForward: + if period <= a.data.period { + break } - } - return ch + a.data.setPeriod(period) + a.state = newPreCommitState(a.data) + close(a.doneChan) + a.doneChan = make(chan struct{}) + return closedchan + default: + } + return a.doneChan } func (a *agreement) confirmed() bool { |