aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
diff options
context:
space:
mode:
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.go72
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 {