aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmd/dexcon-simulation-with-scheduler/main.go4
-rw-r--r--cmd/dexcon-simulation/main.go3
-rw-r--r--core/agreement-state.go16
-rw-r--r--core/agreement-state_test.go6
-rw-r--r--core/agreement.go28
-rw-r--r--core/agreement_test.go6
-rw-r--r--core/consensus.go11
-rw-r--r--simulation/config/config.go27
-rw-r--r--simulation/kubernetes/config.toml.in7
-rw-r--r--simulation/simulation.go6
-rw-r--r--simulation/validator.go26
11 files changed, 84 insertions, 56 deletions
diff --git a/cmd/dexcon-simulation-with-scheduler/main.go b/cmd/dexcon-simulation-with-scheduler/main.go
index b9f5ec3..d1d815a 100644
--- a/cmd/dexcon-simulation-with-scheduler/main.go
+++ b/cmd/dexcon-simulation-with-scheduler/main.go
@@ -49,8 +49,8 @@ func main() {
Mean: cfg.Networking.Mean,
}
proposingLatency := &integration.NormalLatencyModel{
- Sigma: cfg.Validator.ProposeIntervalSigma,
- Mean: cfg.Validator.ProposeIntervalMean,
+ Sigma: cfg.Validator.Legacy.ProposeIntervalSigma,
+ Mean: cfg.Validator.Legacy.ProposeIntervalMean,
}
// Setup validators and other consensus related stuffs.
apps, dbs, validators, err := integration.PrepareValidators(
diff --git a/cmd/dexcon-simulation/main.go b/cmd/dexcon-simulation/main.go
index def4ac9..017cca5 100644
--- a/cmd/dexcon-simulation/main.go
+++ b/cmd/dexcon-simulation/main.go
@@ -35,6 +35,7 @@ var initialize = flag.Bool("init", false, "initialize config file")
var configFile = flag.String("config", "", "path to simulation config file")
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to `file`")
var memprofile = flag.String("memprofile", "", "write memory profile to `file`")
+var legacy = flag.Bool("legacy", false, "legacy consensus protocal")
func main() {
flag.Parse()
@@ -65,7 +66,7 @@ func main() {
defer pprof.StopCPUProfile()
}
- simulation.Run(*configFile)
+ simulation.Run(*configFile, *legacy)
if *memprofile != "" {
f, err := os.Create(*memprofile)
diff --git a/core/agreement-state.go b/core/agreement-state.go
index 33f86ce..b948417 100644
--- a/core/agreement-state.go
+++ b/core/agreement-state.go
@@ -81,7 +81,7 @@ func (s *prepareState) nextState() (agreementState, error) {
delete(s.a.blocks, s.a.ID)
}
}
- s.a.recv.proposeBlock(hash)
+ s.a.recv.ProposeBlock(hash)
return newAckState(s.a), nil
}
func (s *prepareState) receiveVote() error { return nil }
@@ -112,7 +112,7 @@ func (s *ackState) nextState() (agreementState, error) {
if hash == nullBlockHash {
hash = s.a.leader.leaderBlockHash()
}
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VoteAck,
BlockHash: hash,
Period: s.a.period,
@@ -151,7 +151,7 @@ func (s *confirmState) receiveVote() error {
return nil
}
if hash != nullBlockHash {
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VoteConfirm,
BlockHash: hash,
Period: s.a.period,
@@ -181,7 +181,7 @@ func (s *pass1State) nextState() (agreementState, error) {
v, e := s.a.votes[s.a.period][types.VoteConfirm][s.a.ID]
return v, e
}(); exist {
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VotePass,
BlockHash: vote.BlockHash,
Period: s.a.period,
@@ -192,7 +192,7 @@ func (s *pass1State) nextState() (agreementState, error) {
hash, ok := s.a.countVote(s.a.period-1, types.VotePass)
if ok {
if hash == nullBlockHash {
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VotePass,
BlockHash: hash,
Period: s.a.period,
@@ -205,7 +205,7 @@ func (s *pass1State) nextState() (agreementState, error) {
}
}
if voteDefault {
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VotePass,
BlockHash: s.a.defaultBlock,
Period: s.a.period,
@@ -261,7 +261,7 @@ func (s *pass2State) receiveVote() error {
}
ackHash, ok := s.a.countVote(s.a.period, types.VoteAck)
if ok && ackHash != nullBlockHash {
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VotePass,
BlockHash: ackHash,
Period: s.a.period,
@@ -272,7 +272,7 @@ func (s *pass2State) receiveVote() error {
s.a.votes[s.a.period][types.VoteConfirm][s.a.ID]; !exist {
hash, ok := s.a.countVote(s.a.period-1, types.VotePass)
if ok && hash == nullBlockHash {
- s.a.recv.proposeVote(&types.Vote{
+ s.a.recv.ProposeVote(&types.Vote{
Type: types.VotePass,
BlockHash: hash,
Period: s.a.period,
diff --git a/core/agreement-state_test.go b/core/agreement-state_test.go
index a120965..1591625 100644
--- a/core/agreement-state_test.go
+++ b/core/agreement-state_test.go
@@ -43,15 +43,15 @@ type agreementStateTestReceiver struct {
s *AgreementStateTestSuite
}
-func (r *agreementStateTestReceiver) proposeVote(vote *types.Vote) {
+func (r *agreementStateTestReceiver) ProposeVote(vote *types.Vote) {
r.s.voteChan <- vote
}
-func (r *agreementStateTestReceiver) proposeBlock(block common.Hash) {
+func (r *agreementStateTestReceiver) ProposeBlock(block common.Hash) {
r.s.blockChan <- block
}
-func (r *agreementStateTestReceiver) confirmBlock(block common.Hash) {
+func (r *agreementStateTestReceiver) ConfirmBlock(block common.Hash) {
r.s.confirmChan <- block
}
diff --git a/core/agreement.go b/core/agreement.go
index 8fb2207..e741145 100644
--- a/core/agreement.go
+++ b/core/agreement.go
@@ -58,9 +58,9 @@ func newVoteListMap() []map[types.ValidatorID]*types.Vote {
// agreementReceiver is the interface receiving agreement event.
type agreementReceiver interface {
- proposeVote(vote *types.Vote)
- proposeBlock(common.Hash)
- confirmBlock(common.Hash)
+ ProposeVote(vote *types.Vote)
+ ProposeBlock(common.Hash)
+ ConfirmBlock(common.Hash)
}
type pendingBlock struct {
@@ -230,18 +230,20 @@ func (a *agreement) sanityCheck(vote *types.Vote) error {
if !ok {
return ErrIncorrectVoteSignature
}
- if exist := func() bool {
+
+ if err := func() error {
a.data.votesLock.RLock()
defer a.data.votesLock.RUnlock()
- _, exist := a.data.votes[vote.Period]
- return exist
- }(); exist {
- if oldVote, exist :=
- a.data.votes[vote.Period][vote.Type][vote.ProposerID]; exist {
- if vote.BlockHash != oldVote.BlockHash {
- return ErrForkVote
+ if votes, exist := a.data.votes[vote.Period]; exist {
+ if oldVote, exist := votes[vote.Type][vote.ProposerID]; exist {
+ if vote.BlockHash != oldVote.BlockHash {
+ return ErrForkVote
+ }
}
}
+ return nil
+ }(); err != nil {
+ return err
}
return nil
}
@@ -262,6 +264,8 @@ func (a *agreement) processVote(vote *types.Vote) error {
return err
}
if vote.Position != a.agreementID() {
+ a.lock.Lock()
+ defer a.lock.Unlock()
a.pendingVote = append(a.pendingVote, pendingVote{
vote: vote,
receivedTime: time.Now().UTC(),
@@ -279,7 +283,7 @@ func (a *agreement) processVote(vote *types.Vote) error {
if len(a.data.votes[vote.Period][types.VoteConfirm]) >=
a.data.requiredVote {
a.hasOutput = true
- a.data.recv.confirmBlock(vote.BlockHash)
+ a.data.recv.ConfirmBlock(vote.BlockHash)
}
}
return true
diff --git a/core/agreement_test.go b/core/agreement_test.go
index aafd1ed..4f6ec5b 100644
--- a/core/agreement_test.go
+++ b/core/agreement_test.go
@@ -32,15 +32,15 @@ type agreementTestReceiver struct {
s *AgreementTestSuite
}
-func (r *agreementTestReceiver) proposeVote(vote *types.Vote) {
+func (r *agreementTestReceiver) ProposeVote(vote *types.Vote) {
r.s.voteChan <- vote
}
-func (r *agreementTestReceiver) proposeBlock(block common.Hash) {
+func (r *agreementTestReceiver) ProposeBlock(block common.Hash) {
r.s.blockChan <- block
}
-func (r *agreementTestReceiver) confirmBlock(block common.Hash) {
+func (r *agreementTestReceiver) ConfirmBlock(block common.Hash) {
r.s.confirmChan <- block
}
diff --git a/core/consensus.go b/core/consensus.go
index 5b85fcb..6d74bd7 100644
--- a/core/consensus.go
+++ b/core/consensus.go
@@ -70,8 +70,7 @@ type consensusReceiver struct {
restart chan struct{}
}
-func (recv *consensusReceiver) proposeVote(vote *types.Vote) {
- // TODO(jimmy-dexon): move prepareVote() into agreement.
+func (recv *consensusReceiver) ProposeVote(vote *types.Vote) {
if err := recv.consensus.prepareVote(recv.chainID, vote); err != nil {
fmt.Println(err)
return
@@ -84,7 +83,8 @@ func (recv *consensusReceiver) proposeVote(vote *types.Vote) {
recv.consensus.network.BroadcastVote(vote)
}()
}
-func (recv *consensusReceiver) proposeBlock(hash common.Hash) {
+
+func (recv *consensusReceiver) ProposeBlock(hash common.Hash) {
block, exist := recv.consensus.baModules[recv.chainID].findCandidateBlock(hash)
if !exist {
fmt.Println(ErrUnknownBlockProposed)
@@ -97,17 +97,18 @@ func (recv *consensusReceiver) proposeBlock(hash common.Hash) {
}
recv.consensus.network.BroadcastBlock(block)
}
-func (recv *consensusReceiver) confirmBlock(hash common.Hash) {
+
+func (recv *consensusReceiver) ConfirmBlock(hash common.Hash) {
block, exist := recv.consensus.baModules[recv.chainID].findCandidateBlock(hash)
if !exist {
fmt.Println(ErrUnknownBlockConfirmed, hash)
return
}
- recv.restart <- struct{}{}
if err := recv.consensus.ProcessBlock(block); err != nil {
fmt.Println(err)
return
}
+ recv.restart <- struct{}{}
}
// Consensus implements DEXON Consensus algorithm.
diff --git a/simulation/config/config.go b/simulation/config/config.go
index c59b663..2f03f85 100644
--- a/simulation/config/config.go
+++ b/simulation/config/config.go
@@ -41,13 +41,19 @@ type Consensus struct {
GenesisCRS string `toml:"genesis_crs"`
}
-// Validator config for the simulation.
-type Validator struct {
- Consensus Consensus
- Num int
+// Legacy config.
+type Legacy struct {
ProposeIntervalMean float64
ProposeIntervalSigma float64
- MaxBlock uint64
+}
+
+// Validator config for the simulation.
+type Validator struct {
+ Consensus Consensus
+ Legacy Legacy
+ Num int
+ Lambda int
+ MaxBlock uint64
}
// Networking config.
@@ -90,10 +96,13 @@ func GenerateDefault(path string) error {
ChainNum: 7,
GenesisCRS: "In DEXON we trust.",
},
- Num: 7,
- ProposeIntervalMean: 500,
- ProposeIntervalSigma: 30,
- MaxBlock: math.MaxUint64,
+ Legacy: Legacy{
+ ProposeIntervalMean: 500,
+ ProposeIntervalSigma: 50,
+ },
+ Num: 7,
+ Lambda: 250,
+ MaxBlock: math.MaxUint64,
},
Networking: Networking{
Type: NetworkTypeTCPLocal,
diff --git a/simulation/kubernetes/config.toml.in b/simulation/kubernetes/config.toml.in
index 1cc18aa..2f12956 100644
--- a/simulation/kubernetes/config.toml.in
+++ b/simulation/kubernetes/config.toml.in
@@ -2,8 +2,7 @@ title = "DEXON Consensus Simulation Config"
[validator]
num = {{numValidators}}
-propose_interval_mean = 5e+02
-propose_interval_sigma = 3e+01
+lambda = 250
max_block = 1000
[validator.consensus]
@@ -12,6 +11,10 @@ k = 1
chain_num = 7
genesis_crs = "In DEXON we trust."
+[validator.legacy]
+propose_interval_mean = 5e+02
+propose_interval_sigma = 5e+01
+
[networking]
type = "tcp"
peer_server = "peer-server-svc.default.svc.cluster.local"
diff --git a/simulation/simulation.go b/simulation/simulation.go
index 4cfc79c..978107a 100644
--- a/simulation/simulation.go
+++ b/simulation/simulation.go
@@ -26,7 +26,7 @@ import (
)
// Run starts the simulation.
-func Run(configPath string) {
+func Run(configPath string, legacy bool) {
cfg, err := config.Read(configPath)
if err != nil {
panic(err)
@@ -65,7 +65,7 @@ func Run(configPath string) {
for i := 0; i < cfg.Validator.Num; i++ {
fmt.Printf("Validator %d: %s\n", i, vs[i].ID)
- go vs[i].Run()
+ go vs[i].Run(legacy)
}
} else if networkType == config.NetworkTypeTCP {
prv, err := eth.NewPrivateKey()
@@ -75,7 +75,7 @@ func Run(configPath string) {
network := NewTCPNetwork(false, cfg.Networking.PeerServer, networkModel)
network.Start()
v := NewValidator(prv, eth.SigToPub, cfg.Validator, network)
- go v.Run()
+ go v.Run(legacy)
vs = append(vs, v)
}
diff --git a/simulation/validator.go b/simulation/validator.go
index 6d73c50..21b9db6 100644
--- a/simulation/validator.go
+++ b/simulation/validator.go
@@ -83,7 +83,7 @@ func (v *Validator) GetID() types.ValidatorID {
}
// Run starts the validator.
-func (v *Validator) Run() {
+func (v *Validator) Run(legacy bool) {
v.network.Join(v)
v.msgChannel = v.network.ReceiveChan()
@@ -99,13 +99,23 @@ func (v *Validator) Run() {
break
}
}
- v.consensus = core.NewConsensus(
- v.app, v.gov, v.db, v.network,
- time.NewTicker(
- time.Duration(v.config.ProposeIntervalMean)*time.Millisecond),
- v.prvKey, v.sigToPub)
-
- go v.consensus.Run()
+ if legacy {
+ v.consensus = core.NewConsensus(
+ v.app, v.gov, v.db, v.network,
+ 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.network,
+ time.NewTicker(
+ time.Duration(v.config.Lambda)*time.Millisecond),
+ v.prvKey, v.sigToPub)
+
+ go v.consensus.Run()
+ }
isShutdown := make(chan struct{})