aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2018-08-10 15:12:56 +0800
committerJimmy Hu <jimmy.hu@dexon.org>2018-08-10 15:12:56 +0800
commit09a0ab086cdafcb27b74e6346efdc8e96ca8145d (patch)
treec14bda316a48c94e5300b5799f152a82f0594558
parent03917cdfa1f762849541e1bed31394340ed1f957 (diff)
downloaddexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.tar
dexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.tar.gz
dexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.tar.bz2
dexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.tar.lz
dexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.tar.xz
dexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.tar.zst
dexon-consensus-09a0ab086cdafcb27b74e6346efdc8e96ca8145d.zip
core: update governance interface and move K into config (#40)
-rw-r--r--GNUmakefile12
-rwxr-xr-xbin/install_eth_dep.sh20
-rw-r--r--core/consensus.go7
-rw-r--r--core/consensus_test.go6
-rw-r--r--core/governance.go10
-rw-r--r--core/test/governance.go (renamed from core/test/gov.go)38
-rw-r--r--core/types/configuration.go46
-rw-r--r--core/types/membership-event.go16
-rw-r--r--simulation/app.go20
-rw-r--r--simulation/config/config.go13
-rw-r--r--simulation/gov.go74
-rw-r--r--simulation/governance.go99
-rw-r--r--simulation/validator.go8
-rw-r--r--test_config/test.toml4
14 files changed, 233 insertions, 140 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 96a5efa..6eceb31 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -55,17 +55,7 @@ pre-build: eth-dep
pre-submit: eth-dep check-format lint test vet
eth-dep:
- @rm -rf vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1
- @if [ ! -d .dep/libsecp256k1 ]; then \
- git init .dep/libsecp256k1; \
- cd .dep/libsecp256k1; \
- git remote add origin https://github.com/ethereum/go-ethereum.git; \
- git config core.sparsecheckout true; \
- echo "crypto/secp256k1/libsecp256k1/*" >> .git/info/sparse-checkout; \
- cd ../../; \
- fi
- @cd .dep/libsecp256k1; git pull --depth=1 origin master; cd ../../
- @cp -r .dep/libsecp256k1/crypto/secp256k1/libsecp256k1 vendor/github.com/ethereum/go-ethereum/crypto/secp256k1
+ @bin/install_eth_dep.sh
format:
@go fmt `go list ./... | grep -v 'vendor'`
diff --git a/bin/install_eth_dep.sh b/bin/install_eth_dep.sh
new file mode 100755
index 0000000..79ecd0e
--- /dev/null
+++ b/bin/install_eth_dep.sh
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+if [ -e .dep/libsecp256k1 ]; then
+ exit 0
+fi
+
+rm -rf vendor/github.com/ethereum/go-ethereum/crypto/secp256k1/libsecp256k1
+if [ ! -d .dep/libsecp256k1 ]; then
+ git init .dep/libsecp256k1
+ cd .dep/libsecp256k1
+ git remote add origin https://github.com/ethereum/go-ethereum.git
+ git config core.sparsecheckout true
+ echo "crypto/secp256k1/libsecp256k1/*" >> .git/info/sparse-checkout
+ cd ../../
+fi
+cd .dep/libsecp256k1
+git pull --depth=1 origin master
+cd ../../
+cp -r .dep/libsecp256k1/crypto/secp256k1/libsecp256k1 \
+ vendor/github.com/ethereum/go-ethereum/crypto/secp256k1
diff --git a/core/consensus.go b/core/consensus.go
index 33f2f8b..d668c9e 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -42,7 +42,6 @@ func NewConsensus(
app Application,
gov Governance,
db blockdb.BlockDatabase) *Consensus {
-
validatorSet := gov.GetValidatorSet()
// Setup acking by information returned from Governace.
@@ -52,11 +51,9 @@ func NewConsensus(
}
// Setup sequencer by information returned from Governace.
- // TODO(mission): the value of 'K' should be in governace.
- // TODO(mission): the ratio of 'phi' should be in governance.
to := newTotalOrdering(
- 0,
- uint64(2*(len(validatorSet)-1)/3+1),
+ uint64(gov.GetTotalOrderingK()),
+ uint64(float32(len(validatorSet)-1)*gov.GetPhiRatio()+1),
uint64(len(validatorSet)))
return &Consensus{
diff --git a/core/consensus_test.go b/core/consensus_test.go
index 1544818..beeb1a7 100644
--- a/core/consensus_test.go
+++ b/core/consensus_test.go
@@ -53,7 +53,7 @@ func (s *ConsensusTestSuite) prepareGenesisBlock(
return block
}
-func (s *ConsensusTestSuite) prepareConsensus(gov *test.Gov) (
+func (s *ConsensusTestSuite) prepareConsensus(gov *test.Governance) (
*test.App, *Consensus) {
app := test.NewApp()
@@ -77,7 +77,7 @@ func (s *ConsensusTestSuite) TestSimpleDeliverBlock() {
// This test case only works for Total Ordering with K=0.
var (
minInterval = 50 * time.Millisecond
- gov = test.NewGov(4, 1000)
+ gov = test.NewGovernance(4, 1000)
req = s.Require()
validators []types.ValidatorID
)
@@ -262,7 +262,7 @@ func (s *ConsensusTestSuite) TestPrepareBlock() {
// - Make sure Consensus.PrepareBlock would only attempt to
// ack the prepared block.
var (
- gov = test.NewGov(4, 1000)
+ gov = test.NewGovernance(4, 1000)
req = s.Require()
validators []types.ValidatorID
)
diff --git a/core/governance.go b/core/governance.go
index a7069a5..d94fad0 100644
--- a/core/governance.go
+++ b/core/governance.go
@@ -30,9 +30,15 @@ type Governance interface {
// Get the current validator set and it's corresponding stake.
GetValidatorSet() map[types.ValidatorID]decimal.Decimal
+ // Get K
+ GetTotalOrderingK() int
+
+ // Get PhiRatio
+ GetPhiRatio() float32
+
// Get block proposing interval (in milliseconds).
GetBlockProposingInterval() int
- // Get membership events after a certain epoch.
- GetMembershipEvents(epoch int) []types.MembershipEvent
+ // Get configuration change events after a certain epoch.
+ GetConfigurationChangeEvent(epoch int) []types.ConfigurationChangeEvent
}
diff --git a/core/test/gov.go b/core/test/governance.go
index 7a5bdfc..a7ae1b0 100644
--- a/core/test/gov.go
+++ b/core/test/governance.go
@@ -23,22 +23,21 @@ import (
"github.com/shopspring/decimal"
)
-// Gov is an implementation of Goverance for testing purpose.
-type Gov struct {
+// Governance is an implementation of Goverance for testing purpose.
+type Governance struct {
BlockProposingInterval int
Validators map[types.ValidatorID]decimal.Decimal
}
-// NewGov constructs a Gov instance.
-func NewGov(
- validatorCount, proposingInterval int) (gov *Gov) {
+// NewGovernance constructs a Governance instance.
+func NewGovernance(validatorCount, proposingInterval int) (g *Governance) {
- gov = &Gov{
+ g = &Governance{
BlockProposingInterval: proposingInterval,
Validators: make(map[types.ValidatorID]decimal.Decimal),
}
for i := 0; i < validatorCount; i++ {
- gov.Validators[types.ValidatorID{Hash: common.NewRandomHash()}] =
+ g.Validators[types.ValidatorID{Hash: common.NewRandomHash()}] =
decimal.NewFromFloat(0)
}
return
@@ -46,18 +45,29 @@ func NewGov(
// GetValidatorSet implements Governance interface to return current
// validator set.
-func (gov *Gov) GetValidatorSet() map[types.ValidatorID]decimal.Decimal {
- return gov.Validators
+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 (gov *Gov) GetBlockProposingInterval() int {
- return gov.BlockProposingInterval
+func (g *Governance) GetBlockProposingInterval() int {
+ return g.BlockProposingInterval
}
-// GetMembershipEvents implements Governance interface to return membership
-// changed events.
-func (gov *Gov) GetMembershipEvents(epoch int) []types.MembershipEvent {
+// GetTotalOrderingK returns K.
+func (g *Governance) GetTotalOrderingK() int {
+ return 0
+}
+
+// GetPhiRatio returns phi ratio.
+func (g *Governance) GetPhiRatio() float32 {
+ return 0.667
+}
+
+// GetConfigurationChangeEvent Get configuration change events after a certain
+// epoch.
+func (g *Governance) GetConfigurationChangeEvent(
+ epoch int) []types.ConfigurationChangeEvent {
return nil
}
diff --git a/core/types/configuration.go b/core/types/configuration.go
new file mode 100644
index 0000000..4158331
--- /dev/null
+++ b/core/types/configuration.go
@@ -0,0 +1,46 @@
+// 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 types
+
+// ConfigurationChangeEventType specifies the action of a membership event.
+type ConfigurationChangeEventType int
+
+// Event enums.
+const (
+ KChanged ConfigurationChangeEventType = iota
+ MembershipAdd
+ MembershipRemove
+)
+
+// IntegerEventPayload is a general payload for integer type value.
+type IntegerEventPayload struct {
+ Value int64
+}
+
+// MembershipEventPayload is the payload type for membership event.
+type MembershipEventPayload struct {
+ ID ValidatorID
+ Evidence []byte
+}
+
+// ConfigurationChangeEvent specifies the event of membership changes.
+type ConfigurationChangeEvent struct {
+ Epoch int
+ Event ConfigurationChangeEventType
+ Payload interface{}
+}
diff --git a/core/types/membership-event.go b/core/types/membership-event.go
deleted file mode 100644
index 8d05039..0000000
--- a/core/types/membership-event.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package types
-
-// MembershipActionType specifies the action of a membership event.
-type MembershipActionType int
-
-// Event enums.
-const (
- MembershipActionAdd MembershipActionType = iota
- MembershipActionDelete
-)
-
-// MembershipEvent specifies the event of membership changes.
-type MembershipEvent struct {
- Epoch int
- Action MembershipActionType
-}
diff --git a/simulation/app.go b/simulation/app.go
index 2d09f2a..89b41a1 100644
--- a/simulation/app.go
+++ b/simulation/app.go
@@ -26,8 +26,8 @@ import (
"github.com/dexon-foundation/dexon-consensus-core/core/types"
)
-// SimApp is an DEXON app for simulation.
-type SimApp struct {
+// simApp is an DEXON app for simulation.
+type simApp struct {
ValidatorID types.ValidatorID
Outputs []*types.Block
Early bool
@@ -40,9 +40,9 @@ type SimApp struct {
blockByHash map[common.Hash]*types.Block
}
-// NewSimApp returns point to a new instance of SimApp.
-func NewSimApp(id types.ValidatorID, Network PeerServerNetwork) *SimApp {
- return &SimApp{
+// newSimApp returns point to a new instance of simApp.
+func newSimApp(id types.ValidatorID, Network PeerServerNetwork) *simApp {
+ return &simApp{
ValidatorID: id,
Network: Network,
DeliverID: 0,
@@ -52,13 +52,13 @@ func NewSimApp(id types.ValidatorID, Network PeerServerNetwork) *SimApp {
}
}
-func (a *SimApp) addBlock(block *types.Block) {
+func (a *simApp) addBlock(block *types.Block) {
a.blockByHash[block.Hash] = block
}
// getAckedBlocks will return all unconfirmed blocks' hash with lower Height
// than the block with ackHash.
-func (a *SimApp) getAckedBlocks(ackHash common.Hash) (output common.Hashes) {
+func (a *simApp) getAckedBlocks(ackHash common.Hash) (output common.Hashes) {
// TODO(jimmy-dexon): Why there are some acks never seen?
ackBlock, exist := a.blockByHash[ackHash]
if !exist {
@@ -83,12 +83,12 @@ func (a *SimApp) getAckedBlocks(ackHash common.Hash) (output common.Hashes) {
// StronglyAcked is called when a block is strongly acked by DEXON
// Reliabe Broadcast algorithm.
-func (a *SimApp) StronglyAcked(blockHash common.Hash) {
+func (a *simApp) StronglyAcked(blockHash common.Hash) {
}
// TotalOrderingDeliver is called when blocks are delivered by the total
// ordering algorithm.
-func (a *SimApp) TotalOrderingDeliver(blockHashes common.Hashes, early bool) {
+func (a *simApp) TotalOrderingDeliver(blockHashes common.Hashes, early bool) {
now := time.Now()
blocks := make([]*types.Block, len(blockHashes))
for idx := range blockHashes {
@@ -147,7 +147,7 @@ func (a *SimApp) TotalOrderingDeliver(blockHashes common.Hashes, early bool) {
}
// DeliverBlock is called when a block in compaction chain is delivered.
-func (a *SimApp) DeliverBlock(blockHash common.Hash, timestamp time.Time) {
+func (a *simApp) DeliverBlock(blockHash common.Hash, timestamp time.Time) {
seenTime, exist := a.blockSeen[blockHash]
if !exist {
return
diff --git a/simulation/config/config.go b/simulation/config/config.go
index c704a8d..02c077b 100644
--- a/simulation/config/config.go
+++ b/simulation/config/config.go
@@ -34,8 +34,15 @@ const (
NetworkTypeTCPLocal NetworkType = "tcp-local"
)
+// Consensus settings.
+type Consensus struct {
+ PhiRatio float32
+ K int
+}
+
// Validator config for the simulation.
type Validator struct {
+ Consensus Consensus
Num int
ProposeIntervalMean float64
ProposeIntervalSigma float64
@@ -70,6 +77,10 @@ func GenerateDefault(path string) error {
config := Config{
Title: "DEXON Consensus Simulation Config",
Validator: Validator{
+ Consensus: Consensus{
+ PhiRatio: 0.66667,
+ K: 2,
+ },
Num: 7,
ProposeIntervalMean: 500,
ProposeIntervalSigma: 30,
@@ -100,7 +111,7 @@ func Read(path string) (*Config, error) {
var config Config
- if toml.NewDecoder(f).Decode(&config); err != nil {
+ if err := toml.NewDecoder(f).Decode(&config); err != nil {
return nil, err
}
return &config, nil
diff --git a/simulation/gov.go b/simulation/gov.go
deleted file mode 100644
index ddba949..0000000
--- a/simulation/gov.go
+++ /dev/null
@@ -1,74 +0,0 @@
-// 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 simulation
-
-import (
- "fmt"
- "sync"
-
- "github.com/dexon-foundation/dexon-consensus-core/core/types"
- "github.com/shopspring/decimal"
-)
-
-type simGov struct {
- lock sync.RWMutex
- validatorSet map[types.ValidatorID]decimal.Decimal
- expectedNumValidators int
-}
-
-func newSimGov(numValidators int) *simGov {
- return &simGov{
- validatorSet: make(map[types.ValidatorID]decimal.Decimal),
- expectedNumValidators: numValidators,
- }
-}
-
-func (gov *simGov) GetValidatorSet() (
- ret map[types.ValidatorID]decimal.Decimal) {
-
- gov.lock.RLock()
- defer gov.lock.RUnlock()
-
- // Return the cloned validatorSet.
- ret = make(map[types.ValidatorID]decimal.Decimal)
- for k, v := range gov.validatorSet {
- ret[k] = v
- }
- return
-}
-
-func (gov *simGov) GetBlockProposingInterval() int {
- return 0
-}
-
-func (gov *simGov) GetMembershipEvents(epoch int) []types.MembershipEvent {
- return nil
-}
-
-func (gov *simGov) addValidator(vID types.ValidatorID) {
- gov.lock.Lock()
- defer gov.lock.Unlock()
-
- if _, exists := gov.validatorSet[vID]; exists {
- return
- }
- if len(gov.validatorSet) == gov.expectedNumValidators {
- panic(fmt.Errorf("attempt to add validator when ready"))
- }
- gov.validatorSet[vID] = decimal.NewFromFloat(0)
-}
diff --git a/simulation/governance.go b/simulation/governance.go
new file mode 100644
index 0000000..7e3f6f2
--- /dev/null
+++ b/simulation/governance.go
@@ -0,0 +1,99 @@
+// 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 simulation
+
+import (
+ "fmt"
+ "sync"
+
+ "github.com/dexon-foundation/dexon-consensus-core/core/types"
+ "github.com/dexon-foundation/dexon-consensus-core/simulation/config"
+ "github.com/shopspring/decimal"
+)
+
+// simGovernance is a simulated governance contract implementing the
+// core.Governance interface.
+type simGovernance struct {
+ lock sync.RWMutex
+ validatorSet map[types.ValidatorID]decimal.Decimal
+ expectedNumValidators int
+ k int
+ phiRatio float32
+}
+
+// newSimGovernance returns a new simGovernance instance.
+func newSimGovernance(
+ numValidators int, consensusConfig config.Consensus) *simGovernance {
+ return &simGovernance{
+ validatorSet: make(map[types.ValidatorID]decimal.Decimal),
+ expectedNumValidators: numValidators,
+ k: consensusConfig.K,
+ phiRatio: consensusConfig.PhiRatio,
+ }
+}
+
+// GetValidatorSet returns the validator set.
+func (g *simGovernance) GetValidatorSet() (
+ ret map[types.ValidatorID]decimal.Decimal) {
+
+ g.lock.RLock()
+ defer g.lock.RUnlock()
+
+ // Return the cloned validatorSet.
+ ret = make(map[types.ValidatorID]decimal.Decimal)
+ for k, v := range g.validatorSet {
+ ret[k] = v
+ }
+ return
+}
+
+// GetTotalOrderingK returns K.
+func (g *simGovernance) GetTotalOrderingK() int {
+ return g.k
+}
+
+// GetTotalOrderingK returns PhiRatio.
+func (g *simGovernance) GetPhiRatio() float32 {
+ return g.phiRatio
+}
+
+// GetBlockProposingInterval returns block proposing interval.
+func (g *simGovernance) GetBlockProposingInterval() int {
+ return 0
+}
+
+// GetConfigurationChangeEvent returns configuration change event since last
+// epoch.
+func (g *simGovernance) GetConfigurationChangeEvent(
+ epoch int) []types.ConfigurationChangeEvent {
+ return nil
+}
+
+// addValidator add a new validator into the simulated governance contract.
+func (g *simGovernance) addValidator(vID types.ValidatorID) {
+ g.lock.Lock()
+ defer g.lock.Unlock()
+
+ if _, exists := g.validatorSet[vID]; exists {
+ return
+ }
+ if len(g.validatorSet) == g.expectedNumValidators {
+ panic(fmt.Errorf("attempt to add validator when ready"))
+ }
+ g.validatorSet[vID] = decimal.NewFromFloat(0)
+}
diff --git a/simulation/validator.go b/simulation/validator.go
index 4bc8283..9a84908 100644
--- a/simulation/validator.go
+++ b/simulation/validator.go
@@ -31,8 +31,8 @@ import (
// Validator represents a validator in DexCon.
type Validator struct {
network Network
- app *SimApp
- gov *simGov
+ app *simApp
+ gov *simGovernance
db blockdb.BlockDatabase
config config.Validator
@@ -55,13 +55,13 @@ func NewValidator(
if err != nil {
panic(err)
}
- gov := newSimGov(config.Num)
+ gov := newSimGovernance(config.Num, config.Consensus)
gov.addValidator(id)
return &Validator{
ID: id,
config: config,
network: network,
- app: NewSimApp(id, network),
+ app: newSimApp(id, network),
gov: gov,
db: db,
isFinished: make(chan struct{}),
diff --git a/test_config/test.toml b/test_config/test.toml
index 29067a4..0204ea1 100644
--- a/test_config/test.toml
+++ b/test_config/test.toml
@@ -6,6 +6,10 @@ propose_interval_mean = 5e+02
propose_interval_sigma = 5e+0
max_block = 20
+[validator.consensus]
+phi_ratio = 6.66670024394989e-01
+k = 2
+
[networking]
type = "tcp-local"
peer_server = "peer.server"