github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/e2e/e2e_test.go (about)

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package e2e
     8  
     9  import (
    10  	"bufio"
    11  	"bytes"
    12  	"context"
    13  	"crypto/sha256"
    14  	"encoding/json"
    15  	"fmt"
    16  	"io"
    17  	"io/ioutil"
    18  	"net/http"
    19  	"os"
    20  	"path"
    21  	"path/filepath"
    22  	"strings"
    23  	"syscall"
    24  	"time"
    25  
    26  	docker "github.com/fsouza/go-dockerclient"
    27  	"github.com/golang/protobuf/proto"
    28  	"github.com/hechain20/hechain/integration/channelparticipation"
    29  	"github.com/hechain20/hechain/integration/nwo"
    30  	"github.com/hechain20/hechain/integration/nwo/commands"
    31  	"github.com/hechain20/hechain/integration/nwo/fabricconfig"
    32  	"github.com/hyperledger/fabric-lib-go/healthz"
    33  	"github.com/hyperledger/fabric-protos-go/orderer/etcdraft"
    34  	. "github.com/onsi/ginkgo"
    35  	. "github.com/onsi/gomega"
    36  	"github.com/onsi/gomega/gbytes"
    37  	"github.com/onsi/gomega/gexec"
    38  	"github.com/tedsuo/ifrit"
    39  	"github.com/tedsuo/ifrit/ginkgomon"
    40  )
    41  
    42  var _ = Describe("EndToEnd", func() {
    43  	var (
    44  		testDir   string
    45  		client    *docker.Client
    46  		network   *nwo.Network
    47  		chaincode nwo.Chaincode
    48  		process   ifrit.Process
    49  	)
    50  
    51  	BeforeEach(func() {
    52  		var err error
    53  		testDir, err = ioutil.TempDir("", "e2e")
    54  		Expect(err).NotTo(HaveOccurred())
    55  
    56  		client, err = docker.NewClientFromEnv()
    57  		Expect(err).NotTo(HaveOccurred())
    58  
    59  		chaincode = nwo.Chaincode{
    60  			Name:            "mycc",
    61  			Version:         "0.0",
    62  			Path:            components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd"),
    63  			Lang:            "binary",
    64  			PackageFile:     filepath.Join(testDir, "simplecc.tar.gz"),
    65  			Ctor:            `{"Args":["init","a","100","b","200"]}`,
    66  			SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`,
    67  			Sequence:        "1",
    68  			InitRequired:    true,
    69  			Label:           "my_prebuilt_chaincode",
    70  		}
    71  	})
    72  
    73  	AfterEach(func() {
    74  		if process != nil {
    75  			process.Signal(syscall.SIGTERM)
    76  			Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
    77  		}
    78  		if network != nil {
    79  			network.Cleanup()
    80  		}
    81  		os.RemoveAll(testDir)
    82  	})
    83  
    84  	Describe("basic solo network with 2 orgs and no docker", func() {
    85  		var (
    86  			metricsReader        *MetricsReader
    87  			runArtifactsFilePath string
    88  		)
    89  
    90  		BeforeEach(func() {
    91  			metricsReader = NewMetricsReader()
    92  			go metricsReader.Start()
    93  
    94  			network = nwo.New(nwo.BasicSolo(), testDir, nil, StartPort(), components)
    95  			network.MetricsProvider = "statsd"
    96  			network.StatsdEndpoint = metricsReader.Address()
    97  			network.Consensus.ChannelParticipationEnabled = true
    98  			network.Profiles = append(network.Profiles, &nwo.Profile{
    99  				Name:          "TwoOrgsBaseProfileChannel",
   100  				Consortium:    "SampleConsortium",
   101  				Orderers:      []string{"orderer"},
   102  				Organizations: []string{"Org1", "Org2"},
   103  			})
   104  			network.Channels = append(network.Channels, &nwo.Channel{
   105  				Name:        "baseprofilechannel",
   106  				Profile:     "TwoOrgsBaseProfileChannel",
   107  				BaseProfile: "TwoOrgsOrdererGenesis",
   108  			})
   109  
   110  			runArtifactsFilePath = filepath.Join(testDir, "run-artifacts.txt")
   111  			os.Setenv("RUN_ARTIFACTS_FILE", runArtifactsFilePath)
   112  			for i, e := range network.ExternalBuilders {
   113  				e.PropagateEnvironment = append(e.PropagateEnvironment, "RUN_ARTIFACTS_FILE")
   114  				network.ExternalBuilders[i] = e
   115  			}
   116  
   117  			network.GenerateConfigTree()
   118  			for _, peer := range network.PeersWithChannel("testchannel") {
   119  				core := network.ReadPeerConfig(peer)
   120  				core.VM = nil
   121  				network.WritePeerConfig(peer, core)
   122  			}
   123  
   124  			network.Bootstrap()
   125  
   126  			networkRunner := network.NetworkGroupRunner()
   127  			process = ifrit.Invoke(networkRunner)
   128  			Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   129  		})
   130  
   131  		AfterEach(func() {
   132  			if metricsReader != nil {
   133  				metricsReader.Close()
   134  			}
   135  
   136  			// Terminate the processes but defer the network cleanup to the outer
   137  			// AfterEach.
   138  			if process != nil {
   139  				process.Signal(syscall.SIGTERM)
   140  				Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
   141  				process = nil
   142  			}
   143  
   144  			// Ensure that the temporary directories generated by launched external
   145  			// chaincodes have been cleaned up. This must be done after the peers
   146  			// have been terminated.
   147  			contents, err := ioutil.ReadFile(runArtifactsFilePath)
   148  			Expect(err).NotTo(HaveOccurred())
   149  			scanner := bufio.NewScanner(bytes.NewBuffer(contents))
   150  			for scanner.Scan() {
   151  				Expect(scanner.Text()).NotTo(BeAnExistingFile())
   152  			}
   153  		})
   154  
   155  		It("executes a basic solo network with 2 orgs and no docker", func() {
   156  			By("getting the orderer by name")
   157  			orderer := network.Orderer("orderer")
   158  
   159  			By("setting up the channel")
   160  			network.CreateAndJoinChannel(orderer, "testchannel")
   161  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   162  
   163  			By("listing channels with osnadmin")
   164  			tlsdir := network.OrdererLocalTLSDir(orderer)
   165  			sess, err := network.Osnadmin(commands.ChannelList{
   166  				OrdererAddress: network.OrdererAddress(orderer, nwo.AdminPort),
   167  				CAFile:         filepath.Join(tlsdir, "ca.crt"),
   168  				ClientCert:     filepath.Join(tlsdir, "server.crt"),
   169  				ClientKey:      filepath.Join(tlsdir, "server.key"),
   170  			})
   171  			Expect(err).NotTo(HaveOccurred())
   172  			Eventually(sess).Should(gexec.Exit(0))
   173  			var channelList channelparticipation.ChannelList
   174  			err = json.Unmarshal(sess.Out.Contents(), &channelList)
   175  			Expect(err).NotTo(HaveOccurred())
   176  			Expect(channelList).To(Equal(channelparticipation.ChannelList{
   177  				SystemChannel: &channelparticipation.ChannelInfoShort{
   178  					Name: "systemchannel",
   179  					URL:  "/participation/v1/channels/systemchannel",
   180  				},
   181  				Channels: []channelparticipation.ChannelInfoShort{{
   182  					Name: "testchannel",
   183  					URL:  "/participation/v1/channels/testchannel",
   184  				}},
   185  			}))
   186  
   187  			By("attempting to install unsupported chaincode without docker")
   188  			badCC := chaincode
   189  			badCC.Lang = "unsupported-type"
   190  			badCC.Label = "chaincode-label"
   191  			badCC.PackageFile = filepath.Join(testDir, "unsupported-type.tar.gz")
   192  			nwo.PackageChaincodeBinary(badCC)
   193  			badCC.SetPackageIDFromPackageFile()
   194  			sess, err = network.PeerAdminSession(
   195  				network.Peer("Org1", "peer0"),
   196  				commands.ChaincodeInstall{
   197  					PackageFile: badCC.PackageFile,
   198  					ClientAuth:  network.ClientAuthRequired,
   199  				},
   200  			)
   201  			Expect(err).NotTo(HaveOccurred())
   202  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   203  			Expect(sess.Err).To(gbytes.Say("docker build is disabled"))
   204  
   205  			By("deploying the chaincode")
   206  			nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
   207  
   208  			By("ensuring external cc run artifacts exist after deploying")
   209  			contents, err := ioutil.ReadFile(runArtifactsFilePath)
   210  			Expect(err).NotTo(HaveOccurred())
   211  			scanner := bufio.NewScanner(bytes.NewBuffer(contents))
   212  			for scanner.Scan() {
   213  				Expect(scanner.Text()).To(BeADirectory())
   214  			}
   215  
   216  			By("getting the client peer by name")
   217  			peer := network.Peer("Org1", "peer0")
   218  
   219  			RunQueryInvokeQuery(network, orderer, peer, "testchannel")
   220  			RunRespondWith(network, orderer, peer, "testchannel")
   221  
   222  			By("evaluating statsd metrics")
   223  			metricsWriteInterval := 5 * time.Second
   224  			CheckPeerStatsdStreamMetrics(metricsReader, 2*metricsWriteInterval)
   225  			CheckPeerStatsdMetrics("org1_peer0", metricsReader, 2*metricsWriteInterval)
   226  			CheckPeerStatsdMetrics("org2_peer0", metricsReader, 2*metricsWriteInterval)
   227  
   228  			By("checking for orderer metrics")
   229  			CheckOrdererStatsdMetrics("ordererorg_orderer", metricsReader, 2*metricsWriteInterval)
   230  
   231  			By("setting up a channel from a base profile")
   232  			additionalPeer := network.Peer("Org2", "peer0")
   233  			network.CreateChannel("baseprofilechannel", orderer, peer, additionalPeer)
   234  		})
   235  	})
   236  
   237  	Describe("basic etcdraft network with docker chaincode builds", func() {
   238  		BeforeEach(func() {
   239  			network = nwo.New(nwo.MultiChannelEtcdRaft(), testDir, client, StartPort(), components)
   240  			network.Consensus.ChannelParticipationEnabled = true
   241  			network.MetricsProvider = "prometheus"
   242  			network.GenerateConfigTree()
   243  			network.Bootstrap()
   244  
   245  			networkRunner := network.NetworkGroupRunner()
   246  			process = ifrit.Invoke(networkRunner)
   247  			Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   248  		})
   249  
   250  		It("builds and executes transactions with docker chaincode", func() {
   251  			chaincodePath, err := filepath.Abs("../chaincode/module")
   252  			Expect(err).NotTo(HaveOccurred())
   253  
   254  			// use these two variants of the same chaincode to ensure we test
   255  			// the golang docker build for both module and gopath chaincode
   256  			chaincode := nwo.Chaincode{
   257  				Name:            "mycc",
   258  				Version:         "0.0",
   259  				Path:            chaincodePath,
   260  				Lang:            "golang",
   261  				PackageFile:     filepath.Join(testDir, "modulecc.tar.gz"),
   262  				Ctor:            `{"Args":["init","a","100","b","200"]}`,
   263  				SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`,
   264  				Sequence:        "1",
   265  				InitRequired:    true,
   266  				Label:           "my_module_chaincode",
   267  			}
   268  
   269  			gopathChaincode := nwo.Chaincode{
   270  				Name:            "mycc",
   271  				Version:         "0.0",
   272  				Path:            "github.com/hechain20/hechain/integration/chaincode/simple/cmd",
   273  				Lang:            "golang",
   274  				PackageFile:     filepath.Join(testDir, "simplecc.tar.gz"),
   275  				Ctor:            `{"Args":["init","a","100","b","200"]}`,
   276  				SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`,
   277  				Sequence:        "1",
   278  				InitRequired:    true,
   279  				Label:           "my_simple_chaincode",
   280  			}
   281  
   282  			orderer := network.Orderer("orderer")
   283  
   284  			network.CreateAndJoinChannel(orderer, "testchannel")
   285  			cl := channelparticipation.List(network, orderer)
   286  			channelparticipation.ChannelListMatcher(cl, []string{"testchannel"}, []string{"systemchannel"}...)
   287  
   288  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   289  
   290  			// package, install, and approve by org1 - module chaincode
   291  			packageInstallApproveChaincode(network, "testchannel", orderer, chaincode, network.Peer("Org1", "peer0"))
   292  
   293  			// package, install, and approve by org2 - gopath chaincode, same logic
   294  			packageInstallApproveChaincode(network, "testchannel", orderer, gopathChaincode, network.Peer("Org2", "peer0"))
   295  
   296  			testPeers := network.PeersWithChannel("testchannel")
   297  			nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, network.PeerOrgs(), testPeers...)
   298  			nwo.CommitChaincode(network, "testchannel", orderer, chaincode, testPeers[0], testPeers...)
   299  			nwo.InitChaincode(network, "testchannel", orderer, chaincode, testPeers...)
   300  
   301  			By("listing the containers after committing the chaincode definition")
   302  			initialContainerFilter := map[string][]string{
   303  				"name": {
   304  					chaincodeContainerNameFilter(network, chaincode),
   305  					chaincodeContainerNameFilter(network, gopathChaincode),
   306  				},
   307  			}
   308  
   309  			containers, err := client.ListContainers(docker.ListContainersOptions{Filters: initialContainerFilter})
   310  			Expect(err).NotTo(HaveOccurred())
   311  			Expect(containers).To(HaveLen(2))
   312  
   313  			RunQueryInvokeQuery(network, orderer, network.Peer("Org1", "peer0"), "testchannel")
   314  
   315  			By("evaluating the operations endpoint and prometheus metrics")
   316  			CheckPeerOperationEndpoints(network, network.Peer("Org2", "peer0"))
   317  			CheckOrdererOperationEndpoints(network, orderer)
   318  
   319  			// upgrade chaincode to v2.0 with different label
   320  			chaincode.Version = "1.0"
   321  			chaincode.Sequence = "2"
   322  			chaincode.Label = "my_module_chaincode_updated"
   323  			gopathChaincode.Version = "1.0"
   324  			gopathChaincode.Sequence = "2"
   325  			gopathChaincode.Label = "my_simple_chaincode_updated"
   326  
   327  			// package, install, and approve by org1 - module chaincode
   328  			packageInstallApproveChaincode(network, "testchannel", orderer, chaincode, network.Peer("Org1", "peer0"))
   329  
   330  			// package, install, and approve by org2 - gopath chaincode, same logic
   331  			packageInstallApproveChaincode(network, "testchannel", orderer, gopathChaincode, network.Peer("Org2", "peer0"))
   332  
   333  			nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, network.PeerOrgs(), testPeers...)
   334  			nwo.CommitChaincode(network, "testchannel", orderer, chaincode, testPeers[0], testPeers...)
   335  			nwo.InitChaincode(network, "testchannel", orderer, chaincode, testPeers...)
   336  
   337  			By("listing the containers after updating the chaincode definition")
   338  			// expect the containers for the previous package id to be stopped
   339  			containers, err = client.ListContainers(docker.ListContainersOptions{Filters: initialContainerFilter})
   340  			Expect(err).NotTo(HaveOccurred())
   341  			Expect(containers).To(HaveLen(0))
   342  			updatedContainerFilter := map[string][]string{
   343  				"name": {
   344  					chaincodeContainerNameFilter(network, chaincode),
   345  					chaincodeContainerNameFilter(network, gopathChaincode),
   346  				},
   347  			}
   348  			containers, err = client.ListContainers(docker.ListContainersOptions{Filters: updatedContainerFilter})
   349  			Expect(err).NotTo(HaveOccurred())
   350  			Expect(containers).To(HaveLen(2))
   351  
   352  			RunQueryInvokeQuery(network, orderer, network.Peer("Org1", "peer0"), "testchannel")
   353  
   354  			By("retrieving the local mspid of the peer via simple chaincode")
   355  			sess, err := network.PeerUserSession(network.Peer("Org2", "peer0"), "User1", commands.ChaincodeQuery{
   356  				ChannelID: "testchannel",
   357  				Name:      "mycc",
   358  				Ctor:      `{"Args":["mspid"]}`,
   359  			})
   360  			Expect(err).NotTo(HaveOccurred())
   361  			Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   362  			Expect(sess).To(gbytes.Say("Org2MSP"))
   363  		})
   364  	})
   365  
   366  	Describe("basic single node etcdraft network with static leader", func() {
   367  		var (
   368  			peerRunners    []*ginkgomon.Runner
   369  			processes      map[string]ifrit.Process
   370  			ordererProcess ifrit.Process
   371  		)
   372  
   373  		BeforeEach(func() {
   374  			network = nwo.New(nwo.MultiChannelEtcdRaft(), testDir, client, StartPort(), components)
   375  			network.Consensus.ChannelParticipationEnabled = true
   376  			network.GenerateConfigTree()
   377  			for _, peer := range network.Peers {
   378  				core := network.ReadPeerConfig(peer)
   379  				core.Peer.Gossip.UseLeaderElection = false
   380  				core.Peer.Gossip.OrgLeader = true
   381  				core.Peer.Deliveryclient.ReconnectTotalTimeThreshold = time.Duration(time.Second)
   382  				network.WritePeerConfig(peer, core)
   383  			}
   384  			network.Bootstrap()
   385  
   386  			ordererRunner := network.OrdererGroupRunner()
   387  			ordererProcess = ifrit.Invoke(ordererRunner)
   388  			Eventually(ordererProcess.Ready(), network.EventuallyTimeout).Should(BeClosed())
   389  
   390  			peerRunners = make([]*ginkgomon.Runner, len(network.Peers))
   391  			processes = map[string]ifrit.Process{}
   392  			for i, peer := range network.Peers {
   393  				pr := network.PeerRunner(peer)
   394  				peerRunners[i] = pr
   395  				p := ifrit.Invoke(pr)
   396  				processes[peer.ID()] = p
   397  				Eventually(p.Ready(), network.EventuallyTimeout).Should(BeClosed())
   398  			}
   399  		})
   400  
   401  		AfterEach(func() {
   402  			if ordererProcess != nil {
   403  				ordererProcess.Signal(syscall.SIGTERM)
   404  				Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
   405  			}
   406  			for _, p := range processes {
   407  				p.Signal(syscall.SIGTERM)
   408  				Eventually(p.Wait(), network.EventuallyTimeout).Should(Receive())
   409  			}
   410  		})
   411  
   412  		It("creates two channels with two orgs trying to reconfigure and update metadata", func() {
   413  			orderer := network.Orderer("orderer")
   414  			peer := network.Peer("Org1", "peer0")
   415  
   416  			By("Create first channel and deploy the chaincode")
   417  			network.CreateAndJoinChannel(orderer, "testchannel")
   418  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   419  			nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
   420  			RunQueryInvokeQuery(network, orderer, peer, "testchannel")
   421  
   422  			By("Create second channel and deploy chaincode")
   423  			network.CreateAndJoinChannel(orderer, "testchannel2")
   424  			cl := channelparticipation.List(network, orderer)
   425  			channelparticipation.ChannelListMatcher(cl, []string{"testchannel", "testchannel2"}, []string{"systemchannel"}...)
   426  
   427  			peers := network.PeersWithChannel("testchannel2")
   428  			nwo.EnableCapabilities(network, "testchannel2", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   429  			nwo.ApproveChaincodeForMyOrg(network, "testchannel2", orderer, chaincode, peers...)
   430  			nwo.CheckCommitReadinessUntilReady(network, "testchannel2", chaincode, network.PeerOrgs(), peers...)
   431  			nwo.CommitChaincode(network, "testchannel2", orderer, chaincode, peers[0], peers...)
   432  			nwo.InitChaincode(network, "testchannel2", orderer, chaincode, peers...)
   433  			RunQueryInvokeQuery(network, orderer, peer, "testchannel2")
   434  
   435  			By("Update consensus metadata to increase snapshot interval")
   436  			snapDir := path.Join(network.RootDir, "orderers", orderer.ID(), "etcdraft", "snapshot", "testchannel")
   437  			files, err := ioutil.ReadDir(snapDir)
   438  			Expect(err).NotTo(HaveOccurred())
   439  			numOfSnaps := len(files)
   440  
   441  			nwo.UpdateConsensusMetadata(network, peer, orderer, "testchannel", func(originalMetadata []byte) []byte {
   442  				metadata := &etcdraft.ConfigMetadata{}
   443  				err := proto.Unmarshal(originalMetadata, metadata)
   444  				Expect(err).NotTo(HaveOccurred())
   445  
   446  				// update max in flight messages
   447  				metadata.Options.MaxInflightBlocks = 1000
   448  				metadata.Options.SnapshotIntervalSize = 10 * 1024 * 1024 // 10 MB
   449  
   450  				// write metadata back
   451  				newMetadata, err := proto.Marshal(metadata)
   452  				Expect(err).NotTo(HaveOccurred())
   453  				return newMetadata
   454  			})
   455  
   456  			// assert that no new snapshot is taken because SnapshotIntervalSize has just enlarged
   457  			files, err = ioutil.ReadDir(snapDir)
   458  			Expect(err).NotTo(HaveOccurred())
   459  			Expect(len(files)).To(Equal(numOfSnaps))
   460  
   461  			By("ensuring that static leaders do not give up on retrieving blocks after the orderer goes down")
   462  			ordererProcess.Signal(syscall.SIGTERM)
   463  			Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
   464  			for _, peerRunner := range peerRunners {
   465  				Eventually(peerRunner.Err(), network.EventuallyTimeout).Should(gbytes.Say("peer is a static leader, ignoring peer.deliveryclient.reconnectTotalTimeThreshold"))
   466  			}
   467  		})
   468  	})
   469  
   470  	Describe("single node etcdraft network with remapped orderer endpoints", func() {
   471  		BeforeEach(func() {
   472  			network = nwo.New(nwo.MinimalRaft(), testDir, client, StartPort(), components)
   473  			network.GenerateConfigTree()
   474  
   475  			configtxConfig := network.ReadConfigTxConfig()
   476  			ordererEndpoints := configtxConfig.Profiles["SampleDevModeEtcdRaft"].Orderer.Organizations[0].OrdererEndpoints
   477  			correctOrdererEndpoint := ordererEndpoints[0]
   478  			ordererEndpoints[0] = "127.0.0.1:1"
   479  			network.WriteConfigTxConfig(configtxConfig)
   480  
   481  			peer := network.Peer("Org1", "peer0")
   482  			peerConfig := network.ReadPeerConfig(peer)
   483  			peerConfig.Peer.Deliveryclient.AddressOverrides = []*fabricconfig.AddressOverride{
   484  				{
   485  					From:        "127.0.0.1:1",
   486  					To:          correctOrdererEndpoint,
   487  					CACertsFile: network.CACertsBundlePath(),
   488  				},
   489  			}
   490  			network.WritePeerConfig(peer, peerConfig)
   491  
   492  			network.Bootstrap()
   493  
   494  			networkRunner := network.NetworkGroupRunner()
   495  			process = ifrit.Invoke(networkRunner)
   496  			Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   497  		})
   498  
   499  		It("creates and updates channel", func() {
   500  			orderer := network.Orderer("orderer")
   501  
   502  			network.CreateAndJoinChannel(orderer, "testchannel")
   503  
   504  			// The below call waits for the config update to commit on the peer, so
   505  			// it will fail if the orderer addresses are wrong.
   506  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   507  		})
   508  	})
   509  
   510  	Describe("basic solo network with containers being interrupted", func() {
   511  		BeforeEach(func() {
   512  			network = nwo.New(nwo.FullSolo(), testDir, client, StartPort(), components)
   513  
   514  			network.GenerateConfigTree()
   515  			network.Bootstrap()
   516  
   517  			networkRunner := network.NetworkGroupRunner()
   518  			process = ifrit.Invoke(networkRunner)
   519  			Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   520  		})
   521  
   522  		It("recreates terminated chaincode containers", func() {
   523  			chaincode := nwo.Chaincode{
   524  				Name:            "mycc",
   525  				Version:         "0.0",
   526  				Path:            "github.com/hechain20/hechain/integration/chaincode/simple/cmd",
   527  				Lang:            "golang",
   528  				PackageFile:     filepath.Join(testDir, "simplecc.tar.gz"),
   529  				Ctor:            `{"Args":["init","a","100","b","200"]}`,
   530  				SignaturePolicy: `OR ('Org1MSP.peer', 'Org2MSP.peer')`,
   531  				Sequence:        "1",
   532  				InitRequired:    true,
   533  				Label:           "my_simple_chaincode",
   534  			}
   535  
   536  			peer := network.Peers[0]
   537  			orderer := network.Orderer("orderer")
   538  
   539  			By("creating and joining channels")
   540  			network.CreateAndJoinChannels(orderer)
   541  
   542  			By("enabling new lifecycle capabilities")
   543  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   544  			By("deploying the chaincode")
   545  			nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
   546  
   547  			By("querying and invoking chaincode")
   548  			RunQueryInvokeQuery(network, orderer, peer, "testchannel")
   549  
   550  			By("removing chaincode containers from all peers")
   551  			listChaincodeContainers := docker.ListContainersOptions{
   552  				Filters: map[string][]string{
   553  					"name": {chaincodeContainerNameFilter(network, chaincode)},
   554  				},
   555  			}
   556  			ctx := context.Background()
   557  			containers, err := client.ListContainers(listChaincodeContainers)
   558  			Expect(err).NotTo(HaveOccurred())
   559  			Expect(containers).NotTo(BeEmpty())
   560  
   561  			var originalContainerIDs []string
   562  			for _, container := range containers {
   563  				originalContainerIDs = append(originalContainerIDs, container.ID)
   564  				err = client.RemoveContainer(docker.RemoveContainerOptions{
   565  					ID:            container.ID,
   566  					RemoveVolumes: true,
   567  					Force:         true,
   568  					Context:       ctx,
   569  				})
   570  				Expect(err).NotTo(HaveOccurred())
   571  			}
   572  
   573  			By("invoking chaincode against all peers in test channel")
   574  			for _, peer := range network.Peers {
   575  				sess, err := network.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
   576  					ChannelID: "testchannel",
   577  					Orderer:   network.OrdererAddress(orderer, nwo.ListenPort),
   578  					Name:      "mycc",
   579  					Ctor:      `{"Args":["invoke","a","b","10"]}`,
   580  					PeerAddresses: []string{
   581  						network.PeerAddress(peer, nwo.ListenPort),
   582  					},
   583  					WaitForEvent: true,
   584  				})
   585  				Expect(err).NotTo(HaveOccurred())
   586  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   587  				Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
   588  			}
   589  
   590  			By("checking successful removals of all old chaincode containers")
   591  			newContainers, err := client.ListContainers(listChaincodeContainers)
   592  			Expect(err).NotTo(HaveOccurred())
   593  			Expect(newContainers).To(HaveLen(len(containers)))
   594  
   595  			for _, container := range newContainers {
   596  				Expect(originalContainerIDs).NotTo(ContainElement(container.ID))
   597  			}
   598  		})
   599  	})
   600  })
   601  
   602  func RunQueryInvokeQuery(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channel string) {
   603  	By("querying the chaincode")
   604  	sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
   605  		ChannelID: channel,
   606  		Name:      "mycc",
   607  		Ctor:      `{"Args":["query","a"]}`,
   608  	})
   609  	Expect(err).NotTo(HaveOccurred())
   610  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   611  	Expect(sess).To(gbytes.Say("100"))
   612  
   613  	sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
   614  		ChannelID: channel,
   615  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
   616  		Name:      "mycc",
   617  		Ctor:      `{"Args":["invoke","a","b","10"]}`,
   618  		PeerAddresses: []string{
   619  			n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort),
   620  			n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort),
   621  		},
   622  		WaitForEvent: true,
   623  	})
   624  	Expect(err).NotTo(HaveOccurred())
   625  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   626  	Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
   627  
   628  	sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeQuery{
   629  		ChannelID: channel,
   630  		Name:      "mycc",
   631  		Ctor:      `{"Args":["query","a"]}`,
   632  	})
   633  	Expect(err).NotTo(HaveOccurred())
   634  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   635  	Expect(sess).To(gbytes.Say("90"))
   636  }
   637  
   638  func RunRespondWith(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channel string) {
   639  	By("responding with a 300")
   640  	sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
   641  		ChannelID: channel,
   642  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
   643  		Name:      "mycc",
   644  		Ctor:      `{"Args":["respond","300","response-message","response-payload"]}`,
   645  		PeerAddresses: []string{
   646  			n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort),
   647  			n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort),
   648  		},
   649  		WaitForEvent: true,
   650  	})
   651  	Expect(err).NotTo(HaveOccurred())
   652  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   653  	Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:300"))
   654  
   655  	By("responding with a 400")
   656  	sess, err = n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
   657  		ChannelID: channel,
   658  		Orderer:   n.OrdererAddress(orderer, nwo.ListenPort),
   659  		Name:      "mycc",
   660  		Ctor:      `{"Args":["respond","400","response-message","response-payload"]}`,
   661  		PeerAddresses: []string{
   662  			n.PeerAddress(n.Peer("Org1", "peer0"), nwo.ListenPort),
   663  			n.PeerAddress(n.Peer("Org2", "peer0"), nwo.ListenPort),
   664  		},
   665  		WaitForEvent: true,
   666  	})
   667  	Expect(err).NotTo(HaveOccurred())
   668  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(1))
   669  	Expect(sess.Err).To(gbytes.Say(`Error: endorsement failure during invoke.`))
   670  }
   671  
   672  func CheckPeerStatsdMetrics(prefix string, mr *MetricsReader, timeout time.Duration) {
   673  	By("checking for peer statsd metrics")
   674  	Eventually(mr.String, timeout).Should(SatisfyAll(
   675  		ContainSubstring(prefix+".logging.entries_checked.info:"),
   676  		ContainSubstring(prefix+".logging.entries_written.info:"),
   677  		ContainSubstring(prefix+".go.mem.gc_completed_count:"),
   678  		ContainSubstring(prefix+".grpc.server.unary_requests_received.protos_Endorser.ProcessProposal:"),
   679  		ContainSubstring(prefix+".grpc.server.unary_requests_completed.protos_Endorser.ProcessProposal.OK:"),
   680  		ContainSubstring(prefix+".grpc.server.unary_request_duration.protos_Endorser.ProcessProposal.OK:"),
   681  		ContainSubstring(prefix+".ledger.blockchain_height"),
   682  		ContainSubstring(prefix+".ledger.blockstorage_commit_time"),
   683  		ContainSubstring(prefix+".ledger.blockstorage_and_pvtdata_commit_time"),
   684  	))
   685  }
   686  
   687  func CheckPeerStatsdStreamMetrics(mr *MetricsReader, timeout time.Duration) {
   688  	By("checking for stream metrics")
   689  	Eventually(mr.String, timeout).Should(SatisfyAll(
   690  		ContainSubstring(".grpc.server.stream_requests_received.protos_Deliver.DeliverFiltered:"),
   691  		ContainSubstring(".grpc.server.stream_requests_completed.protos_Deliver.DeliverFiltered.Unknown:"),
   692  		ContainSubstring(".grpc.server.stream_request_duration.protos_Deliver.DeliverFiltered.Unknown:"),
   693  		ContainSubstring(".grpc.server.stream_messages_received.protos_Deliver.DeliverFiltered"),
   694  		ContainSubstring(".grpc.server.stream_messages_sent.protos_Deliver.DeliverFiltered"),
   695  	))
   696  }
   697  
   698  func CheckOrdererStatsdMetrics(prefix string, mr *MetricsReader, timeout time.Duration) {
   699  	Eventually(mr.String, timeout).Should(SatisfyAll(
   700  		ContainSubstring(prefix+".grpc.server.stream_request_duration.orderer_AtomicBroadcast.Broadcast.OK"),
   701  		ContainSubstring(prefix+".grpc.server.stream_request_duration.orderer_AtomicBroadcast.Deliver."),
   702  		ContainSubstring(prefix+".logging.entries_checked.info:"),
   703  		ContainSubstring(prefix+".logging.entries_written.info:"),
   704  		ContainSubstring(prefix+".go.mem.gc_completed_count:"),
   705  		ContainSubstring(prefix+".grpc.server.stream_requests_received.orderer_AtomicBroadcast.Deliver:"),
   706  		ContainSubstring(prefix+".grpc.server.stream_requests_completed.orderer_AtomicBroadcast.Deliver."),
   707  		ContainSubstring(prefix+".grpc.server.stream_messages_received.orderer_AtomicBroadcast.Deliver"),
   708  		ContainSubstring(prefix+".grpc.server.stream_messages_sent.orderer_AtomicBroadcast.Deliver"),
   709  		ContainSubstring(prefix+".ledger.blockchain_height"),
   710  		ContainSubstring(prefix+".ledger.blockstorage_commit_time"),
   711  	))
   712  }
   713  
   714  func CheckPeerOperationEndpoints(network *nwo.Network, peer *nwo.Peer) {
   715  	metricsURL := fmt.Sprintf("https://127.0.0.1:%d/metrics", network.PeerPort(peer, nwo.OperationsPort))
   716  	logspecURL := fmt.Sprintf("https://127.0.0.1:%d/logspec", network.PeerPort(peer, nwo.OperationsPort))
   717  	healthURL := fmt.Sprintf("https://127.0.0.1:%d/healthz", network.PeerPort(peer, nwo.OperationsPort))
   718  
   719  	authClient, unauthClient := nwo.PeerOperationalClients(network, peer)
   720  
   721  	CheckPeerPrometheusMetrics(authClient, metricsURL)
   722  	CheckLogspecOperations(authClient, logspecURL)
   723  	CheckHealthEndpoint(authClient, healthURL)
   724  
   725  	By("getting the logspec without a client cert")
   726  	resp, err := unauthClient.Get(logspecURL)
   727  	Expect(err).NotTo(HaveOccurred())
   728  	Expect(resp.StatusCode).To(Equal(http.StatusUnauthorized))
   729  
   730  	By("ensuring health checks do not require a client cert")
   731  	CheckHealthEndpoint(unauthClient, healthURL)
   732  }
   733  
   734  func CheckOrdererOperationEndpoints(network *nwo.Network, orderer *nwo.Orderer) {
   735  	metricsURL := fmt.Sprintf("https://127.0.0.1:%d/metrics", network.OrdererPort(orderer, nwo.OperationsPort))
   736  	logspecURL := fmt.Sprintf("https://127.0.0.1:%d/logspec", network.OrdererPort(orderer, nwo.OperationsPort))
   737  	healthURL := fmt.Sprintf("https://127.0.0.1:%d/healthz", network.OrdererPort(orderer, nwo.OperationsPort))
   738  
   739  	authClient, unauthClient := nwo.OrdererOperationalClients(network, orderer)
   740  
   741  	CheckOrdererPrometheusMetrics(authClient, metricsURL)
   742  	CheckLogspecOperations(authClient, logspecURL)
   743  	CheckHealthEndpoint(authClient, healthURL)
   744  
   745  	By("getting the logspec without a client cert")
   746  	resp, err := unauthClient.Get(logspecURL)
   747  	Expect(err).NotTo(HaveOccurred())
   748  	Expect(resp.StatusCode).To(Equal(http.StatusUnauthorized))
   749  
   750  	By("ensuring health checks do not require a client cert")
   751  	CheckHealthEndpoint(unauthClient, healthURL)
   752  }
   753  
   754  func CheckPeerPrometheusMetrics(client *http.Client, url string) {
   755  	By("hitting the prometheus metrics endpoint")
   756  	resp, err := client.Get(url)
   757  	Expect(err).NotTo(HaveOccurred())
   758  	Expect(resp.StatusCode).To(Equal(http.StatusOK))
   759  	resp.Body.Close()
   760  
   761  	Eventually(getBody(client, url)).Should(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`))
   762  
   763  	By("checking for some expected metrics")
   764  	body := getBody(client, url)()
   765  	Expect(body).To(ContainSubstring(`# TYPE go_gc_duration_seconds summary`))
   766  	Expect(body).To(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`))
   767  	Expect(body).To(ContainSubstring(`grpc_server_stream_request_duration_count{code="Unknown",method="DeliverFiltered",service="protos_Deliver"}`))
   768  	Expect(body).To(ContainSubstring(`grpc_server_stream_messages_received{method="DeliverFiltered",service="protos_Deliver"}`))
   769  	Expect(body).To(ContainSubstring(`grpc_server_stream_messages_sent{method="DeliverFiltered",service="protos_Deliver"}`))
   770  	Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_closed counter`))
   771  	Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_opened counter`))
   772  	Expect(body).To(ContainSubstring(`ledger_blockchain_height`))
   773  	Expect(body).To(ContainSubstring(`ledger_blockstorage_commit_time_bucket`))
   774  	Expect(body).To(ContainSubstring(`ledger_blockstorage_and_pvtdata_commit_time_bucket`))
   775  }
   776  
   777  func CheckOrdererPrometheusMetrics(client *http.Client, url string) {
   778  	By("hitting the prometheus metrics endpoint")
   779  	resp, err := client.Get(url)
   780  	Expect(err).NotTo(HaveOccurred())
   781  	Expect(resp.StatusCode).To(Equal(http.StatusOK))
   782  	resp.Body.Close()
   783  
   784  	Eventually(getBody(client, url)).Should(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`))
   785  
   786  	By("checking for some expected metrics")
   787  	body := getBody(client, url)()
   788  	Expect(body).To(ContainSubstring(`# TYPE go_gc_duration_seconds summary`))
   789  	Expect(body).To(ContainSubstring(`# TYPE grpc_server_stream_request_duration histogram`))
   790  	Expect(body).To(ContainSubstring(`grpc_server_stream_request_duration_sum{code="OK",method="Deliver",service="orderer_AtomicBroadcast"`))
   791  	Expect(body).To(ContainSubstring(`grpc_server_stream_request_duration_sum{code="OK",method="Broadcast",service="orderer_AtomicBroadcast"`))
   792  	Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_closed counter`))
   793  	Expect(body).To(ContainSubstring(`# TYPE grpc_comm_conn_opened counter`))
   794  	Expect(body).To(ContainSubstring(`ledger_blockchain_height`))
   795  	Expect(body).To(ContainSubstring(`ledger_blockstorage_commit_time_bucket`))
   796  }
   797  
   798  func CheckLogspecOperations(client *http.Client, logspecURL string) {
   799  	By("getting the logspec")
   800  	resp, err := client.Get(logspecURL)
   801  	Expect(err).NotTo(HaveOccurred())
   802  	Expect(resp.StatusCode).To(Equal(http.StatusOK))
   803  	bodyBytes, err := ioutil.ReadAll(resp.Body)
   804  	resp.Body.Close()
   805  	Expect(err).NotTo(HaveOccurred())
   806  	Expect(string(bodyBytes)).To(MatchJSON(`{"spec":"info"}`))
   807  
   808  	updateReq, err := http.NewRequest(http.MethodPut, logspecURL, strings.NewReader(`{"spec":"debug"}`))
   809  	Expect(err).NotTo(HaveOccurred())
   810  
   811  	By("setting the logspec")
   812  	resp, err = client.Do(updateReq)
   813  	Expect(err).NotTo(HaveOccurred())
   814  	Expect(resp.StatusCode).To(Equal(http.StatusNoContent))
   815  	resp.Body.Close()
   816  
   817  	resp, err = client.Get(logspecURL)
   818  	Expect(err).NotTo(HaveOccurred())
   819  	Expect(resp.StatusCode).To(Equal(http.StatusOK))
   820  	bodyBytes, err = ioutil.ReadAll(resp.Body)
   821  	resp.Body.Close()
   822  	Expect(err).NotTo(HaveOccurred())
   823  	Expect(string(bodyBytes)).To(MatchJSON(`{"spec":"debug"}`))
   824  
   825  	By("resetting the logspec")
   826  	updateReq, err = http.NewRequest(http.MethodPut, logspecURL, strings.NewReader(`{"spec":"info"}`))
   827  	Expect(err).NotTo(HaveOccurred())
   828  	resp, err = client.Do(updateReq)
   829  	Expect(err).NotTo(HaveOccurred())
   830  	Expect(resp.StatusCode).To(Equal(http.StatusNoContent))
   831  	resp.Body.Close()
   832  }
   833  
   834  func CheckHealthEndpoint(client *http.Client, url string) {
   835  	body := getBody(client, url)()
   836  
   837  	var healthStatus healthz.HealthStatus
   838  	err := json.Unmarshal([]byte(body), &healthStatus)
   839  	Expect(err).NotTo(HaveOccurred())
   840  	Expect(healthStatus.Status).To(Equal(healthz.StatusOK))
   841  }
   842  
   843  func getBody(client *http.Client, url string) func() string {
   844  	return func() string {
   845  		resp, err := client.Get(url)
   846  		Expect(err).NotTo(HaveOccurred())
   847  		Expect(resp.StatusCode).To(Equal(http.StatusOK))
   848  		bodyBytes, err := ioutil.ReadAll(resp.Body)
   849  		Expect(err).NotTo(HaveOccurred())
   850  		resp.Body.Close()
   851  		return string(bodyBytes)
   852  	}
   853  }
   854  
   855  func packageInstallApproveChaincode(network *nwo.Network, channel string, orderer *nwo.Orderer, chaincode nwo.Chaincode, peers ...*nwo.Peer) {
   856  	nwo.PackageChaincode(network, chaincode, peers[0])
   857  	nwo.InstallChaincode(network, chaincode, peers...)
   858  	nwo.ApproveChaincodeForMyOrg(network, channel, orderer, chaincode, peers...)
   859  }
   860  
   861  func hashFile(file string) string {
   862  	f, err := os.Open(file)
   863  	Expect(err).NotTo(HaveOccurred())
   864  	defer f.Close()
   865  
   866  	h := sha256.New()
   867  	_, err = io.Copy(h, f)
   868  	Expect(err).NotTo(HaveOccurred())
   869  
   870  	return fmt.Sprintf("%x", h.Sum(nil))
   871  }
   872  
   873  func chaincodeContainerNameFilter(n *nwo.Network, chaincode nwo.Chaincode) string {
   874  	return fmt.Sprintf("^/%s-.*-%s-%s$", n.NetworkID, chaincode.Label, hashFile(chaincode.PackageFile))
   875  }