Merge pull request #61 from getamis/test/quorum-general-consensus-test
tests/quorum: add general consensus test
This commit is contained in:
commit
533c9f1152
|
@ -17,13 +17,20 @@
|
|||
package functional
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
"sync"
|
||||
|
||||
"github.com/getamis/istanbul-tools/tests"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/getamis/istanbul-tools/container"
|
||||
"github.com/getamis/istanbul-tools/genesis"
|
||||
"github.com/getamis/istanbul-tools/tests"
|
||||
)
|
||||
|
||||
var _ = Describe("QFS-01: General consensus", func() {
|
||||
|
@ -49,67 +56,65 @@ var _ = Describe("QFS-01: General consensus", func() {
|
|||
constellationNetwork.Finalize()
|
||||
})
|
||||
|
||||
// FIt("QFS-01-01, QFS-01-02: Blockchain initialization and run", func() {
|
||||
// fmt.Printf("validators:%v\n", blockchain.Validators())
|
||||
// errc := make(chan error, len(blockchain.Validators()))
|
||||
// valSet := make(map[common.Address]bool, numberOfValidators)
|
||||
// for _, geth := range blockchain.Validators() {
|
||||
// valSet[geth.Address()] = true
|
||||
// }
|
||||
// for _, geth := range blockchain.Validators() {
|
||||
// go func(geth container.Ethereum) {
|
||||
// // 1. Verify genesis block
|
||||
// c := geth.NewClient()
|
||||
// header, err := c.HeaderByNumber(context.Background(), big.NewInt(0))
|
||||
// if err != nil {
|
||||
// errc <- err
|
||||
// return
|
||||
// }
|
||||
It("QFS-01-01, QFS-01-02: Blockchain initialization and run", func() {
|
||||
errc := make(chan error, len(blockchain.Validators()))
|
||||
valSet := make(map[common.Address]bool, numberOfValidators)
|
||||
for _, geth := range blockchain.Validators() {
|
||||
valSet[geth.Address()] = true
|
||||
}
|
||||
for _, geth := range blockchain.Validators() {
|
||||
go func(geth container.Ethereum) {
|
||||
// 1. Verify genesis block
|
||||
c := geth.NewClient()
|
||||
header, err := c.HeaderByNumber(context.Background(), big.NewInt(0))
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
|
||||
// if header.GasLimit.Int64() != genesis.InitGasLimit {
|
||||
// errStr := fmt.Sprintf("Invalid genesis gas limit. want:%v, got:%v", genesis.InitGasLimit, header.GasLimit.Int64())
|
||||
// errc <- errors.New(errStr)
|
||||
// return
|
||||
// }
|
||||
if header.GasLimit.Int64() != genesis.InitGasLimit {
|
||||
errStr := fmt.Sprintf("Invalid genesis gas limit. want:%v, got:%v", genesis.InitGasLimit, header.GasLimit.Int64())
|
||||
errc <- errors.New(errStr)
|
||||
return
|
||||
}
|
||||
|
||||
// if header.Difficulty.Int64() != genesis.InitDifficulty {
|
||||
// errStr := fmt.Sprintf("Invalid genesis difficulty. want:%v, got:%v", genesis.InitDifficulty, header.Difficulty.Int64())
|
||||
// errc <- errors.New(errStr)
|
||||
// return
|
||||
// }
|
||||
if header.Difficulty.Int64() != genesis.InitDifficulty {
|
||||
errStr := fmt.Sprintf("Invalid genesis difficulty. want:%v, got:%v", genesis.InitDifficulty, header.Difficulty.Int64())
|
||||
errc <- errors.New(errStr)
|
||||
return
|
||||
}
|
||||
|
||||
// if header.MixDigest != types.IstanbulDigest {
|
||||
// errStr := fmt.Sprintf("Invalid block mixhash. want:%v, got:%v", types.IstanbulDigest, header.MixDigest)
|
||||
// errc <- errors.New(errStr)
|
||||
// return
|
||||
if header.MixDigest != types.IstanbulDigest {
|
||||
errStr := fmt.Sprintf("Invalid block mixhash. want:%v, got:%v", types.IstanbulDigest, header.MixDigest)
|
||||
errc <- errors.New(errStr)
|
||||
return
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
// // 2. Check validator set
|
||||
// istClient := geth.NewIstanbulClient()
|
||||
// vals, err := istClient.GetValidators(context.Background(), big.NewInt(0))
|
||||
// if err != nil {
|
||||
// errc <- err
|
||||
// return
|
||||
// }
|
||||
// 2. Check validator set
|
||||
istClient := geth.NewIstanbulClient()
|
||||
vals, err := istClient.GetValidators(context.Background(), big.NewInt(0))
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
|
||||
// for _, val := range vals {
|
||||
// if _, ok := valSet[val]; !ok {
|
||||
// errc <- errors.New("Invalid validator address.")
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
for _, val := range vals {
|
||||
if _, ok := valSet[val]; !ok {
|
||||
errc <- errors.New("Invalid validator address.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// errc <- nil
|
||||
// }(geth)
|
||||
// }
|
||||
errc <- nil
|
||||
}(geth)
|
||||
}
|
||||
|
||||
// for i := 0; i < len(blockchain.Validators()); i++ {
|
||||
// err := <-errc
|
||||
// Expect(err).To(BeNil())
|
||||
// }
|
||||
|
||||
// })
|
||||
for i := 0; i < len(blockchain.Validators()); i++ {
|
||||
err := <-errc
|
||||
Expect(err).To(BeNil())
|
||||
}
|
||||
})
|
||||
|
||||
It("QFS-01-03: Peer connection", func(done Done) {
|
||||
expectedPeerCount := len(blockchain.Validators()) - 1
|
||||
|
@ -121,141 +126,141 @@ var _ = Describe("QFS-01: General consensus", func() {
|
|||
close(done)
|
||||
}, 20)
|
||||
|
||||
// It("TFS-01-04: Consensus progress", func(done Done) {
|
||||
// const (
|
||||
// targetBlockHeight = 10
|
||||
// maxBlockPeriod = 3
|
||||
// )
|
||||
It("QFS-01-04: Consensus progress", func(done Done) {
|
||||
const (
|
||||
targetBlockHeight = 10
|
||||
maxBlockPeriod = 3
|
||||
)
|
||||
|
||||
// By("Wait for consensus progress", func() {
|
||||
// tests.WaitFor(blockchain.Validators(), func(geth container.Ethereum, wg *sync.WaitGroup) {
|
||||
// Expect(geth.WaitForBlockHeight(targetBlockHeight)).To(BeNil())
|
||||
// wg.Done()
|
||||
// })
|
||||
// })
|
||||
By("Wait for consensus progress", func() {
|
||||
tests.WaitFor(blockchain.Validators(), func(geth container.Ethereum, wg *sync.WaitGroup) {
|
||||
Expect(geth.WaitForBlockHeight(targetBlockHeight)).To(BeNil())
|
||||
wg.Done()
|
||||
})
|
||||
})
|
||||
|
||||
// By("Check the block period should less than 3 seconds", func() {
|
||||
// errc := make(chan error, len(blockchain.Validators()))
|
||||
// for _, geth := range blockchain.Validators() {
|
||||
// go func(geth container.Ethereum) {
|
||||
// c := geth.NewClient()
|
||||
// lastBlockTime := int64(0)
|
||||
// // The reason to verify block period from block#2 is that
|
||||
// // the block period from block#1 to block#2 might take long time due to
|
||||
// // encounter several round changes at the beginning of the consensus progress.
|
||||
// for i := 2; i <= targetBlockHeight; i++ {
|
||||
// header, err := c.HeaderByNumber(context.Background(), big.NewInt(int64(i)))
|
||||
// if err != nil {
|
||||
// errc <- err
|
||||
// return
|
||||
// }
|
||||
// if lastBlockTime != 0 {
|
||||
// diff := header.Time.Int64() - lastBlockTime
|
||||
// if diff > maxBlockPeriod {
|
||||
// errStr := fmt.Sprintf("Invaild block(%v) period, want:%v, got:%v", header.Number.Int64(), maxBlockPeriod, diff)
|
||||
// errc <- errors.New(errStr)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// lastBlockTime = header.Time.Int64()
|
||||
// }
|
||||
// errc <- nil
|
||||
// }(geth)
|
||||
// }
|
||||
By("Check the block period should less than 3 seconds", func() {
|
||||
errc := make(chan error, len(blockchain.Validators()))
|
||||
for _, geth := range blockchain.Validators() {
|
||||
go func(geth container.Ethereum) {
|
||||
c := geth.NewClient()
|
||||
lastBlockTime := int64(0)
|
||||
// The reason to verify block period from block#2 is that
|
||||
// the block period from block#1 to block#2 might take long time due to
|
||||
// encounter several round changes at the beginning of the consensus progress.
|
||||
for i := 2; i <= targetBlockHeight; i++ {
|
||||
header, err := c.HeaderByNumber(context.Background(), big.NewInt(int64(i)))
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
if lastBlockTime != 0 {
|
||||
diff := header.Time.Int64() - lastBlockTime
|
||||
if diff > maxBlockPeriod {
|
||||
errStr := fmt.Sprintf("Invaild block(%v) period, want:%v, got:%v", header.Number.Int64(), maxBlockPeriod, diff)
|
||||
errc <- errors.New(errStr)
|
||||
return
|
||||
}
|
||||
}
|
||||
lastBlockTime = header.Time.Int64()
|
||||
}
|
||||
errc <- nil
|
||||
}(geth)
|
||||
}
|
||||
|
||||
// for i := 0; i < len(blockchain.Validators()); i++ {
|
||||
// err := <-errc
|
||||
// Expect(err).To(BeNil())
|
||||
// }
|
||||
// })
|
||||
// close(done)
|
||||
// }, 60)
|
||||
for i := 0; i < len(blockchain.Validators()); i++ {
|
||||
err := <-errc
|
||||
Expect(err).To(BeNil())
|
||||
}
|
||||
})
|
||||
close(done)
|
||||
}, 60)
|
||||
|
||||
// It("TFS-01-05: Round robin proposer selection", func(done Done) {
|
||||
// var (
|
||||
// timesOfBeProposer = 3
|
||||
// targetBlockHeight = timesOfBeProposer * numberOfValidators
|
||||
// emptyProposer = common.Address{}
|
||||
// )
|
||||
It("QFS-01-05: Round robin proposer selection", func(done Done) {
|
||||
var (
|
||||
timesOfBeProposer = 3
|
||||
targetBlockHeight = timesOfBeProposer * numberOfValidators
|
||||
emptyProposer = common.Address{}
|
||||
)
|
||||
|
||||
// By("Wait for consensus progress", func() {
|
||||
// tests.WaitFor(blockchain.Validators(), func(geth container.Ethereum, wg *sync.WaitGroup) {
|
||||
// Expect(geth.WaitForBlockHeight(targetBlockHeight)).To(BeNil())
|
||||
// wg.Done()
|
||||
// })
|
||||
// })
|
||||
By("Wait for consensus progress", func() {
|
||||
tests.WaitFor(blockchain.Validators(), func(geth container.Ethereum, wg *sync.WaitGroup) {
|
||||
Expect(geth.WaitForBlockHeight(targetBlockHeight)).To(BeNil())
|
||||
wg.Done()
|
||||
})
|
||||
})
|
||||
|
||||
// By("Block proposer selection should follow round-robin policy", func() {
|
||||
// errc := make(chan error, len(blockchain.Validators()))
|
||||
// for _, geth := range blockchain.Validators() {
|
||||
// go func(geth container.Ethereum) {
|
||||
// c := geth.NewClient()
|
||||
// istClient := geth.NewIstanbulClient()
|
||||
By("Block proposer selection should follow round-robin policy", func() {
|
||||
errc := make(chan error, len(blockchain.Validators()))
|
||||
for _, geth := range blockchain.Validators() {
|
||||
go func(geth container.Ethereum) {
|
||||
c := geth.NewClient()
|
||||
istClient := geth.NewIstanbulClient()
|
||||
|
||||
// // get initial validator set
|
||||
// vals, err := istClient.GetValidators(context.Background(), big.NewInt(0))
|
||||
// if err != nil {
|
||||
// errc <- err
|
||||
// return
|
||||
// }
|
||||
// get initial validator set
|
||||
vals, err := istClient.GetValidators(context.Background(), big.NewInt(0))
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
|
||||
// lastProposerIdx := -1
|
||||
// counts := make(map[common.Address]int, numberOfValidators)
|
||||
// // initial count map
|
||||
// for _, addr := range vals {
|
||||
// counts[addr] = 0
|
||||
// }
|
||||
// for i := 1; i <= targetBlockHeight; i++ {
|
||||
// header, err := c.HeaderByNumber(context.Background(), big.NewInt(int64(i)))
|
||||
// if err != nil {
|
||||
// errc <- err
|
||||
// return
|
||||
// }
|
||||
lastProposerIdx := -1
|
||||
counts := make(map[common.Address]int, numberOfValidators)
|
||||
// initial count map
|
||||
for _, addr := range vals {
|
||||
counts[addr] = 0
|
||||
}
|
||||
for i := 1; i <= targetBlockHeight; i++ {
|
||||
header, err := c.HeaderByNumber(context.Background(), big.NewInt(int64(i)))
|
||||
if err != nil {
|
||||
errc <- err
|
||||
return
|
||||
}
|
||||
|
||||
// p := container.GetProposer(header)
|
||||
// if p == emptyProposer {
|
||||
// errStr := fmt.Sprintf("Empty block(%v) proposer", header.Number.Int64())
|
||||
// errc <- errors.New(errStr)
|
||||
// return
|
||||
// }
|
||||
// // count the times to be the proposer
|
||||
// if count, ok := counts[p]; ok {
|
||||
// counts[p] = count + 1
|
||||
// }
|
||||
// // check if the proposer is valid
|
||||
// if lastProposerIdx == -1 {
|
||||
// for i, val := range vals {
|
||||
// if p == val {
|
||||
// lastProposerIdx = i
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// proposerIdx := (lastProposerIdx + 1) % len(vals)
|
||||
// if p != vals[proposerIdx] {
|
||||
// errStr := fmt.Sprintf("Invaild block(%v) proposer, want:%v, got:%v", header.Number.Int64(), vals[proposerIdx], p)
|
||||
// errc <- errors.New(errStr)
|
||||
// return
|
||||
// }
|
||||
// lastProposerIdx = proposerIdx
|
||||
// }
|
||||
// }
|
||||
// // check times to be proposer
|
||||
// for _, count := range counts {
|
||||
// if count != timesOfBeProposer {
|
||||
// errc <- errors.New("Wrong times to be proposer.")
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// errc <- nil
|
||||
// }(geth)
|
||||
// }
|
||||
p := container.GetProposer(header)
|
||||
if p == emptyProposer {
|
||||
errStr := fmt.Sprintf("Empty block(%v) proposer", header.Number.Int64())
|
||||
errc <- errors.New(errStr)
|
||||
return
|
||||
}
|
||||
// count the times to be the proposer
|
||||
if count, ok := counts[p]; ok {
|
||||
counts[p] = count + 1
|
||||
}
|
||||
// check if the proposer is valid
|
||||
if lastProposerIdx == -1 {
|
||||
for i, val := range vals {
|
||||
if p == val {
|
||||
lastProposerIdx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
proposerIdx := (lastProposerIdx + 1) % len(vals)
|
||||
if p != vals[proposerIdx] {
|
||||
errStr := fmt.Sprintf("Invaild block(%v) proposer, want:%v, got:%v", header.Number.Int64(), vals[proposerIdx], p)
|
||||
errc <- errors.New(errStr)
|
||||
return
|
||||
}
|
||||
lastProposerIdx = proposerIdx
|
||||
}
|
||||
}
|
||||
// check times to be proposer
|
||||
for _, count := range counts {
|
||||
if count != timesOfBeProposer {
|
||||
errc <- errors.New("Wrong times to be proposer.")
|
||||
return
|
||||
}
|
||||
}
|
||||
errc <- nil
|
||||
}(geth)
|
||||
}
|
||||
|
||||
// for i := 0; i < len(blockchain.Validators()); i++ {
|
||||
// err := <-errc
|
||||
// Expect(err).To(BeNil())
|
||||
// }
|
||||
// })
|
||||
// close(done)
|
||||
// }, 120)
|
||||
for i := 0; i < len(blockchain.Validators()); i++ {
|
||||
err := <-errc
|
||||
Expect(err).To(BeNil())
|
||||
}
|
||||
})
|
||||
close(done)
|
||||
}, 120)
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue