diff --git a/container/blockchain.go b/container/blockchain.go index 387303fd..096bffc7 100644 --- a/container/blockchain.go +++ b/container/blockchain.go @@ -232,17 +232,19 @@ func NewDefaultQuorumBlockchainWithFaulty(network *DockerNetwork, ctn Constellat NoDiscover(), Etherbase("1a9afb711302c5f83b5902843d1c007a1a137632"), Mine(), + SyncMode("full"), + Unlock(0), + Password("password.txt"), Logging(false), IsQuorum(true), - NoUSB(), - SyncMode("full")} + } normalOpts := make([]Option, len(commonOpts), len(commonOpts)+2) copy(normalOpts, commonOpts[:]) - normalOpts = append(normalOpts, ImageRepository("quay.io/amis/quorum"), ImageTag("latest")) + normalOpts = append(normalOpts, ImageRepository("quay.io/amis/quorum"), ImageTag("feature_istanbul")) faultyOpts := make([]Option, len(commonOpts), len(commonOpts)+3) copy(faultyOpts, commonOpts[:]) // FIXME: Needs a faulty quorum - faultyOpts = append(faultyOpts, ImageRepository("quay.io/amis/geth_faulty"), ImageTag("latest"), FaultyMode(1)) + faultyOpts = append(faultyOpts, ImageRepository("quay.io/amis/quorum_faulty"), ImageTag("latest"), FaultyMode(1)) // New env client bc = &blockchain{isQuorum: true, constellationNetwork: ctn} @@ -273,14 +275,17 @@ func NewDefaultQuorumBlockchainWithFaulty(network *DockerNetwork, ctn Constellat log.Fatalf("Failed to get free ip addresses, err: %v", err) } - keys, addrs := generateKeys(totalNodes) + //Create accounts + bc.generateAccounts(totalNodes) + + keys, _, addrs := istcommon.GenerateKeys(totalNodes) bc.setupGenesis(addrs) // Create normal validators bc.opts = normalOpts - bc.setupValidators(ips[:numOfNormal], keys[:numOfNormal], bc.opts...) + bc.setupValidators(ips[:numOfNormal], keys[:numOfNormal], 0, bc.opts...) // Create faulty validators bc.opts = faultyOpts - bc.setupValidators(ips[numOfNormal:], keys[numOfNormal:], bc.opts...) + bc.setupValidators(ips[numOfNormal:], keys[numOfNormal:], numOfNormal, bc.opts...) return bc } diff --git a/tests/quorum/functional/byzantine_faulty_test.go b/tests/quorum/functional/byzantine_faulty_test.go new file mode 100644 index 00000000..401fce96 --- /dev/null +++ b/tests/quorum/functional/byzantine_faulty_test.go @@ -0,0 +1,118 @@ +// Copyright 2017 AMIS Technologies +// This file is part of the go-ethereum library. +// +// The go-ethereum 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 go-ethereum 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 go-ethereum library. If not, see . + +package functional + +import ( + "sync" + "time" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/getamis/istanbul-tools/container" + "github.com/getamis/istanbul-tools/tests" +) + +var _ = Describe("QFS-05: Byzantine Faulty", func() { + + Context("QFS-05-01: F faulty validators", func() { + const ( + numberOfNormal = 3 + numberOfFaulty = 1 + ) + var ( + constellationNetwork container.ConstellationNetwork + blockchain container.Blockchain + ) + BeforeEach(func() { + constellationNetwork = container.NewDefaultConstellationNetwork(dockerNetwork, numberOfNormal+numberOfFaulty) + Expect(constellationNetwork.Start()).To(BeNil()) + blockchain = container.NewDefaultQuorumBlockchainWithFaulty(dockerNetwork, constellationNetwork, numberOfNormal, numberOfFaulty) + Expect(blockchain.Start(true)).To(BeNil()) + }) + + AfterEach(func() { + Expect(blockchain.Stop(false)).To(BeNil()) + blockchain.Finalize() + Expect(constellationNetwork.Stop()).To(BeNil()) + constellationNetwork.Finalize() + }) + + It("Should generate blocks", func(done Done) { + + By("Wait for p2p connection", func() { + tests.WaitFor(blockchain.Validators(), func(geth container.Ethereum, wg *sync.WaitGroup) { + Expect(geth.WaitForPeersConnected(numberOfNormal + numberOfFaulty - 1)).To(BeNil()) + wg.Done() + }) + }) + + By("Wait for blocks", func() { + const targetBlockHeight = 3 + tests.WaitFor(blockchain.Validators()[:1], func(geth container.Ethereum, wg *sync.WaitGroup) { + Expect(geth.WaitForBlocks(targetBlockHeight)).To(BeNil()) + wg.Done() + }) + }) + + close(done) + }, 60) + }) + + Context("QFS-05-01: F+1 faulty validators", func() { + const ( + numberOfNormal = 2 + numberOfFaulty = 2 + ) + var ( + constellationNetwork container.ConstellationNetwork + blockchain container.Blockchain + ) + BeforeEach(func() { + constellationNetwork = container.NewDefaultConstellationNetwork(dockerNetwork, numberOfNormal+numberOfFaulty) + Expect(constellationNetwork.Start()).To(BeNil()) + blockchain = container.NewDefaultQuorumBlockchainWithFaulty(dockerNetwork, constellationNetwork, numberOfNormal, numberOfFaulty) + Expect(blockchain.Start(true)).To(BeNil()) + }) + + AfterEach(func() { + Expect(blockchain.Stop(false)).To(BeNil()) + blockchain.Finalize() + Expect(constellationNetwork.Stop()).To(BeNil()) + constellationNetwork.Finalize() + }) + + It("Should not generate blocks", func(done Done) { + By("Wait for p2p connection", func() { + tests.WaitFor(blockchain.Validators(), func(geth container.Ethereum, wg *sync.WaitGroup) { + Expect(geth.WaitForPeersConnected(numberOfNormal + numberOfFaulty - 1)).To(BeNil()) + wg.Done() + }) + }) + + By("Wait for blocks", func() { + // Only check normal validators + tests.WaitFor(blockchain.Validators()[:2], func(geth container.Ethereum, wg *sync.WaitGroup) { + Expect(geth.WaitForNoBlocks(0, time.Second*30)).To(BeNil()) + wg.Done() + }) + }) + close(done) + }, 60) + }) + +})