diff options
Diffstat (limited to 'simulation')
-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 |
5 files changed, 125 insertions, 89 deletions
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{}), |