aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMission Liao <mission.liao@dexon.org>2018-09-18 09:07:52 +0800
committerGitHub <noreply@github.com>2018-09-18 09:07:52 +0800
commit81cf96477127a2da8843d544802027c7061a9c06 (patch)
tree70c06aec5df92df1dd93b605cc7afdbd2b8b0347
parent8a908e98279d7e80978cd412057eddd4a6bbf06c (diff)
downloaddexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.tar
dexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.tar.gz
dexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.tar.bz2
dexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.tar.lz
dexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.tar.xz
dexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.tar.zst
dexon-consensus-81cf96477127a2da8843d544802027c7061a9c06.zip
core: remove ticker parameter from NewConsensus
- remove BlockProposingInterval, it's replaced by lambda. - remove ticker parameter of NewConsensus, ticker would be derived from governance. - leave a backdoor to hook the construction of ticker. - move 'Lambda' config from to consensus.
-rw-r--r--core/consensus.go14
-rw-r--r--core/consensus_test.go9
-rw-r--r--core/interfaces.go14
-rw-r--r--core/test/governance.go36
-rw-r--r--core/ticker.go58
-rw-r--r--integration_test/utils.go4
-rw-r--r--integration_test/validator.go3
-rw-r--r--simulation/config/config.go4
-rw-r--r--simulation/governance.go8
-rw-r--r--simulation/validator.go16
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()
}