tests/quorum: add general consensus test

This commit is contained in:
Miya Chen 2017-09-06 11:32:22 +08:00
parent b6522e3db0
commit 035bc07c0a
1 changed files with 186 additions and 181 deletions

View File

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