diff options
-rw-r--r-- | core/consensus.go | 14 | ||||
-rw-r--r-- | core/consensus_test.go | 9 | ||||
-rw-r--r-- | core/interfaces.go | 14 | ||||
-rw-r--r-- | core/test/governance.go | 36 | ||||
-rw-r--r-- | core/ticker.go | 58 | ||||
-rw-r--r-- | integration_test/utils.go | 4 | ||||
-rw-r--r-- | integration_test/validator.go | 3 | ||||
-rw-r--r-- | simulation/config/config.go | 4 | ||||
-rw-r--r-- | simulation/governance.go | 8 | ||||
-rw-r--r-- | simulation/validator.go | 16 |
10 files changed, 113 insertions, 53 deletions
diff --git a/core/consensus.go b/core/consensus.go index 5e56ab9..6f59638 100644 --- a/core/consensus.go +++ b/core/consensus.go @@ -124,7 +124,7 @@ type Consensus struct { ccModule *compactionChain db blockdb.BlockDatabase network Network - tick *time.Ticker + tickerObj Ticker prvKey crypto.PrivateKey sigToPub SigToPubFn lock sync.RWMutex @@ -138,7 +138,6 @@ func NewConsensus( gov Governance, db blockdb.BlockDatabase, network Network, - tick *time.Ticker, prv crypto.PrivateKey, sigToPub SigToPubFn) *Consensus { validatorSet := gov.GetValidatorSet() @@ -172,7 +171,7 @@ func NewConsensus( gov: gov, db: db, network: network, - tick: tick, + tickerObj: newTicker(gov), prvKey: prv, sigToPub: sigToPub, ctx: ctx, @@ -202,7 +201,6 @@ func NewConsensus( blockProposer, ) } - return con } @@ -216,10 +214,10 @@ func (con *Consensus) Run() { } go con.processMsg(con.network.ReceiveChan(), con.PreProcessBlock) // Reset ticker. - <-con.tick.C - <-con.tick.C + <-con.tickerObj.Tick() + <-con.tickerObj.Tick() for { - <-con.tick.C + <-con.tickerObj.Tick() for _, tick := range ticks { go func(tick chan struct{}) { tick <- struct{}{} }(tick) } @@ -302,7 +300,7 @@ func (con *Consensus) RunLegacy() { ProposingBlockLoop: for { select { - case <-con.tick.C: + case <-con.tickerObj.Tick(): case <-con.ctx.Done(): break ProposingBlockLoop } diff --git a/core/consensus_test.go b/core/consensus_test.go index 1e97993..e799675 100644 --- a/core/consensus_test.go +++ b/core/consensus_test.go @@ -83,8 +83,7 @@ func (s *ConsensusTestSuite) prepareConsensus( s.Require().Nil(err) prv, exist := gov.PrivateKeys[vID] s.Require().True(exist) - con := NewConsensus(app, gov, db, - &network{}, time.NewTicker(1), prv, eth.SigToPub) + con := NewConsensus(app, gov, db, &network{}, prv, eth.SigToPub) return &con.app, con } @@ -102,7 +101,7 @@ func (s *ConsensusTestSuite) TestSimpleDeliverBlock() { // This test case only works for Total Ordering with K=0. var ( minInterval = 50 * time.Millisecond - gov, err = test.NewGovernance(4, 1000) + gov, err = test.NewGovernance(4, time.Second) req = s.Require() validators []types.ValidatorID ) @@ -325,7 +324,7 @@ func (s *ConsensusTestSuite) TestPrepareBlock() { // - Make sure Consensus.PrepareBlock would only attempt to // ack the prepared block. var ( - gov, err = test.NewGovernance(4, 1000) + gov, err = test.NewGovernance(4, time.Second) req = s.Require() validators []types.ValidatorID ) @@ -381,7 +380,7 @@ func (s *ConsensusTestSuite) TestPrepareBlock() { func (s *ConsensusTestSuite) TestPrepareGenesisBlock() { var ( - gov, err = test.NewGovernance(4, 1000) + gov, err = test.NewGovernance(4, time.Second) validators []types.ValidatorID ) s.Require().Nil(err) diff --git a/core/interfaces.go b/core/interfaces.go index 68f210e..2b616ab 100644 --- a/core/interfaces.go +++ b/core/interfaces.go @@ -84,9 +84,6 @@ type Governance interface { // Get PhiRatio. GetPhiRatio() float32 - // Get block proposing interval (in milliseconds). - GetBlockProposingInterval() int - // Get Number of shards. GetNumShards() uint32 @@ -99,6 +96,9 @@ type Governance interface { // Get configuration change events after an epoch. GetConfigurationChangeEvent(epoch int) []types.ConfigurationChangeEvent + // Get lambda for BA. + GetLambda() time.Duration + // AddDKGComplaint adds a DKGComplaint. AddDKGComplaint(complaint *types.DKGComplaint) @@ -111,3 +111,11 @@ type Governance interface { // DKGMasterPublicKeys gets all the DKGMasterPublicKey of round. DKGMasterPublicKeys(round uint64) []*types.DKGMasterPublicKey } + +// Ticker define the capability to tick by interval. +type Ticker interface { + // Tick would return a channel, which would be triggered until next tick. + Tick() <-chan time.Time + // Stop the ticker. + Stop() +} diff --git a/core/test/governance.go b/core/test/governance.go index 64ca39f..1658e46 100644 --- a/core/test/governance.go +++ b/core/test/governance.go @@ -19,6 +19,7 @@ package test import ( "fmt" + "time" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/dexon-foundation/dexon-consensus-core/crypto" @@ -34,22 +35,22 @@ var ( // Governance is an implementation of Goverance for testing purpose. type Governance struct { - BlockProposingInterval int - Validators map[types.ValidatorID]decimal.Decimal - PrivateKeys map[types.ValidatorID]crypto.PrivateKey - DKGComplaint map[uint64][]*types.DKGComplaint - DKGMasterPublicKey map[uint64][]*types.DKGMasterPublicKey + Lambda time.Duration + Validators map[types.ValidatorID]decimal.Decimal + PrivateKeys map[types.ValidatorID]crypto.PrivateKey + DKGComplaint map[uint64][]*types.DKGComplaint + DKGMasterPublicKey map[uint64][]*types.DKGMasterPublicKey } // NewGovernance constructs a Governance instance. -func NewGovernance(validatorCount, proposingInterval int) ( +func NewGovernance(validatorCount int, lambda time.Duration) ( g *Governance, err error) { g = &Governance{ - BlockProposingInterval: proposingInterval, - Validators: make(map[types.ValidatorID]decimal.Decimal), - PrivateKeys: make(map[types.ValidatorID]crypto.PrivateKey), - DKGComplaint: make(map[uint64][]*types.DKGComplaint), - DKGMasterPublicKey: make(map[uint64][]*types.DKGMasterPublicKey), + Lambda: lambda, + Validators: make(map[types.ValidatorID]decimal.Decimal), + PrivateKeys: make(map[types.ValidatorID]crypto.PrivateKey), + DKGComplaint: make(map[uint64][]*types.DKGComplaint), + DKGMasterPublicKey: make(map[uint64][]*types.DKGMasterPublicKey), } for i := 0; i < validatorCount; i++ { prv, err := eth.NewPrivateKey() @@ -69,12 +70,6 @@ func (g *Governance) GetValidatorSet() map[types.ValidatorID]decimal.Decimal { return g.Validators } -// GetBlockProposingInterval implements Governance interface to return maximum -// allowed block proposing interval in millisecond. -func (g *Governance) GetBlockProposingInterval() int { - return g.BlockProposingInterval -} - // GetTotalOrderingK returns K. func (g *Governance) GetTotalOrderingK() int { return 0 @@ -107,8 +102,13 @@ func (g *Governance) GetGenesisCRS() string { return "🆕 DEXON" } +// GetLambda returns lambda for BA. +func (g *Governance) GetLambda() time.Duration { + return g.Lambda +} + // GetPrivateKey return the private key for that validator, this function -// is a test utility and not a general core.Governance interface. +// is a test utility and not a general Governance interface. func (g *Governance) GetPrivateKey( vID types.ValidatorID) (key crypto.PrivateKey, err error) { diff --git a/core/ticker.go b/core/ticker.go new file mode 100644 index 0000000..dffd676 --- /dev/null +++ b/core/ticker.go @@ -0,0 +1,58 @@ +// Copyright 2018 The dexon-consensus-core Authors +// This file is part of the dexon-consensus-core library. +// +// The dexon-consensus-core library is free software: you can redistribute it +// and/or modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the License, +// or (at your option) any later version. +// +// The dexon-consensus-core library is distributed in the hope that it will be +// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser +// General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the dexon-consensus-core library. If not, see +// <http://www.gnu.org/licenses/>. + +package core + +import "time" + +// defaultTicker is a wrapper to implement ticker interface based on +// time.Ticker. +type defaultTicker struct { + ticker *time.Ticker +} + +// newDefaultTicker constructs an defaultTicker instance by giving an interval. +func newDefaultTicker(lambda time.Duration) *defaultTicker { + return &defaultTicker{ticker: time.NewTicker(lambda)} +} + +// Tick implements Tick method of ticker interface. +func (t *defaultTicker) Tick() <-chan time.Time { + return t.ticker.C +} + +// Stop implements Stop method of ticker interface. +func (t *defaultTicker) Stop() { + t.ticker.Stop() +} + +// newTicker is a helper to setup a ticker by giving an Governance. If +// the governace object implements a ticker generator, a ticker from that +// generator would be returned, else constructs a default one. +func newTicker(gov Governance) (t Ticker) { + type tickerGenerator interface { + NewTicker() Ticker + } + + if gen, ok := gov.(tickerGenerator); ok { + t = gen.NewTicker() + } + if t == nil { + t = newDefaultTicker(gov.GetLambda()) + } + return +} diff --git a/integration_test/utils.go b/integration_test/utils.go index de7e6ab..57bb2bc 100644 --- a/integration_test/utils.go +++ b/integration_test/utils.go @@ -1,6 +1,8 @@ package integration import ( + "time" + "github.com/dexon-foundation/dexon-consensus-core/core/blockdb" "github.com/dexon-foundation/dexon-consensus-core/core/test" "github.com/dexon-foundation/dexon-consensus-core/core/types" @@ -25,7 +27,7 @@ func PrepareValidators( dbs = make(map[types.ValidatorID]blockdb.BlockDatabase) validators = make(map[types.ValidatorID]*Validator) - gov, err := test.NewGovernance(validatorCount, 700) + gov, err := test.NewGovernance(validatorCount, 700*time.Millisecond) if err != nil { return } diff --git a/integration_test/validator.go b/integration_test/validator.go index a110ab0..18e5c00 100644 --- a/integration_test/validator.go +++ b/integration_test/validator.go @@ -102,8 +102,7 @@ func NewValidator( networkLatency: networkLatency, proposingLatency: proposingLatency, cons: core.NewConsensus( - app, gov, - db, &Network{}, time.NewTicker(1), privateKey, eth.SigToPub), + app, gov, db, &Network{}, privateKey, eth.SigToPub), } } diff --git a/simulation/config/config.go b/simulation/config/config.go index f8f629b..ceb0abd 100644 --- a/simulation/config/config.go +++ b/simulation/config/config.go @@ -40,6 +40,7 @@ type Consensus struct { K int ChainNum uint32 GenesisCRS string `toml:"genesis_crs"` + Lambda int } // Legacy config. @@ -53,7 +54,6 @@ type Validator struct { Consensus Consensus Legacy Legacy Num int - Lambda int MaxBlock uint64 } @@ -96,13 +96,13 @@ func GenerateDefault(path string) error { K: 1, ChainNum: 7, GenesisCRS: "In DEXON we trust.", + Lambda: 250, }, Legacy: Legacy{ ProposeIntervalMean: 500, ProposeIntervalSigma: 50, }, Num: 7, - Lambda: 250, MaxBlock: math.MaxUint64, }, Networking: Networking{ diff --git a/simulation/governance.go b/simulation/governance.go index 44f679d..79c9119 100644 --- a/simulation/governance.go +++ b/simulation/governance.go @@ -20,6 +20,7 @@ package simulation import ( "fmt" "sync" + "time" "github.com/dexon-foundation/dexon-consensus-core/core/types" "github.com/dexon-foundation/dexon-consensus-core/simulation/config" @@ -38,6 +39,7 @@ type simGovernance struct { crs string dkgComplaint map[uint64][]*types.DKGComplaint dkgMasterPublicKey map[uint64][]*types.DKGMasterPublicKey + lambda time.Duration } // newSimGovernance returns a new simGovernance instance. @@ -52,6 +54,7 @@ func newSimGovernance( crs: consensusConfig.GenesisCRS, dkgComplaint: make(map[uint64][]*types.DKGComplaint), dkgMasterPublicKey: make(map[uint64][]*types.DKGMasterPublicKey), + lambda: time.Duration(consensusConfig.Lambda) * time.Millisecond, } } @@ -107,6 +110,11 @@ func (g *simGovernance) GetGenesisCRS() string { return g.crs } +// GetLambda return lambda for BA. +func (g *simGovernance) GetLambda() time.Duration { + return g.lambda +} + // addValidator add a new validator into the simulated governance contract. func (g *simGovernance) addValidator(vID types.ValidatorID) { g.lock.Lock() diff --git a/simulation/validator.go b/simulation/validator.go index 137c2c0..12ff308 100644 --- a/simulation/validator.go +++ b/simulation/validator.go @@ -20,7 +20,6 @@ package simulation import ( "fmt" "sort" - "time" "github.com/dexon-foundation/dexon-consensus-core/common" "github.com/dexon-foundation/dexon-consensus-core/core" @@ -99,22 +98,11 @@ func (v *validator) run(serverEndpoint interface{}, legacy bool) { break } } + v.consensus = core.NewConsensus( + v.app, v.gov, v.db, v.netModule, v.prvKey, v.sigToPub) if legacy { - v.consensus = core.NewConsensus( - v.app, v.gov, v.db, v.netModule, - time.NewTicker( - time.Duration( - v.config.Legacy.ProposeIntervalMean)*time.Millisecond), - v.prvKey, v.sigToPub) - go v.consensus.RunLegacy() } else { - v.consensus = core.NewConsensus( - v.app, v.gov, v.db, v.netModule, - time.NewTicker( - time.Duration(v.config.Lambda)*time.Millisecond), - v.prvKey, v.sigToPub) - go v.consensus.Run() } |