diff options
author | Wei-Ning Huang <w@dexon.org> | 2018-08-10 15:12:56 +0800 |
---|---|---|
committer | Jimmy Hu <jimmy.hu@dexon.org> | 2018-08-10 15:12:56 +0800 |
commit | 09a0ab086cdafcb27b74e6346efdc8e96ca8145d (patch) | |
tree | c14bda316a48c94e5300b5799f152a82f0594558 | |
parent | 03917cdfa1f762849541e1bed31394340ed1f957 (diff) | |
download | dexon-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-- | GNUmakefile | 12 | ||||
-rwxr-xr-x | bin/install_eth_dep.sh | 20 | ||||
-rw-r--r-- | core/consensus.go | 7 | ||||
-rw-r--r-- | core/consensus_test.go | 6 | ||||
-rw-r--r-- | core/governance.go | 10 | ||||
-rw-r--r-- | core/test/governance.go (renamed from core/test/gov.go) | 38 | ||||
-rw-r--r-- | core/types/configuration.go | 46 | ||||
-rw-r--r-- | core/types/membership-event.go | 16 | ||||
-rw-r--r-- | simulation/app.go | 20 | ||||
-rw-r--r-- | simulation/config/config.go | 13 | ||||
-rw-r--r-- | simulation/gov.go | 74 | ||||
-rw-r--r-- | simulation/governance.go | 99 | ||||
-rw-r--r-- | simulation/validator.go | 8 | ||||
-rw-r--r-- | test_config/test.toml | 4 |
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" |