From eb6401eaf5890e35260d555a08f4728f576a2464 Mon Sep 17 00:00:00 2001 From: Jimmy Hu Date: Fri, 29 Mar 2019 15:20:03 +0800 Subject: vendor: sync to latest core --- .../dexon-consensus/core/configuration-chain.go | 115 ++++++++++++--------- .../dexon-consensus/core/consensus.go | 24 +++-- .../dexon-consensus/core/syncer/agreement.go | 12 ++- .../dexon-consensus/core/utils/utils.go | 5 + 4 files changed, 98 insertions(+), 58 deletions(-) (limited to 'vendor/github.com') 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 92b283098..c8aac38bc 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 @@ -406,17 +406,6 @@ func (cc *configurationChain) runDKGPhaseNine(round uint64, reset uint64) error return nil } -func (cc *configurationChain) runTick(ticker Ticker) (aborted bool) { - cc.dkgLock.Unlock() - defer cc.dkgLock.Lock() - select { - case <-cc.dkgCtx.Done(): - aborted = true - case <-ticker.Tick(): - } - return -} - func (cc *configurationChain) initDKGPhasesFunc() { cc.dkgRunPhases = []dkgStepFn{ func(round uint64, reset uint64) error { @@ -448,7 +437,18 @@ func (cc *configurationChain) initDKGPhasesFunc() { } } -func (cc *configurationChain) runDKG(round uint64, reset uint64) (err error) { +func (cc *configurationChain) runDKG( + round uint64, reset uint64, event *common.Event, + dkgBeginHeight, dkgHeight uint64) (err error) { + // Check if corresponding DKG signer is ready. + if _, _, err = cc.getDKGInfo(round, false); err == nil { + return ErrSkipButNoError + } + cfg := utils.GetConfigWithPanic(cc.gov, round, cc.logger) + phaseHeight := uint64( + cfg.LambdaDKG.Nanoseconds() / cfg.MinBlockInterval.Nanoseconds()) + skipPhase := int(dkgHeight / phaseHeight) + cc.logger.Info("Skipping DKG phase", "phase", skipPhase) cc.dkgLock.Lock() defer cc.dkgLock.Unlock() if cc.dkg == nil { @@ -467,51 +467,70 @@ func (cc *configurationChain) runDKG(round uint64, reset uint64) (err error) { panic(fmt.Errorf("duplicated call to runDKG: %d %d", round, reset)) } cc.dkgRunning = true - var ticker Ticker defer func() { - if ticker != nil { - ticker.Stop() - } // Here we should hold the cc.dkgLock, reset cc.dkg to nil when done. if cc.dkg != nil { cc.dkg = nil } cc.dkgRunning = false }() - // Check if corresponding DKG signer is ready. - if _, _, err = cc.getDKGInfo(round, true); err == nil { - return ErrSkipButNoError + wg := sync.WaitGroup{} + var dkgError error + // Make a copy of cc.dkgCtx so each phase function can refer to the correct + // context. + ctx := cc.dkgCtx + cc.dkg.step = skipPhase + for i := skipPhase; i < len(cc.dkgRunPhases); i++ { + wg.Add(1) + event.RegisterHeight(dkgBeginHeight+phaseHeight*uint64(i), func(uint64) { + go func() { + defer wg.Done() + cc.dkgLock.Lock() + defer cc.dkgLock.Unlock() + if dkgError != nil { + return + } + select { + case <-ctx.Done(): + dkgError = ErrDKGAborted + return + default: + } + + err := cc.dkgRunPhases[cc.dkg.step](round, reset) + if err == nil || err == ErrSkipButNoError { + err = nil + cc.dkg.step++ + err = cc.db.PutOrUpdateDKGProtocol(cc.dkg.toDKGProtocolInfo()) + if err != nil { + cc.logger.Error("Failed to save DKG Protocol", + "step", cc.dkg.step, + "error", err) + } + } + if err != nil && dkgError == nil { + dkgError = err + } + }() + }) } - tickStartAt := 1 - - for i := cc.dkg.step; i < len(cc.dkgRunPhases); i++ { - if i >= tickStartAt && ticker == nil { - ticker = newTicker(cc.gov, round, TickerDKG) - } - - if ticker != nil && cc.runTick(ticker) { - return - } - - switch err = cc.dkgRunPhases[i](round, reset); err { - case ErrSkipButNoError, nil: - cc.dkg.step = i + 1 - err = cc.db.PutOrUpdateDKGProtocol(cc.dkg.toDKGProtocolInfo()) - if err != nil { - return fmt.Errorf("put or update DKG protocol error: %v", err) - } - - if err == nil { - continue - } else { - return - } - default: - return - } + cc.dkgLock.Unlock() + wgChan := make(chan struct{}, 1) + go func() { + wg.Wait() + wgChan <- struct{}{} + }() + select { + case <-cc.dkgCtx.Done(): + case <-wgChan: } - - return nil + cc.dkgLock.Lock() + select { + case <-cc.dkgCtx.Done(): + return ErrDKGAborted + default: + } + return dkgError } func (cc *configurationChain) isDKGFinal(round uint64) bool { 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 6d0f68377..6e3072371 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/consensus.go @@ -849,17 +849,21 @@ func (con *Consensus) prepare(initBlock *types.Block) (err error) { "reset", e.Reset) return false } - if _, err := typesDKG.NewGroupPublicKey( + gpk, err := typesDKG.NewGroupPublicKey( nextRound, con.gov.DKGMasterPublicKeys(nextRound), con.gov.DKGComplaints(nextRound), - utils.GetDKGThreshold(nextConfig)); err != nil { + utils.GetDKGThreshold(nextConfig)) + if err != nil { con.logger.Error("Next DKG failed to prepare, reset it", "round", e.Round, "reset", e.Reset, "error", err) return false } + if len(gpk.QualifyNodeIDs) < utils.GetDKGValidThreshold(nextConfig) { + return false + } return true } con.event.RegisterHeight(e.NextDKGResetHeight(), func(uint64) { @@ -976,13 +980,17 @@ func (con *Consensus) prepare(initBlock *types.Block) (err error) { con.cfgModule.registerDKG(con.ctx, nextRound, e.Reset, utils.GetDKGThreshold(nextConfig)) con.event.RegisterHeight(e.NextDKGPreparationHeight(), - func(uint64) { + func(h uint64) { func() { con.dkgReady.L.Lock() defer con.dkgReady.L.Unlock() con.dkgRunning = 0 }() - con.runDKG(nextRound, e.Reset, nextConfig) + // We want to skip some of the DKG phases when started. + dkgCurrentHeight := h - e.NextDKGPreparationHeight() + con.runDKG( + nextRound, e.Reset, + e.NextDKGPreparationHeight(), dkgCurrentHeight) }) }() }) @@ -1114,7 +1122,8 @@ func (con *Consensus) generateBlockRandomness(blocks []*types.Block) { } // runDKG starts running DKG protocol. -func (con *Consensus) runDKG(round, reset uint64, config *types.Config) { +func (con *Consensus) runDKG( + round, reset, dkgBeginHeight, dkgHeight uint64) { con.dkgReady.L.Lock() defer con.dkgReady.L.Unlock() if con.dkgRunning != 0 { @@ -1128,7 +1137,10 @@ func (con *Consensus) runDKG(round, reset uint64, config *types.Config) { con.dkgReady.Broadcast() con.dkgRunning = 2 }() - if err := con.cfgModule.runDKG(round, reset); err != nil { + if err := + con.cfgModule.runDKG( + round, reset, + con.event, dkgBeginHeight, dkgHeight); err != nil { con.logger.Error("Failed to runDKG", "error", err) } }() diff --git a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go index a4a0f2023..13da027bd 100644 --- a/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go +++ b/vendor/github.com/dexon-foundation/dexon-consensus/core/syncer/agreement.go @@ -39,7 +39,7 @@ type agreement struct { outputChan chan<- *types.Block pullChan chan<- common.Hash blocks map[types.Position]map[common.Hash]*types.Block - agreementResults map[common.Hash]struct{} + agreementResults map[common.Hash][]byte latestCRSRound uint64 pendingAgrs map[uint64]map[common.Hash]*types.AgreementResult pendingBlocks map[uint64]map[common.Hash]*types.Block @@ -62,7 +62,7 @@ func newAgreement(chainTip uint64, outputChan: ch, pullChan: pullChan, blocks: make(map[types.Position]map[common.Hash]*types.Block), - agreementResults: make(map[common.Hash]struct{}), + agreementResults: make(map[common.Hash][]byte), logger: logger, pendingAgrs: make( map[uint64]map[common.Hash]*types.AgreementResult), @@ -105,7 +105,11 @@ func (a *agreement) processBlock(b *types.Block) { if _, exist := a.confirmedBlocks[b.Hash]; exist { return } - if _, exist := a.agreementResults[b.Hash]; exist { + if rand, exist := a.agreementResults[b.Hash]; exist { + if b.Position.Round >= core.DKGDelayRound && + len(b.Finalization.Randomness) == 0 { + b.Finalization.Randomness = rand + } a.confirm(b) } else { if _, exist := a.blocks[b.Position]; !exist { @@ -219,7 +223,7 @@ func (a *agreement) processAgreementResult(r *types.AgreementResult) { return } } - a.agreementResults[r.BlockHash] = struct{}{} + a.agreementResults[r.BlockHash] = r.Randomness loop: for { select { 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 fcdf4224e..9a4ae923b 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 @@ -139,6 +139,11 @@ func GetDKGThreshold(config *types.Config) int { return int(config.NotarySetSize*2/3) + 1 } +// GetDKGValidThreshold return threshold for DKG set to considered valid. +func GetDKGValidThreshold(config *types.Config) int { + return int(config.NotarySetSize * 5 / 6) +} + // GetNextRoundValidationHeight returns the block height to check if the next // round is ready. func GetNextRoundValidationHeight(begin, length uint64) uint64 { -- cgit