aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go156
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go17
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go30
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go11
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go166
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go38
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go2
-rw-r--r--vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go5
-rw-r--r--vendor/vendor.json48
12 files changed, 267 insertions, 212 deletions
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
index 423174c48..8cb4c2e37 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement-mgr.go
@@ -22,11 +22,11 @@ import (
"errors"
"math"
"sync"
- "sync/atomic"
"time"
"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"
"github.com/dexon-foundation/dexon-consensus/core/utils"
)
@@ -35,6 +35,7 @@ var (
ErrPreviousRoundIsNotFinished = errors.New("previous round is not finished")
ErrRoundOutOfRange = errors.New("round out of range")
ErrInvalidBlock = errors.New("invalid block")
+ ErrNoValidLeader = errors.New("no valid leader")
)
const maxResultCache = 100
@@ -89,7 +90,9 @@ func newAgreementMgrConfig(prev agreementMgrConfig, config *types.Config,
}
type baRoundSetting struct {
- notarySet map[types.NodeID]struct{}
+ round uint64
+ dkgSet map[types.NodeID]struct{}
+ threshold int
ticker Ticker
crs common.Hash
}
@@ -132,13 +135,9 @@ func newAgreementMgr(con *Consensus) (mgr *agreementMgr, err error) {
voteFilter: utils.NewVoteFilter(),
}
mgr.recv = &consensusBAReceiver{
- consensus: con,
- restartNotary: make(chan types.Position, 1),
- roundValue: &atomic.Value{},
- changeNotaryHeightValue: &atomic.Value{},
+ consensus: con,
+ restartNotary: make(chan types.Position, 1),
}
- mgr.recv.updateRound(uint64(0))
- mgr.recv.changeNotaryHeightValue.Store(uint64(0))
return mgr, nil
}
@@ -177,6 +176,19 @@ func (mgr *agreementMgr) run() {
}()
}
+func (mgr *agreementMgr) calcLeader(
+ dkgSet map[types.NodeID]struct{},
+ crs common.Hash, pos types.Position) (
+ types.NodeID, error) {
+ nodeSet := types.NewNodeSetFromMap(dkgSet)
+ leader := nodeSet.GetSubSet(1, types.NewNodeLeaderTarget(
+ crs, pos.Height))
+ for nID := range leader {
+ return nID, nil
+ }
+ return types.NodeID{}, ErrNoValidLeader
+}
+
func (mgr *agreementMgr) config(round uint64) *agreementMgrConfig {
mgr.lock.RLock()
defer mgr.lock.RUnlock()
@@ -201,13 +213,6 @@ func (mgr *agreementMgr) notifyRoundEvents(evts []utils.RoundEventParam) error {
}
if lastCfg.RoundID() == e.Round {
mgr.configs[len(mgr.configs)-1].ExtendLength()
- // It's not an atomic operation to update an atomic value based
- // on another. However, it's the best way so far to extend
- // length of round without refactoring.
- if mgr.recv.round() == e.Round {
- mgr.recv.changeNotaryHeightValue.Store(
- mgr.configs[len(mgr.configs)-1].RoundEndHeight())
- }
} else if lastCfg.RoundID()+1 == e.Round {
mgr.configs = append(mgr.configs, newAgreementMgrConfig(
lastCfg, e.Config, e.CRS))
@@ -285,10 +290,6 @@ func (mgr *agreementMgr) processAgreementResult(
}
} else if result.Position.Newer(aID) {
mgr.logger.Info("Fast syncing BA", "position", result.Position)
- nIDs, err := mgr.cache.GetNotarySet(result.Position.Round)
- if err != nil {
- return err
- }
if result.Position.Round < DKGDelayRound {
mgr.logger.Debug("Calling Network.PullBlocks for fast syncing BA",
"hash", result.BlockHash)
@@ -299,13 +300,19 @@ func (mgr *agreementMgr) processAgreementResult(
}
}
}
- mgr.logger.Debug("Calling Governance.CRS", "round", result.Position.Round)
- crs := utils.GetCRSWithPanic(mgr.gov, result.Position.Round, mgr.logger)
- leader, err := mgr.cache.GetLeaderNode(result.Position)
+ setting := mgr.generateSetting(result.Position.Round)
+ if setting == nil {
+ mgr.logger.Warn("unable to get setting", "round",
+ result.Position.Round)
+ return ErrConfigurationNotReady
+ }
+ leader, err := mgr.calcLeader(setting.dkgSet, setting.crs, result.Position)
if err != nil {
return err
}
- mgr.baModule.restart(nIDs, result.Position, leader, crs)
+ mgr.baModule.restart(
+ setting.dkgSet, setting.threshold,
+ result.Position, leader, setting.crs)
if result.Position.Round >= DKGDelayRound {
return mgr.baModule.processAgreementResult(result)
}
@@ -333,57 +340,87 @@ func (mgr *agreementMgr) stop() {
mgr.waitGroup.Wait()
}
+func (mgr *agreementMgr) generateSetting(round uint64) *baRoundSetting {
+ curConfig := mgr.config(round)
+ if curConfig == nil {
+ return nil
+ }
+ var dkgSet map[types.NodeID]struct{}
+ if round >= DKGDelayRound {
+ _, qualidifed, err := typesDKG.CalcQualifyNodes(
+ mgr.gov.DKGMasterPublicKeys(round),
+ mgr.gov.DKGComplaints(round),
+ utils.GetDKGThreshold(mgr.gov.Configuration(round)),
+ )
+ if err != nil {
+ mgr.logger.Error("Failed to get gpk", "round", round, "error", err)
+ return nil
+ }
+ dkgSet = qualidifed
+ }
+ if len(dkgSet) == 0 {
+ var err error
+ dkgSet, err = mgr.cache.GetNotarySet(round)
+ if err != nil {
+ mgr.logger.Error("Failed to get notarySet", "round", round)
+ return nil
+ }
+ }
+ return &baRoundSetting{
+ crs: curConfig.crs,
+ dkgSet: dkgSet,
+ round: round,
+ threshold: utils.GetBAThreshold(&types.Config{
+ NotarySetSize: curConfig.notarySetSize}),
+ }
+}
+
func (mgr *agreementMgr) runBA(initRound uint64) {
// These are round based variables.
var (
currentRound uint64
nextRound = initRound
curConfig = mgr.config(initRound)
- setting = baRoundSetting{}
+ setting = &baRoundSetting{}
tickDuration time.Duration
+ ticker Ticker
)
// Check if this routine needs to awake in this round and prepare essential
// variables when yes.
- checkRound := func() (isNotary bool) {
+ checkRound := func() (isDKG bool) {
defer func() {
currentRound = nextRound
nextRound++
}()
// Wait until the configuartion for next round is ready.
for {
- if curConfig = mgr.config(nextRound); curConfig != nil {
+ if setting = mgr.generateSetting(nextRound); setting != nil {
break
} else {
mgr.logger.Debug("Round is not ready", "round", nextRound)
time.Sleep(1 * time.Second)
}
}
- // Check if this node in notary set of this chain in this round.
- notarySet, err := mgr.cache.GetNotarySet(nextRound)
- if err != nil {
- panic(err)
- }
- setting.crs = curConfig.crs
- setting.notarySet = notarySet
- _, isNotary = setting.notarySet[mgr.ID]
- if isNotary {
- mgr.logger.Info("Selected as notary set",
+ _, isDKG = setting.dkgSet[mgr.ID]
+ if isDKG {
+ mgr.logger.Info("Selected as dkg set",
"ID", mgr.ID,
"round", nextRound)
} else {
- mgr.logger.Info("Not selected as notary set",
+ mgr.logger.Info("Not selected as dkg set",
"ID", mgr.ID,
"round", nextRound)
}
// Setup ticker
if tickDuration != curConfig.lambdaBA {
- if setting.ticker != nil {
- setting.ticker.Stop()
+ if ticker != nil {
+ ticker.Stop()
}
- setting.ticker = newTicker(mgr.gov, nextRound, TickerBA)
+ ticker = newTicker(mgr.gov, nextRound, TickerBA)
tickDuration = curConfig.lambdaBA
}
+ setting.ticker = ticker
return
}
Loop:
@@ -395,15 +432,25 @@ Loop:
}
mgr.recv.isNotary = checkRound()
// Run BA for this round.
- mgr.recv.updateRound(currentRound)
- mgr.recv.changeNotaryHeightValue.Store(curConfig.RoundEndHeight())
mgr.recv.restartNotary <- types.Position{
- Round: mgr.recv.round(),
+ Round: currentRound,
Height: math.MaxUint64,
}
mgr.voteFilter = utils.NewVoteFilter()
mgr.recv.emptyBlockHashMap = &sync.Map{}
- if err := mgr.baRoutineForOneRound(&setting); err != nil {
+ if currentRound >= DKGDelayRound && mgr.recv.isNotary {
+ var err error
+ mgr.recv.npks, mgr.recv.psigSigner, err =
+ mgr.con.cfgModule.getDKGInfo(currentRound, false)
+ if err != nil {
+ mgr.logger.Warn("cannot get dkg info",
+ "round", currentRound, "error", err)
+ }
+ } else {
+ mgr.recv.npks = nil
+ mgr.recv.psigSigner = nil
+ }
+ if err := mgr.baRoutineForOneRound(setting); err != nil {
mgr.logger.Error("BA routine failed",
"error", err,
"nodeID", mgr.ID)
@@ -419,7 +466,7 @@ func (mgr *agreementMgr) baRoutineForOneRound(
oldPos := agr.agreementID()
restart := func(restartPos types.Position) (breakLoop bool, err error) {
if !isStop(restartPos) {
- if restartPos.Round > oldPos.Round {
+ if restartPos.Height+1 >= mgr.config(setting.round).RoundEndHeight() {
for {
select {
case <-mgr.ctx.Done():
@@ -427,14 +474,12 @@ func (mgr *agreementMgr) baRoutineForOneRound(
default:
}
tipRound := mgr.bcModule.tipRound()
- if tipRound > restartPos.Round {
- // It's a vary rare that this go routine sleeps for entire round.
+ if tipRound > setting.round {
break
- } else if tipRound != restartPos.Round {
- mgr.logger.Debug("Waiting blockChain to change round...",
- "pos", restartPos)
} else {
- break
+ mgr.logger.Debug("Waiting blockChain to change round...",
+ "curRound", setting.round,
+ "tipRound", tipRound)
}
time.Sleep(100 * time.Millisecond)
}
@@ -459,9 +504,6 @@ func (mgr *agreementMgr) baRoutineForOneRound(
default:
}
nextHeight, nextTime = mgr.bcModule.nextBlock()
- if isStop(oldPos) && nextHeight == 0 {
- break
- }
if isStop(restartPos) {
break
}
@@ -473,18 +515,18 @@ func (mgr *agreementMgr) baRoutineForOneRound(
time.Sleep(100 * time.Millisecond)
}
nextPos := types.Position{
- Round: recv.round(),
+ Round: setting.round,
Height: nextHeight,
}
oldPos = nextPos
var leader types.NodeID
- leader, err = mgr.cache.GetLeaderNode(nextPos)
+ leader, err = mgr.calcLeader(setting.dkgSet, setting.crs, nextPos)
if err != nil {
return
}
time.Sleep(nextTime.Sub(time.Now()))
setting.ticker.Restart()
- agr.restart(setting.notarySet, nextPos, leader, setting.crs)
+ agr.restart(setting.dkgSet, setting.threshold, nextPos, leader, setting.crs)
return
}
Loop:
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 f2a9e3def..b122a4ddf 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/agreement.go
@@ -160,7 +160,8 @@ func newAgreement(
// restart the agreement
func (a *agreement) restart(
- notarySet map[types.NodeID]struct{}, aID types.Position, leader types.NodeID,
+ notarySet map[types.NodeID]struct{},
+ threshold int, aID types.Position, leader types.NodeID,
crs common.Hash) {
if !func() bool {
a.lock.Lock()
@@ -181,7 +182,7 @@ func (a *agreement) restart(
a.data.votes[1] = newVoteListMap()
a.data.period = 2
a.data.blocks = make(map[types.NodeID]*types.Block)
- a.data.requiredVote = len(notarySet)*2/3 + 1
+ a.data.requiredVote = threshold
a.data.leader.restart(crs)
a.data.lockValue = types.SkipBlockHash
a.data.lockIter = 0
@@ -289,9 +290,11 @@ func (a *agreement) restart(
}
func (a *agreement) stop() {
- a.restart(make(map[types.NodeID]struct{}), types.Position{
- Height: math.MaxUint64,
- }, types.NodeID{}, common.Hash{})
+ a.restart(make(map[types.NodeID]struct{}), int(math.MaxInt32),
+ types.Position{
+ Height: math.MaxUint64,
+ },
+ types.NodeID{}, common.Hash{})
}
func isStop(aID types.Position) bool {
@@ -399,6 +402,9 @@ func (a *agreement) prepareVote(vote *types.Vote) (err error) {
}
func (a *agreement) updateFilter(filter *utils.VoteFilter) {
+ if isStop(a.agreementID()) {
+ return
+ }
a.lock.RLock()
defer a.lock.RUnlock()
a.data.lock.RLock()
@@ -417,6 +423,7 @@ func (a *agreement) processVote(vote *types.Vote) error {
return err
}
aID := a.agreementID()
+
// Agreement module has stopped.
if isStop(aID) {
// Hacky way to not drop first votes for genesis height.
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
index 2d67d626f..9fbb86162 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/blockchain.go
@@ -137,11 +137,14 @@ type blockChain struct {
vGetter tsigVerifierGetter
app Application
logger common.Logger
- pendingRandomnesses map[types.Position]*types.AgreementResult
+ pendingRandomnesses map[types.Position][]byte
configs []blockChainConfig
pendingBlocks pendingBlockRecords
confirmedBlocks types.BlocksByPosition
dMoment time.Time
+
+ // Do not access this variable besides processAgreementResult.
+ lastPosition types.Position
}
func newBlockChain(nID types.NodeID, dMoment time.Time, initBlock *types.Block,
@@ -157,7 +160,7 @@ func newBlockChain(nID types.NodeID, dMoment time.Time, initBlock *types.Block,
logger: logger,
dMoment: dMoment,
pendingRandomnesses: make(
- map[types.Position]*types.AgreementResult),
+ map[types.Position][]byte),
}
}
@@ -629,10 +632,7 @@ func (bc *blockChain) confirmBlock(b *types.Block) {
func (bc *blockChain) setRandomnessFromPending(b *types.Block) bool {
if r, exist := bc.pendingRandomnesses[b.Position]; exist {
- if !r.BlockHash.Equal(b.Hash) {
- panic(fmt.Errorf("mismathed randomness: %s %s", b, r))
- }
- b.Randomness = r.Randomness
+ b.Randomness = r
delete(bc.pendingRandomnesses, b.Position)
return true
}
@@ -643,6 +643,9 @@ func (bc *blockChain) processAgreementResult(result *types.AgreementResult) erro
if result.Position.Round < DKGDelayRound {
return nil
}
+ if !result.Position.Newer(bc.lastPosition) {
+ return ErrSkipButNoError
+ }
ok, err := bc.verifyRandomness(
result.BlockHash, result.Position.Round, result.Randomness)
if err != nil {
@@ -656,6 +659,19 @@ func (bc *blockChain) processAgreementResult(result *types.AgreementResult) erro
if !result.Position.Newer(bc.lastDelivered.Position) {
return nil
}
- bc.pendingRandomnesses[result.Position] = result
+ bc.pendingRandomnesses[result.Position] = result.Randomness
+ bc.lastPosition = bc.lastDelivered.Position
return nil
}
+
+func (bc *blockChain) addBlockRandomness(pos types.Position, rand []byte) {
+ if pos.Round < DKGDelayRound {
+ return
+ }
+ bc.lock.Lock()
+ defer bc.lock.Unlock()
+ if !pos.Newer(bc.lastDelivered.Position) {
+ return
+ }
+ bc.pendingRandomnesses[pos] = rand
+}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go
index c8aac38bc..fbd504d24 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/configuration-chain.go
@@ -586,8 +586,19 @@ func (cc *configurationChain) recoverDKGInfo(
// Restore group public key.
cc.logger.Debug("Calling Governance.DKGMasterPublicKeys for recoverDKGInfo",
"round", round)
+ mpk := cc.gov.DKGMasterPublicKeys(round)
cc.logger.Debug("Calling Governance.DKGComplaints for recoverDKGInfo",
"round", round)
+ comps := cc.gov.DKGComplaints(round)
+ qualifies, _, err := typesDKG.CalcQualifyNodes(mpk, comps, threshold)
+ if err != nil {
+ return err
+ }
+ if len(qualifies) <
+ utils.GetDKGValidThreshold(utils.GetConfigWithPanic(
+ cc.gov, round, cc.logger)) {
+ return typesDKG.ErrNotReachThreshold
+ }
npks, err := typesDKG.NewNodePublicKeys(round,
cc.gov.DKGMasterPublicKeys(round),
cc.gov.DKGComplaints(round),
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
index 57b30383c..e657c6449 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go
@@ -22,7 +22,6 @@ import (
"encoding/hex"
"fmt"
"sync"
- "sync/atomic"
"time"
"github.com/dexon-foundation/dexon-consensus/common"
@@ -60,23 +59,13 @@ var (
// consensusBAReceiver implements agreementReceiver.
type consensusBAReceiver struct {
- consensus *Consensus
- agreementModule *agreement
- changeNotaryHeightValue *atomic.Value
- roundValue *atomic.Value
- emptyBlockHashMap *sync.Map
- isNotary bool
- restartNotary chan types.Position
- npks *typesDKG.NodePublicKeys
- psigSigner *dkgShareSecret
-}
-
-func (recv *consensusBAReceiver) round() uint64 {
- return recv.roundValue.Load().(uint64)
-}
-
-func (recv *consensusBAReceiver) changeNotaryHeight() uint64 {
- return recv.changeNotaryHeightValue.Load().(uint64)
+ consensus *Consensus
+ agreementModule *agreement
+ emptyBlockHashMap *sync.Map
+ isNotary bool
+ restartNotary chan types.Position
+ npks *typesDKG.NodePublicKeys
+ psigSigner *dkgShareSecret
}
func (recv *consensusBAReceiver) emptyBlockHash(pos types.Position) (
@@ -99,17 +88,13 @@ func (recv *consensusBAReceiver) emptyBlockHash(pos types.Position) (
}
func (recv *consensusBAReceiver) VerifyPartialSignature(vote *types.Vote) bool {
- if recv.round() >= DKGDelayRound && vote.BlockHash != types.SkipBlockHash {
+ if vote.Position.Round >= DKGDelayRound && vote.BlockHash != types.SkipBlockHash {
if vote.Type == types.VoteCom || vote.Type == types.VoteFastCom {
- if recv.npks == nil || recv.npks.Round != vote.Position.Round {
- var err error
- recv.npks, _, err =
- recv.consensus.cfgModule.getDKGInfo(vote.Position.Round, true)
- if err != nil || recv.npks == nil {
- recv.consensus.logger.Warn("cannot get npks",
- "round", vote.Position.Round, "error", err)
- return false
- }
+ if recv.npks == nil {
+ return false
+ }
+ if vote.Position.Round != recv.npks.Round {
+ return false
}
pubKey, exist := recv.npks.PublicKeys[vote.ProposerID]
if !exist {
@@ -138,11 +123,9 @@ func (recv *consensusBAReceiver) ProposeVote(vote *types.Vote) {
if !recv.isNotary {
return
}
- if recv.round() >= DKGDelayRound && vote.BlockHash != types.SkipBlockHash {
+ if recv.psigSigner != nil &&
+ vote.BlockHash != types.SkipBlockHash {
if vote.Type == types.VoteCom || vote.Type == types.VoteFastCom {
- if recv.psigSigner == nil {
- return
- }
if vote.BlockHash == types.NullBlockHash {
hash, err := recv.emptyBlockHash(vote.Position)
if err != nil {
@@ -272,7 +255,7 @@ func (recv *consensusBAReceiver) ConfirmBlock(
if vote.BlockHash != hash {
continue
}
- if recv.round() >= DKGDelayRound {
+ if block.Position.Round >= DKGDelayRound {
ID, exist := recv.npks.IDMap[vote.ProposerID]
if !exist {
continue
@@ -282,7 +265,7 @@ func (recv *consensusBAReceiver) ConfirmBlock(
}
voteList = append(voteList, *vote)
}
- if recv.round() >= DKGDelayRound {
+ if block.Position.Round >= DKGDelayRound {
rand, err := cryptoDKG.RecoverSignature(psigs, IDs)
if err != nil {
recv.consensus.logger.Warn("Unable to recover randomness",
@@ -303,17 +286,13 @@ func (recv *consensusBAReceiver) ConfirmBlock(
IsEmptyBlock: isEmptyBlockConfirmed,
Randomness: block.Randomness,
}
+ recv.consensus.baMgr.touchAgreementResult(result)
recv.consensus.logger.Debug("Broadcast AgreementResult",
"result", result)
recv.consensus.network.BroadcastAgreementResult(result)
if block.IsEmpty() {
- if err :=
- recv.consensus.bcModule.processAgreementResult(
- result); err != nil {
- recv.consensus.logger.Warn(
- "Failed to process agreement result",
- "result", result)
- }
+ recv.consensus.bcModule.addBlockRandomness(
+ block.Position, block.Randomness)
}
if block.Position.Round >= DKGDelayRound {
recv.consensus.logger.Debug(
@@ -385,23 +364,7 @@ CleanChannelLoop:
break CleanChannelLoop
}
}
- newPos := block.Position
- changeNotaryHeight := recv.changeNotaryHeight()
- if block.Position.Height+1 >= changeNotaryHeight {
- recv.consensus.logger.Info("Round will change",
- "block", block,
- "change-height", changeNotaryHeight)
- newPos.Round++
- recv.updateRound(newPos.Round)
- }
- currentRound := recv.round()
- if block.Position.Height > changeNotaryHeight &&
- block.Position.Round < currentRound {
- panic(fmt.Errorf(
- "round not switch when confirming: %s, %d, should switch at %d, %s",
- block, currentRound, changeNotaryHeight, newPos))
- }
- recv.restartNotary <- newPos
+ recv.restartNotary <- block.Position
}
func (recv *consensusBAReceiver) PullBlocks(hashes common.Hashes) {
@@ -420,18 +383,6 @@ func (recv *consensusBAReceiver) ReportForkBlock(b1, b2 *types.Block) {
recv.consensus.gov.ReportForkBlock(b1, b2)
}
-func (recv *consensusBAReceiver) updateRound(round uint64) {
- recv.roundValue.Store(round)
- var err error
- _, recv.psigSigner, err =
- recv.consensus.cfgModule.getDKGInfo(round, false)
- if err != nil {
- recv.consensus.logger.Warn("cannot get dkg info",
- "round", round, "error", err)
- recv.psigSigner = nil
- }
-}
-
// consensusDKGReceiver implements dkgReceiver.
type consensusDKGReceiver struct {
ID types.NodeID
@@ -774,12 +725,13 @@ func (con *Consensus) prepare(initBlock *types.Block) (err error) {
// modules see the up-to-date node set, we need to make sure this action
// should be taken as the first one.
con.roundEvent.Register(func(evts []utils.RoundEventParam) {
- defer elapse("purge-node-set", evts[len(evts)-1])()
+ defer elapse("purge-cache", evts[len(evts)-1])()
for _, e := range evts {
if e.Reset == 0 {
continue
}
con.nodeSetCache.Purge(e.Round + 1)
+ con.tsigVerifierCache.Purge(e.Round + 1)
}
})
// Register round event handler to abort previous running DKG if any.
@@ -895,13 +847,64 @@ func (con *Consensus) prepare(initBlock *types.Block) (err error) {
e := evts[len(evts)-1]
defer elapse("touch-NodeSetCache", e)()
con.event.RegisterHeight(e.NextTouchNodeSetCacheHeight(), func(uint64) {
- if err := con.nodeSetCache.Touch(e.Round + 1); err != nil {
- con.logger.Warn("Failed to update nodeSetCache",
- "round", e.Round+1,
- "error", err)
+ if e.Reset == 0 {
+ return
}
+ go func() {
+ nextRound := e.Round + 1
+ if err := con.nodeSetCache.Touch(nextRound); err != nil {
+ con.logger.Warn("Failed to update nodeSetCache",
+ "round", nextRound,
+ "error", err)
+ }
+ }()
})
})
+ con.roundEvent.Register(func(evts []utils.RoundEventParam) {
+ e := evts[len(evts)-1]
+ if e.Reset != 0 {
+ return
+ }
+ defer elapse("touch-DKGCache", e)()
+ go func() {
+ if _, err :=
+ con.tsigVerifierCache.Update(e.Round); err != nil {
+ con.logger.Warn("Failed to update tsig cache",
+ "round", e.Round,
+ "error", err)
+ }
+ }()
+ go func() {
+ threshold := utils.GetDKGThreshold(
+ utils.GetConfigWithPanic(con.gov, e.Round, con.logger))
+ // Restore group public key.
+ con.logger.Debug(
+ "Calling Governance.DKGMasterPublicKeys for recoverDKGInfo",
+ "round", e.Round)
+ con.logger.Debug(
+ "Calling Governance.DKGComplaints for recoverDKGInfo",
+ "round", e.Round)
+ _, qualifies, err := typesDKG.CalcQualifyNodes(
+ con.gov.DKGMasterPublicKeys(e.Round),
+ con.gov.DKGComplaints(e.Round),
+ threshold)
+ if err != nil {
+ con.logger.Warn("Failed to calculate dkg set",
+ "round", e.Round,
+ "error", err)
+ return
+ }
+ if _, exist := qualifies[con.ID]; !exist {
+ return
+ }
+ if _, _, err :=
+ con.cfgModule.getDKGInfo(e.Round, true); err != nil {
+ con.logger.Warn("Failed to recover DKG info",
+ "round", e.Round,
+ "error", err)
+ }
+ }()
+ })
// checkCRS is a generator of checker to check if CRS for that round is
// ready or not.
checkCRS := func(round uint64) func() bool {
@@ -1090,12 +1093,7 @@ func (con *Consensus) generateBlockRandomness(blocks []*types.Block) {
Position: block.Position,
Randomness: sig.Signature[:],
}
- if err := con.bcModule.processAgreementResult(result); err != nil {
- con.logger.Error("Failed to process BlockRandomness",
- "result", result,
- "error", err)
- return
- }
+ con.bcModule.addBlockRandomness(block.Position, sig.Signature[:])
con.logger.Debug("Broadcast BlockRandomness",
"block", block,
"result", result)
@@ -1320,8 +1318,7 @@ MessageLoop:
// ProcessVote is the entry point to submit ont vote to a Consensus instance.
func (con *Consensus) ProcessVote(vote *types.Vote) (err error) {
- v := vote.Clone()
- err = con.baMgr.processVote(v)
+ err = con.baMgr.processVote(vote)
return
}
@@ -1338,6 +1335,9 @@ func (con *Consensus) ProcessAgreementResult(
}
if err := con.bcModule.processAgreementResult(rand); err != nil {
con.baMgr.untouchAgreementResult(rand)
+ if err == ErrSkipButNoError {
+ return nil
+ }
return err
}
// Syncing BA Module.
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go
index 9a71bea1f..e4ae14c2c 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/dkg-tsig-protocol.go
@@ -555,7 +555,7 @@ func (tc *TSigVerifierCache) UpdateAndGet(round uint64) (
return v, ok, nil
}
-// Purge the cache and returns if success.
+// Purge the cache.
func (tc *TSigVerifierCache) Purge(round uint64) {
tc.lock.Lock()
defer tc.lock.Unlock()
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
index cff954652..1dcd41b9e 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/block.go
@@ -83,7 +83,7 @@ type Block struct {
Payload []byte `json:"payload"`
PayloadHash common.Hash `json:"payload_hash"`
Witness Witness `json:"witness"`
- Randomness []byte `json:"finalization"`
+ Randomness []byte `json:"randomness"`
Signature crypto.Signature `json:"signature"`
CRSSignature crypto.Signature `json:"crs_signature"`
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
index 301cef7da..e9b22bcb0 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/types/dkg/dkg.go
@@ -345,7 +345,7 @@ func CalcQualifyNodes(
}
}
for nID, complaints := range complaintsByID {
- if len(complaints) > threshold {
+ if len(complaints) >= threshold {
disqualifyIDs[nID] = struct{}{}
}
}
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go
index 89ebd2409..89dcfc86b 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/nodeset-cache.go
@@ -36,10 +36,9 @@ var (
)
type sets struct {
- crs common.Hash
- nodeSet *types.NodeSet
- notarySet map[types.NodeID]struct{}
- leaderNode map[uint64]types.NodeID
+ crs common.Hash
+ nodeSet *types.NodeSet
+ notarySet map[types.NodeID]struct{}
}
// NodeSetCacheInterface interface specifies interface used by NodeSetCache.
@@ -133,30 +132,6 @@ func (cache *NodeSetCache) GetNotarySet(
return cache.cloneMap(IDs.notarySet), nil
}
-// GetLeaderNode returns the BA leader of the position.
-func (cache *NodeSetCache) GetLeaderNode(pos types.Position) (
- types.NodeID, error) {
- IDs, err := cache.getOrUpdate(pos.Round)
- if err != nil {
- return types.NodeID{}, err
- }
- cache.lock.Lock()
- defer cache.lock.Unlock()
- if _, exist := IDs.leaderNode[pos.Height]; !exist {
- notarySet := types.NewNodeSetFromMap(IDs.notarySet)
- leader := notarySet.GetSubSet(1, types.NewNodeLeaderTarget(
- IDs.crs, pos.Height))
- if len(leader) != 1 {
- panic(errors.New("length of leader is not one"))
- }
- for nID := range leader {
- IDs.leaderNode[pos.Height] = nID
- break
- }
- }
- return IDs.leaderNode[pos.Height], nil
-}
-
// Purge a specific round.
func (cache *NodeSetCache) Purge(rID uint64) {
cache.lock.Lock()
@@ -238,10 +213,9 @@ func (cache *NodeSetCache) update(round uint64) (nIDs *sets, err error) {
return
}
nIDs = &sets{
- crs: crs,
- nodeSet: nodeSet,
- notarySet: make(map[types.NodeID]struct{}),
- leaderNode: make(map[uint64]types.NodeID, cfg.RoundLength),
+ crs: crs,
+ nodeSet: nodeSet,
+ notarySet: make(map[types.NodeID]struct{}),
}
nIDs.notarySet = nodeSet.GetSubSet(
int(cfg.NotarySetSize), types.NewNotarySetTarget(crs))
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go
index 472c7247b..602d2da16 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/round-event.go
@@ -79,7 +79,7 @@ func (e RoundEventParam) NextRoundHeight() uint64 {
// NextTouchNodeSetCacheHeight returns the height to touch the node set cache.
func (e RoundEventParam) NextTouchNodeSetCacheHeight() uint64 {
- return e.BeginHeight + e.Config.RoundLength*9/10
+ return e.BeginHeight + e.Config.RoundLength/2
}
// NextDKGResetHeight returns the height to reset DKG for next period.
diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
index e6739ce2b..1a372c70c 100644
--- a/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
+++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/utils/utils.go
@@ -144,6 +144,11 @@ func GetDKGValidThreshold(config *types.Config) int {
return int(config.NotarySetSize * 5 / 6)
}
+// GetBAThreshold return threshold for BA votes.
+func GetBAThreshold(config *types.Config) int {
+ return int(config.NotarySetSize*2/3 + 1)
+}
+
// GetNextRoundValidationHeight returns the block height to check if the next
// round is ready.
func GetNextRoundValidationHeight(begin, length uint64) uint64 {
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 4ad0a8c6c..f6e974cdd 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -141,16 +141,16 @@
{
"checksumSHA1": "In6vBHYUsX7DUIGiFN2hQggBgvI=",
"path": "github.com/dexon-foundation/dexon-consensus/common",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "fE4+Jlw+2y4JJMHtGuHxHWqqPfY=",
+ "checksumSHA1": "iFSmNrfc8OsbwuZtqF1njr6MPp0=",
"path": "github.com/dexon-foundation/dexon-consensus/core",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
@@ -165,64 +165,64 @@
{
"checksumSHA1": "tQSbYCu5P00lUhKsx3IbBZCuSLY=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "mMdctxTa/jNwAwZjjYoyEZdLoF8=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/dkg",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "BhLKK8RveoLaeXc9UyUKMwQqchU=",
"path": "github.com/dexon-foundation/dexon-consensus/core/crypto/ecdsa",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "hj/KetWUHp+1CX+50V0QnCthfWc=",
"path": "github.com/dexon-foundation/dexon-consensus/core/db",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
"checksumSHA1": "pxAzlI5kjyIAJSX+/aRGjjhR+pw=",
"path": "github.com/dexon-foundation/dexon-consensus/core/syncer",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "TmZF8DyrzGHTTfXXIFnKlzva3mU=",
+ "checksumSHA1": "zIgCdN4FJiAuPGMhB+/9YGK/Wgk=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "5BskQaPpK94/ecmvy845hwM6F+8=",
+ "checksumSHA1": "QVeatfLQUBE8/vwjvVImyQiTijE=",
"path": "github.com/dexon-foundation/dexon-consensus/core/types/dkg",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},
{
- "checksumSHA1": "pvJYiUy3EubRjeh5VYpt73Jjg1Q=",
+ "checksumSHA1": "YooeNHTYxH05Ky5vnoyZsQR4/08=",
"path": "github.com/dexon-foundation/dexon-consensus/core/utils",
- "revision": "b11406ecd961bc26f4382e06c8061708a58063e0",
- "revisionTime": "2019-04-01T11:36:40Z",
+ "revision": "37bb1f320bbdd7ef1a33d400a3ea6b67e301a135",
+ "revisionTime": "2019-04-02T11:03:14Z",
"version": "single-chain",
"versionExact": "single-chain"
},