Merge pull request #33 from getamis/feature/TFU-02-03-remove-validators

Implement TFU-02-03 Remove validators
This commit is contained in:
bailantaotao 2017-08-24 14:42:52 +08:00 committed by GitHub
commit 6c7c38b7ed
2 changed files with 76 additions and 9 deletions

View File

@ -33,6 +33,7 @@ import (
type Blockchain interface {
AddValidators(numOfValidators int) ([]Ethereum, error)
RemoveValidators(candidates []Ethereum, t time.Duration) error
EnsureConsensusWorking(geths []Ethereum, t time.Duration) error
Start(bool) error
Stop(bool) error
@ -127,6 +128,32 @@ func (bc *blockchain) EnsureConsensusWorking(geths []Ethereum, t time.Duration)
return err
}
func (bc *blockchain) RemoveValidators(candidates []Ethereum, processingTime time.Duration) error {
var newValidators []Ethereum
for _, v := range bc.validators {
istClient := v.NewIstanbulClient()
isFound := false
for _, c := range candidates {
if err := istClient.ProposeValidator(context.Background(), c.Address(), false); err != nil {
return err
}
if v.ContainerID() == c.ContainerID() {
isFound = true
}
}
if !isFound {
newValidators = append(newValidators, v)
}
}
// FIXME: It is not good way to wait validator vote out candidates
<-time.After(processingTime)
bc.validators = newValidators
return bc.stop(candidates, false)
}
func (bc *blockchain) Start(strong bool) error {
if err := bc.start(bc.validators); err != nil {
return err
@ -135,12 +162,7 @@ func (bc *blockchain) Start(strong bool) error {
}
func (bc *blockchain) Stop(force bool) error {
for _, v := range bc.validators {
if err := v.Stop(); err != nil && !force {
return err
}
}
return nil
return bc.stop(bc.validators, force)
}
func (bc *blockchain) Finalize() {
@ -260,9 +282,9 @@ func (bc *blockchain) start(validators []Ethereum) error {
return nil
}
func (bc *blockchain) stop(validators []Ethereum) error {
func (bc *blockchain) stop(validators []Ethereum, force bool) error {
for _, v := range validators {
if err := v.Stop(); err != nil {
if err := v.Stop(); err != nil && !force {
return err
}
}

View File

@ -19,6 +19,7 @@ package tests
import (
"context"
"time"
"math"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -47,7 +48,7 @@ var _ = Describe("Dynamic validators addition/removal testing", func() {
It("TFS-02-01 Add validators", func() {
testValidators := 3
By("Ensure that numbers of validator is equal than $numberOfValidators", func() {
By("Ensure that numbers of validator is equal to $numberOfValidators", func() {
for _, v := range blockchain.Validators() {
client := v.NewIstanbulClient()
validators, err := client.GetValidators(context.Background(), nil)
@ -69,4 +70,48 @@ var _ = Describe("Dynamic validators addition/removal testing", func() {
Expect(len(validators)).Should(BeNumerically("==", numberOfValidators+testValidators))
}
})
It("TFS-02-03 Remove validators", func() {
numOfCandidates := 3
By("Ensure that numbers of validator is equal to $numberOfValidators", func() {
for _, v := range blockchain.Validators() {
client := v.NewIstanbulClient()
validators, err := client.GetValidators(context.Background(), nil)
Expect(err).Should(BeNil())
Expect(len(validators)).Should(BeNumerically("==", numberOfValidators))
}
})
_, err := blockchain.AddValidators(numOfCandidates)
Expect(err).Should(BeNil())
By("Ensure that consensus is working in 50 seconds", func() {
Expect(blockchain.EnsureConsensusWorking(blockchain.Validators(), 50*time.Second)).Should(BeNil())
})
for _, v := range blockchain.Validators() {
client := v.NewIstanbulClient()
validators, err := client.GetValidators(context.Background(), nil)
Expect(err).Should(BeNil())
Expect(len(validators)).Should(BeNumerically("==", numberOfValidators+numOfCandidates))
}
// remove validators [1,2,3]
removalCandidates := blockchain.Validators()[:numOfCandidates]
processingTime := time.Duration(math.Pow(2, float64(len(removalCandidates)))*7) * time.Second
Expect(blockchain.RemoveValidators(removalCandidates, processingTime)).Should(BeNil())
By("Ensure that consensus is working in 20 seconds", func() {
Expect(blockchain.EnsureConsensusWorking(blockchain.Validators(), 20*time.Second)).Should(BeNil())
})
for _, v := range blockchain.Validators() {
client := v.NewIstanbulClient()
validators, err := client.GetValidators(context.Background(), nil)
Expect(err).Should(BeNil())
Expect(len(validators)).Should(BeNumerically("==", numberOfValidators))
}
By("Ensure that consensus is working in 30 seconds", func() {
Expect(blockchain.EnsureConsensusWorking(blockchain.Validators(), 30*time.Second)).Should(BeNil())
})
})
})