aboutsummaryrefslogtreecommitdiffstats
path: root/core/agreement-mgr.go
diff options
context:
space:
mode:
authorJimmy Hu <jimmy.hu@dexon.org>2019-04-11 16:45:54 +0800
committerGitHub <noreply@github.com>2019-04-11 16:45:54 +0800
commit464e79e66f18679b8afb821f622ed1358100832d (patch)
tree4ae9c67625369c238e751186629b391cfdf8b4cc /core/agreement-mgr.go
parent5b0aad05d7ccc1dabedfd1f3bfc0d584db849e63 (diff)
downloaddexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.tar
dexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.tar.gz
dexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.tar.bz2
dexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.tar.lz
dexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.tar.xz
dexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.tar.zst
dexon-consensus-464e79e66f18679b8afb821f622ed1358100832d.zip
core: fix false alarm (#564)
* ignore test simple * core: update voteFilter to filter old er round * circleci: save logs * core: move check notarySet to agrmgr * fixup
Diffstat (limited to 'core/agreement-mgr.go')
-rw-r--r--core/agreement-mgr.go47
1 files changed, 37 insertions, 10 deletions
diff --git a/core/agreement-mgr.go b/core/agreement-mgr.go
index ac28955..4597fe9 100644
--- a/core/agreement-mgr.go
+++ b/core/agreement-mgr.go
@@ -24,6 +24,8 @@ import (
"sync"
"time"
+ lru "github.com/hashicorp/golang-lru"
+
"github.com/dexon-foundation/dexon-consensus/common"
"github.com/dexon-foundation/dexon-consensus/core/types"
typesDKG "github.com/dexon-foundation/dexon-consensus/core/types/dkg"
@@ -41,6 +43,7 @@ var (
)
const maxResultCache = 100
+const settingLimit = 3
// genValidLeader generate a validLeader function for agreement modules.
func genValidLeader(
@@ -130,12 +133,15 @@ type agreementMgr struct {
recv *consensusBAReceiver
processedBAResult map[types.Position]struct{}
voteFilter *utils.VoteFilter
+ settingCache *lru.Cache
+ curRoundSetting *baRoundSetting
waitGroup sync.WaitGroup
isRunning bool
lock sync.RWMutex
}
func newAgreementMgr(con *Consensus) (mgr *agreementMgr, err error) {
+ settingCache, _ := lru.New(settingLimit)
mgr = &agreementMgr{
con: con,
ID: con.ID,
@@ -149,6 +155,7 @@ func newAgreementMgr(con *Consensus) (mgr *agreementMgr, err error) {
ctx: con.ctx,
processedBAResult: make(map[types.Position]struct{}, maxResultCache),
voteFilter: utils.NewVoteFilter(),
+ settingCache: settingCache,
}
mgr.recv = &consensusBAReceiver{
consensus: con,
@@ -165,21 +172,18 @@ func (mgr *agreementMgr) prepare() {
newLeaderSelector(genValidLeader(mgr), mgr.logger),
mgr.signer,
mgr.logger)
- nodes, err := mgr.cache.GetNodeSet(round)
- if err != nil {
+ setting := mgr.generateSetting(round)
+ if setting == nil {
+ mgr.logger.Warn("Unable to prepare init setting", "round", round)
return
}
- agr.notarySet = nodes.GetSubSet(
- int(mgr.config(round).notarySetSize),
- types.NewNotarySetTarget(mgr.config(round).crs))
+ mgr.curRoundSetting = setting
+ agr.notarySet = mgr.curRoundSetting.dkgSet
// Hacky way to make agreement module self contained.
mgr.recv.agreementModule = agr
mgr.baModule = agr
if round >= DKGDelayRound {
- setting := mgr.generateSetting(round)
- if setting == nil {
- mgr.logger.Warn("Unable to prepare init setting", "round", round)
- } else if _, exist := setting.dkgSet[mgr.ID]; exist {
+ if _, exist := setting.dkgSet[mgr.ID]; exist {
mgr.logger.Debug("Preparing signer and npks.", "round", round)
npk, signer, err := mgr.con.cfgModule.getDKGInfo(round, false)
if err != nil {
@@ -268,9 +272,25 @@ func (mgr *agreementMgr) notifyRoundEvents(evts []utils.RoundEventParam) error {
}
func (mgr *agreementMgr) processVote(v *types.Vote) (err error) {
+ if !mgr.recv.isNotary {
+ return nil
+ }
if mgr.voteFilter.Filter(v) {
return nil
}
+ if v.Position.Round == mgr.curRoundSetting.round {
+ if _, exist := mgr.curRoundSetting.dkgSet[v.ProposerID]; !exist {
+ return ErrNotInNotarySet
+ }
+ } else if v.Position.Round == mgr.curRoundSetting.round+1 {
+ setting := mgr.generateSetting(v.Position.Round)
+ if setting == nil {
+ return ErrConfigurationNotReady
+ }
+ if _, exist := setting.dkgSet[v.ProposerID]; !exist {
+ return ErrNotInNotarySet
+ }
+ }
if err = mgr.baModule.processVote(v); err == nil {
mgr.baModule.updateFilter(mgr.voteFilter)
mgr.voteFilter.AddVote(v)
@@ -339,6 +359,7 @@ func (mgr *agreementMgr) processAgreementResult(
result.Position.Round)
return ErrConfigurationNotReady
}
+ mgr.curRoundSetting = setting
leader, err := mgr.calcLeader(setting.dkgSet, setting.crs, result.Position)
if err != nil {
return err
@@ -374,6 +395,9 @@ func (mgr *agreementMgr) stop() {
}
func (mgr *agreementMgr) generateSetting(round uint64) *baRoundSetting {
+ if setting, exist := mgr.settingCache.Get(round); exist {
+ return setting.(*baRoundSetting)
+ }
curConfig := mgr.config(round)
if curConfig == nil {
return nil
@@ -399,13 +423,15 @@ func (mgr *agreementMgr) generateSetting(round uint64) *baRoundSetting {
return nil
}
}
- return &baRoundSetting{
+ setting := &baRoundSetting{
crs: curConfig.crs,
dkgSet: dkgSet,
round: round,
threshold: utils.GetBAThreshold(&types.Config{
NotarySetSize: curConfig.notarySetSize}),
}
+ mgr.settingCache.Add(round, setting)
+ return setting
}
func (mgr *agreementMgr) runBA(initRound uint64) {
@@ -465,6 +491,7 @@ Loop:
}
mgr.recv.isNotary = checkRound()
mgr.voteFilter = utils.NewVoteFilter()
+ mgr.voteFilter.Position.Round = currentRound
mgr.recv.emptyBlockHashMap = &sync.Map{}
if currentRound >= DKGDelayRound && mgr.recv.isNotary {
var err error