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

     1  /*
     2  Copyright hechain All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package discovery
     8  
     9  import (
    10  	"encoding/json"
    11  	"io/ioutil"
    12  	"os"
    13  	"path/filepath"
    14  	"strconv"
    15  	"syscall"
    16  	"time"
    17  
    18  	docker "github.com/fsouza/go-dockerclient"
    19  	"github.com/golang/protobuf/proto"
    20  	"github.com/hechain20/hechain/common/policydsl"
    21  	"github.com/hechain20/hechain/integration/nwo"
    22  	"github.com/hechain20/hechain/integration/nwo/commands"
    23  	"github.com/hechain20/hechain/msp"
    24  	"github.com/hechain20/hechain/protoutil"
    25  	"github.com/hyperledger/fabric-protos-go/common"
    26  	"github.com/hyperledger/fabric-protos-go/discovery"
    27  	pm "github.com/hyperledger/fabric-protos-go/msp"
    28  	. "github.com/onsi/ginkgo"
    29  	. "github.com/onsi/gomega"
    30  	"github.com/onsi/gomega/gbytes"
    31  	"github.com/onsi/gomega/gexec"
    32  	"github.com/tedsuo/ifrit"
    33  )
    34  
    35  var _ = Describe("DiscoveryService", func() {
    36  	var (
    37  		testDir   string
    38  		client    *docker.Client
    39  		network   *nwo.Network
    40  		processes []ifrit.Process
    41  		orderer   *nwo.Orderer
    42  		org1Peer0 *nwo.Peer
    43  		org2Peer0 *nwo.Peer
    44  		org3Peer0 *nwo.Peer
    45  	)
    46  
    47  	BeforeEach(func() {
    48  		var err error
    49  		testDir, err = ioutil.TempDir("", "e2e-sd")
    50  		Expect(err).NotTo(HaveOccurred())
    51  
    52  		client, err = docker.NewClientFromEnv()
    53  		Expect(err).NotTo(HaveOccurred())
    54  
    55  		config := nwo.BasicSolo()
    56  		config.RemovePeer("Org1", "peer1")
    57  		config.RemovePeer("Org2", "peer1")
    58  		Expect(config.Peers).To(HaveLen(2))
    59  
    60  		// add org3 with one peer (to generate cryptogen and configtx files)
    61  		config.Organizations = append(config.Organizations, &nwo.Organization{
    62  			Name:          "Org3",
    63  			MSPID:         "Org3MSP",
    64  			Domain:        "org3.example.com",
    65  			EnableNodeOUs: true,
    66  			Users:         2,
    67  			CA:            &nwo.CA{Hostname: "ca"},
    68  		})
    69  		config.Consortiums[0].Organizations = append(config.Consortiums[0].Organizations, "Org3")
    70  		config.Profiles[1].Organizations = append(config.Profiles[1].Organizations, "Org3")
    71  		config.Peers = append(config.Peers,
    72  			&nwo.Peer{
    73  				Name:         "peer0",
    74  				Organization: "Org3",
    75  				Channels: []*nwo.PeerChannel{
    76  					{Name: "testchannel", Anchor: true},
    77  				},
    78  			},
    79  		)
    80  
    81  		network = nwo.New(config, testDir, client, StartPort(), components)
    82  		network.GenerateConfigTree()
    83  		network.Bootstrap()
    84  
    85  		// initially remove Org3 peer0 from the network and later add it back to test joinbysnapshot
    86  		peers := []*nwo.Peer{}
    87  		for _, p := range network.Peers {
    88  			if p.Organization != "Org3" {
    89  				peers = append(peers, p)
    90  			}
    91  		}
    92  		network.Peers = peers
    93  
    94  		networkRunner := network.NetworkGroupRunner()
    95  		process := ifrit.Invoke(networkRunner)
    96  		Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
    97  		processes = append(processes, process)
    98  
    99  		orderer = network.Orderer("orderer")
   100  		network.CreateAndJoinChannel(orderer, "testchannel")
   101  
   102  		org1Peer0 = network.Peer("Org1", "peer0")
   103  		org2Peer0 = network.Peer("Org2", "peer0")
   104  	})
   105  
   106  	AfterEach(func() {
   107  		for _, process := range processes {
   108  			process.Signal(syscall.SIGTERM)
   109  			Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive())
   110  		}
   111  		if network != nil {
   112  			network.Cleanup()
   113  		}
   114  		os.RemoveAll(testDir)
   115  	})
   116  
   117  	It("discovers network configuration even without anchor peers present", func() {
   118  		chaincodeWhenNoAnchorPeers := nwo.Chaincode{
   119  			Name:    "noanchorpeersjustyet",
   120  			Version: "1.0",
   121  			Path:    "github.com/hechain20/hechain/integration/chaincode/simple/cmd",
   122  			Ctor:    `{"Args":["init","a","100","b","200"]}`,
   123  			Policy:  `OR ('Org1MSP.member')`,
   124  		}
   125  		By("Deploying chaincode before anchor peers are defined in the channel")
   126  		nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincodeWhenNoAnchorPeers, org1Peer0)
   127  
   128  		endorsersForChaincodeBeforeAnchorPeersExist := commands.Endorsers{
   129  			UserCert:  network.PeerUserCert(org1Peer0, "User1"),
   130  			UserKey:   network.PeerUserKey(org1Peer0, "User1"),
   131  			MSPID:     network.Organization(org1Peer0.Organization).MSPID,
   132  			Server:    network.PeerAddress(org1Peer0, nwo.ListenPort),
   133  			Channel:   "testchannel",
   134  			Chaincode: chaincodeWhenNoAnchorPeers.Name,
   135  		}
   136  		discoveryQuery := discoverEndorsers(network, endorsersForChaincodeBeforeAnchorPeersExist)
   137  		Eventually(discoveryQuery, network.EventuallyTimeout).Should(BeEquivalentTo(
   138  			[]ChaincodeEndorsers{
   139  				{
   140  					Chaincode: chaincodeWhenNoAnchorPeers.Name,
   141  					EndorsersByGroups: map[string][]nwo.DiscoveredPeer{
   142  						"G0": {network.DiscoveredPeer(org1Peer0)},
   143  					},
   144  					Layouts: []*discovery.Layout{
   145  						{
   146  							QuantitiesByGroup: map[string]uint32{"G0": 1},
   147  						},
   148  					},
   149  				},
   150  			},
   151  		))
   152  	})
   153  
   154  	It("discovers network configuration, endorsers, and peer membership", func() {
   155  		By("Updating anchor peers")
   156  		initialHeight := nwo.GetLedgerHeight(network, org1Peer0, "testchannel")
   157  		network.UpdateChannelAnchors(orderer, "testchannel")
   158  		// wait for anchor peer config updates to be committed
   159  		nwo.WaitUntilEqualLedgerHeight(network, "testchannel", initialHeight+2, org1Peer0)
   160  		//
   161  		// bootstrapping a peer from snapshot
   162  		//
   163  		By("generating a snapshot at current block number on org1Peer0")
   164  		blockNum := nwo.GetLedgerHeight(network, org1Peer0, "testchannel") - 1
   165  		submitSnapshotRequest(network, "testchannel", 0, org1Peer0, "Snapshot request submitted successfully")
   166  
   167  		By("verifying snapshot completed on org1Peer0")
   168  		verifyNoPendingSnapshotRequest(network, org1Peer0, "testchannel")
   169  		snapshotDir := filepath.Join(network.PeerDir(org1Peer0), "filesystem", "snapshots", "completed", "testchannel", strconv.Itoa(blockNum))
   170  
   171  		By("adding peer org3Peer0 to the network")
   172  		org3Peer0 = &nwo.Peer{
   173  			Name:         "peer0",
   174  			Organization: "Org3",
   175  			Channels: []*nwo.PeerChannel{
   176  				{Name: "testchannel", Anchor: true},
   177  			},
   178  		}
   179  		network.Peers = append(network.Peers, org3Peer0)
   180  
   181  		By("starting peer org3Peer0")
   182  		peerRunner := network.PeerRunner(org3Peer0)
   183  		process := ifrit.Invoke(peerRunner)
   184  		Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed())
   185  		processes = append(processes, process)
   186  
   187  		By("joining peer org3Peer0 to channel by a snapshot")
   188  		joinBySnapshot(network, orderer, org3Peer0, "testchannel", snapshotDir)
   189  
   190  		//
   191  		// retrieving configuration and validating membership
   192  		//
   193  
   194  		By("retrieving the configuration from org1Peer0")
   195  		discoveredConfig := discoverConfiguration(network, org1Peer0)
   196  
   197  		By("retrieving the configuration from org3Peer0")
   198  		discoveredConfig2 := discoverConfiguration(network, org1Peer0)
   199  
   200  		By("comparing configuration from org1Peer0 and org3Peer0")
   201  		Expect(proto.Equal(discoveredConfig, discoveredConfig2)).To(BeTrue())
   202  
   203  		By("validating the membership data")
   204  		Expect(discoveredConfig.Msps).To(HaveLen(len(network.Organizations)))
   205  		for _, o := range network.Orderers {
   206  			org := network.Organization(o.Organization)
   207  			mspConfig, err := msp.GetVerifyingMspConfig(network.OrdererOrgMSPDir(org), org.MSPID, "bccsp")
   208  			Expect(err).NotTo(HaveOccurred())
   209  			Expect(discoveredConfig.Msps[org.MSPID]).To(Equal(unmarshalFabricMSPConfig(mspConfig)))
   210  		}
   211  		for _, p := range network.Peers {
   212  			org := network.Organization(p.Organization)
   213  			mspConfig, err := msp.GetVerifyingMspConfig(network.PeerOrgMSPDir(org), org.MSPID, "bccsp")
   214  			Expect(err).NotTo(HaveOccurred())
   215  			Expect(discoveredConfig.Msps[org.MSPID]).To(Equal(unmarshalFabricMSPConfig(mspConfig)))
   216  		}
   217  
   218  		By("validating the orderers")
   219  		Expect(discoveredConfig.Orderers).To(HaveLen(len(network.Orderers)))
   220  		for _, orderer := range network.Orderers {
   221  			ordererMSPID := network.Organization(orderer.Organization).MSPID
   222  			Expect(discoveredConfig.Orderers[ordererMSPID].Endpoint).To(ConsistOf(
   223  				&discovery.Endpoint{Host: "127.0.0.1", Port: uint32(network.OrdererPort(orderer, nwo.ListenPort))},
   224  			))
   225  		}
   226  
   227  		//
   228  		// discovering peers and endorsers
   229  		//
   230  
   231  		By("discovering peers before deploying any user chaincodes")
   232  		Eventually(nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel"), network.EventuallyTimeout).Should(ConsistOf(
   233  			network.DiscoveredPeer(org1Peer0, "_lifecycle"),
   234  			network.DiscoveredPeer(org2Peer0, "_lifecycle"),
   235  			network.DiscoveredPeer(org3Peer0, "_lifecycle"),
   236  		))
   237  
   238  		By("discovering endorsers when missing chaincode")
   239  		endorsers := commands.Endorsers{
   240  			UserCert:  network.PeerUserCert(org1Peer0, "User1"),
   241  			UserKey:   network.PeerUserKey(org1Peer0, "User1"),
   242  			MSPID:     network.Organization(org1Peer0.Organization).MSPID,
   243  			Server:    network.PeerAddress(org1Peer0, nwo.ListenPort),
   244  			Channel:   "testchannel",
   245  			Chaincode: "mycc",
   246  		}
   247  		sess, err := network.Discover(endorsers)
   248  		Expect(err).NotTo(HaveOccurred())
   249  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   250  		Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
   251  
   252  		By("installing and instantiating chaincode on org1.peer0")
   253  		chaincode := nwo.Chaincode{
   254  			Name:    "mycc",
   255  			Version: "1.0",
   256  			Path:    "github.com/hechain20/hechain/integration/chaincode/simple/cmd",
   257  			Ctor:    `{"Args":["init","a","100","b","200"]}`,
   258  			Policy:  `OR (AND ('Org1MSP.member','Org2MSP.member'), AND ('Org1MSP.member','Org3MSP.member'), AND ('Org2MSP.member','Org3MSP.member'))`,
   259  		}
   260  		nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincode, org1Peer0)
   261  
   262  		By("discovering peers after installing and instantiating chaincode using org1's peer")
   263  		dp := nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
   264  		Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(1))
   265  		peersWithCC := peersWithChaincode(dp, "mycc")()
   266  		Expect(peersWithCC).To(ConsistOf(network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc")))
   267  
   268  		By("discovering endorsers for chaincode that has not been installed to enough orgs to satisfy endorsement policy")
   269  		sess, err = network.Discover(endorsers)
   270  		Expect(err).NotTo(HaveOccurred())
   271  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   272  		Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc"`))
   273  
   274  		By("installing chaincode to enough organizations to satisfy the endorsement policy")
   275  		nwo.InstallChaincodeLegacy(network, chaincode, org2Peer0)
   276  
   277  		By("discovering peers after installing chaincode to org2's peer")
   278  		dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
   279  		Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(2))
   280  		peersWithCC = peersWithChaincode(dp, "mycc")()
   281  		Expect(peersWithCC).To(ConsistOf(
   282  			network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc"),
   283  			network.DiscoveredPeer(org2Peer0, "_lifecycle", "mycc"),
   284  		))
   285  
   286  		By("discovering endorsers for chaincode that has been installed to org1 and org2")
   287  		de := discoverEndorsers(network, endorsers)
   288  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   289  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   290  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   291  		))
   292  		discovered := de()
   293  		Expect(discovered).To(HaveLen(1))
   294  		Expect(discovered[0].Layouts).To(HaveLen(1))
   295  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   296  
   297  		By("installing chaincode to all orgs")
   298  		nwo.InstallChaincodeLegacy(network, chaincode, org3Peer0)
   299  
   300  		By("discovering peers after installing and instantiating chaincode all org peers")
   301  		dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
   302  		Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(3))
   303  		peersWithCC = peersWithChaincode(dp, "mycc")()
   304  		Expect(peersWithCC).To(ConsistOf(
   305  			network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc"),
   306  			network.DiscoveredPeer(org2Peer0, "_lifecycle", "mycc"),
   307  			network.DiscoveredPeer(org3Peer0, "_lifecycle", "mycc"),
   308  		))
   309  
   310  		By("discovering endorsers for chaincode that has been installed to all orgs")
   311  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   312  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   313  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   314  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
   315  		))
   316  		discovered = de()
   317  		Expect(discovered).To(HaveLen(1))
   318  		Expect(discovered[0].Layouts).To(HaveLen(3))
   319  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   320  		Expect(discovered[0].Layouts[1].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   321  		Expect(discovered[0].Layouts[2].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   322  
   323  		By("upgrading chaincode and adding a collections config")
   324  		chaincode.Name = "mycc"
   325  		chaincode.Version = "2.0"
   326  		chaincode.CollectionsConfig = filepath.Join("testdata", "collections_config_org1_org2.json")
   327  		nwo.UpgradeChaincodeLegacy(network, "testchannel", orderer, chaincode, org1Peer0, org2Peer0, org3Peer0)
   328  
   329  		By("discovering endorsers for chaincode with a private collection")
   330  		endorsers.Collection = "mycc:collectionMarbles"
   331  		de = discoverEndorsers(network, endorsers)
   332  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   333  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   334  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   335  		))
   336  		discovered = de()
   337  		Expect(discovered).To(HaveLen(1))
   338  		Expect(discovered[0].Layouts).To(HaveLen(1))
   339  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   340  
   341  		endorsers.Collection = "mycc:collectionMarbles"
   342  		endorsers.NoPrivateReads = []string{"mycc"}
   343  		de = discoverEndorsers(network, endorsers)
   344  		By("discovering endorsers for a blind write with a collection consists of all possible peers")
   345  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   346  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   347  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   348  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
   349  		))
   350  
   351  		By("changing the channel policy")
   352  		currentConfig := nwo.GetConfig(network, org3Peer0, orderer, "testchannel")
   353  		updatedConfig := proto.Clone(currentConfig).(*common.Config)
   354  		updatedConfig.ChannelGroup.Groups["Application"].Groups["Org3"].Policies["Writers"].Policy.Value = protoutil.MarshalOrPanic(policydsl.SignedByMspAdmin("Org3MSP"))
   355  		nwo.UpdateConfig(network, orderer, "testchannel", currentConfig, updatedConfig, true, org3Peer0)
   356  
   357  		By("trying to discover endorsers as an org3 admin")
   358  		endorsers = commands.Endorsers{
   359  			UserCert:  network.PeerUserCert(org3Peer0, "Admin"),
   360  			UserKey:   network.PeerUserKey(org3Peer0, "Admin"),
   361  			MSPID:     network.Organization(org3Peer0.Organization).MSPID,
   362  			Server:    network.PeerAddress(org3Peer0, nwo.ListenPort),
   363  			Channel:   "testchannel",
   364  			Chaincode: "mycc",
   365  		}
   366  		de = discoverEndorsers(network, endorsers)
   367  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   368  			ConsistOf(network.DiscoveredPeer(org1Peer0)),
   369  			ConsistOf(network.DiscoveredPeer(org2Peer0)),
   370  			ConsistOf(network.DiscoveredPeer(org3Peer0)),
   371  		))
   372  
   373  		By("trying to discover endorsers as an org3 member")
   374  		endorsers = commands.Endorsers{
   375  			UserCert:  network.PeerUserCert(org3Peer0, "User1"),
   376  			UserKey:   network.PeerUserKey(org3Peer0, "User1"),
   377  			MSPID:     network.Organization(org3Peer0.Organization).MSPID,
   378  			Server:    network.PeerAddress(org3Peer0, nwo.ListenPort),
   379  			Channel:   "testchannel",
   380  			Chaincode: "mycc",
   381  		}
   382  		sess, err = network.Discover(endorsers)
   383  		Expect(err).NotTo(HaveOccurred())
   384  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   385  		Expect(sess.Err).To(gbytes.Say(`access denied`))
   386  
   387  		By("discovering endorsers for _lifecycle system chaincode before enabling V2_0 capabilities")
   388  		endorsers = commands.Endorsers{
   389  			UserCert:  network.PeerUserCert(org1Peer0, "User1"),
   390  			UserKey:   network.PeerUserKey(org1Peer0, "User1"),
   391  			MSPID:     network.Organization(org1Peer0.Organization).MSPID,
   392  			Server:    network.PeerAddress(org1Peer0, nwo.ListenPort),
   393  			Channel:   "testchannel",
   394  			Chaincode: "_lifecycle",
   395  		}
   396  		sess, err = network.Discover(endorsers)
   397  		Expect(err).NotTo(HaveOccurred())
   398  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   399  		Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"_lifecycle"`))
   400  
   401  		//
   402  		// using _lifecycle
   403  		//
   404  
   405  		By("enabling V2_0 application capabilities on the channel")
   406  		nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, org1Peer0, org2Peer0, org3Peer0)
   407  
   408  		By("ensuring peers are still discoverable after enabling V2_0 application capabilities")
   409  		dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
   410  		Eventually(peersWithChaincode(dp, "mycc"), network.EventuallyTimeout).Should(HaveLen(3))
   411  		peersWithCC = peersWithChaincode(dp, "mycc")()
   412  		Expect(peersWithCC).To(ConsistOf(
   413  			network.DiscoveredPeer(org1Peer0, "_lifecycle", "mycc"),
   414  			network.DiscoveredPeer(org2Peer0, "_lifecycle", "mycc"),
   415  			network.DiscoveredPeer(org3Peer0, "_lifecycle", "mycc"),
   416  		))
   417  
   418  		By("ensuring endorsers for mycc are still discoverable after upgrading to V2_0 application capabilities")
   419  		endorsers = commands.Endorsers{
   420  			UserCert:  network.PeerUserCert(org1Peer0, "User1"),
   421  			UserKey:   network.PeerUserKey(org1Peer0, "User1"),
   422  			MSPID:     network.Organization(org1Peer0.Organization).MSPID,
   423  			Server:    network.PeerAddress(org1Peer0, nwo.ListenPort),
   424  			Channel:   "testchannel",
   425  			Chaincode: "mycc",
   426  		}
   427  		de = discoverEndorsers(network, endorsers)
   428  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   429  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   430  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   431  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
   432  		))
   433  
   434  		By("ensuring endorsers for mycc's collection are still discoverable after upgrading to V2_0 application capabilities")
   435  		endorsers.Collection = "mycc:collectionMarbles"
   436  		de = discoverEndorsers(network, endorsers)
   437  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   438  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   439  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   440  		))
   441  
   442  		By("discovering endorsers for _lifecycle system chaincode")
   443  		endorsers = commands.Endorsers{
   444  			UserCert:  network.PeerUserCert(org1Peer0, "User1"),
   445  			UserKey:   network.PeerUserKey(org1Peer0, "User1"),
   446  			MSPID:     network.Organization(org1Peer0.Organization).MSPID,
   447  			Server:    network.PeerAddress(org1Peer0, nwo.ListenPort),
   448  			Channel:   "testchannel",
   449  			Chaincode: "_lifecycle",
   450  		}
   451  		de = discoverEndorsers(network, endorsers)
   452  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   453  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   454  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   455  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
   456  		))
   457  		discovered = de()
   458  		Expect(discovered).To(HaveLen(1))
   459  		Expect(discovered[0].Layouts).To(HaveLen(3))
   460  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   461  		Expect(discovered[0].Layouts[1].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   462  		Expect(discovered[0].Layouts[2].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   463  
   464  		By("discovering endorsers when missing chaincode")
   465  		endorsers = commands.Endorsers{
   466  			UserCert:  network.PeerUserCert(org1Peer0, "User1"),
   467  			UserKey:   network.PeerUserKey(org1Peer0, "User1"),
   468  			MSPID:     network.Organization(org1Peer0.Organization).MSPID,
   469  			Server:    network.PeerAddress(org1Peer0, nwo.ListenPort),
   470  			Channel:   "testchannel",
   471  			Chaincode: "mycc-lifecycle",
   472  		}
   473  		sess, err = network.Discover(endorsers)
   474  		Expect(err).NotTo(HaveOccurred())
   475  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   476  		Expect(sess.Err).To(gbytes.Say(`failed constructing descriptor for chaincodes:<name:"mycc-lifecycle"`))
   477  
   478  		By("deploying chaincode using org1 and org2")
   479  		chaincodePath := components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd")
   480  		chaincode = nwo.Chaincode{
   481  			Name:                "mycc-lifecycle",
   482  			Version:             "1.0",
   483  			Lang:                "binary",
   484  			PackageFile:         filepath.Join(testDir, "simplecc.tar.gz"),
   485  			Path:                chaincodePath,
   486  			Ctor:                `{"Args":["init","a","100","b","200"]}`,
   487  			ChannelConfigPolicy: "/Channel/Application/Endorsement",
   488  			Sequence:            "1",
   489  			InitRequired:        true,
   490  			Label:               "my_prebuilt_chaincode",
   491  		}
   492  
   493  		By("packaging chaincode")
   494  		nwo.PackageChaincodeBinary(chaincode)
   495  
   496  		By("installing chaincode to org1.peer0 and org2.peer0")
   497  		nwo.InstallChaincode(network, chaincode, org1Peer0, org2Peer0)
   498  
   499  		By("approving chaincode definition for org1 and org2")
   500  		for _, org := range []string{"Org1", "Org2"} {
   501  			nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg(org)...)
   502  		}
   503  
   504  		By("committing chaincode definition using org1.peer0 and org2.peer0")
   505  		nwo.CommitChaincode(network, "testchannel", orderer, chaincode, org1Peer0, org1Peer0, org2Peer0)
   506  		nwo.InitChaincode(network, "testchannel", orderer, chaincode, org1Peer0, org2Peer0)
   507  
   508  		By("discovering endorsers for chaincode that has been installed to some orgs")
   509  		de = discoverEndorsers(network, endorsers)
   510  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   511  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   512  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   513  		))
   514  		discovered = de()
   515  		Expect(discovered).To(HaveLen(1))
   516  		Expect(discovered[0].Layouts).To(HaveLen(1))
   517  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   518  
   519  		By("installing chaincode to all orgs")
   520  		nwo.InstallChaincode(network, chaincode, org3Peer0)
   521  
   522  		By("discovering endorsers for chaincode that has been installed to all orgs but not yet approved by org3")
   523  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   524  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   525  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   526  		))
   527  
   528  		By("ensuring peers are only discoverable that have the chaincode installed and approved")
   529  		dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
   530  		Eventually(peersWithChaincode(dp, "mycc-lifecycle"), network.EventuallyTimeout).Should(HaveLen(2))
   531  		peersWithCC = peersWithChaincode(dp, "mycc-lifecycle")()
   532  		Expect(peersWithCC).To(ConsistOf(
   533  			network.DiscoveredPeer(org1Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
   534  			network.DiscoveredPeer(org2Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
   535  		))
   536  
   537  		By("approving chaincode definition for org3")
   538  		nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg("Org3")...)
   539  
   540  		By("discovering endorsers for chaincode that has been installed and approved by all orgs")
   541  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   542  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   543  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   544  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
   545  		))
   546  
   547  		By("discovering peers for chaincode that has been installed and approved by all orgs")
   548  		dp = nwo.DiscoverPeers(network, org1Peer0, "User1", "testchannel")
   549  		Eventually(peersWithChaincode(dp, "mycc-lifecycle"), network.EventuallyTimeout).Should(HaveLen(3))
   550  		peersWithCC = peersWithChaincode(dp, "mycc-lifecycle")()
   551  		Expect(peersWithCC).To(ConsistOf(
   552  			network.DiscoveredPeer(org1Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
   553  			network.DiscoveredPeer(org2Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
   554  			network.DiscoveredPeer(org3Peer0, "mycc-lifecycle", "_lifecycle", "mycc"),
   555  		))
   556  
   557  		By("updating the chaincode definition to sequence 2 to add a collections config")
   558  		chaincode.Sequence = "2"
   559  		chaincode.CollectionsConfig = filepath.Join("testdata", "collections_config_org1_org2.json")
   560  		for _, org := range []string{"Org1", "Org2"} {
   561  			nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg(org)...)
   562  		}
   563  
   564  		By("committing the new chaincode definition using org1 and org2")
   565  		nwo.CheckCommitReadinessUntilReady(network, "testchannel", chaincode, []*nwo.Organization{network.Organization("Org1"), network.Organization("Org2")}, org1Peer0, org2Peer0, org3Peer0)
   566  		nwo.CommitChaincode(network, "testchannel", orderer, chaincode, org1Peer0, org1Peer0, org2Peer0)
   567  
   568  		By("discovering endorsers for sequence 2 that has only been approved by org1 and org2")
   569  		de = discoverEndorsers(network, endorsers)
   570  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   571  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   572  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   573  		))
   574  
   575  		By("approving the chaincode definition at sequence 2 by org3")
   576  		maxLedgerHeight := nwo.GetMaxLedgerHeight(network, "testchannel", org1Peer0, org2Peer0, org3Peer0)
   577  		nwo.ApproveChaincodeForMyOrg(network, "testchannel", orderer, chaincode, network.PeersInOrg("Org3")...)
   578  		nwo.WaitUntilEqualLedgerHeight(network, "testchannel", maxLedgerHeight+1, org1Peer0, org2Peer0, org3Peer0)
   579  
   580  		By("discovering endorsers for sequence 2 that has been approved by all orgs")
   581  		de = discoverEndorsers(network, endorsers)
   582  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   583  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   584  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   585  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org3Peer0)},
   586  		))
   587  
   588  		By("discovering endorsers for chaincode with a private collection")
   589  		endorsers.Collection = "mycc-lifecycle:collectionMarbles"
   590  		de = discoverEndorsers(network, endorsers)
   591  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   592  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org1Peer0)},
   593  			[]nwo.DiscoveredPeer{network.DiscoveredPeer(org2Peer0)},
   594  		))
   595  		discovered = de()
   596  		Expect(discovered).To(HaveLen(1))
   597  		Expect(discovered[0].Layouts).To(HaveLen(1))
   598  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   599  
   600  		By("upgrading a legacy chaincode for all peers")
   601  		nwo.DeployChaincode(network, "testchannel", orderer, nwo.Chaincode{
   602  			Name:              "mycc",
   603  			Version:           "2.0",
   604  			Lang:              "binary",
   605  			PackageFile:       filepath.Join(testDir, "simplecc.tar.gz"),
   606  			Path:              chaincodePath,
   607  			SignaturePolicy:   `AND ('Org1MSP.member', 'Org2MSP.member', 'Org3MSP.member')`,
   608  			Sequence:          "1",
   609  			CollectionsConfig: filepath.Join("testdata", "collections_config_org1_org2_org3.json"),
   610  			Label:             "my_prebuilt_chaincode",
   611  		})
   612  
   613  		By("discovering endorsers for chaincode that has been installed to all peers")
   614  		endorsers.Chaincode = "mycc"
   615  		endorsers.Collection = ""
   616  		de = discoverEndorsers(network, endorsers)
   617  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   618  			ConsistOf(network.DiscoveredPeer(org1Peer0)),
   619  			ConsistOf(network.DiscoveredPeer(org2Peer0)),
   620  			ConsistOf(network.DiscoveredPeer(org3Peer0)),
   621  		))
   622  		discovered = de()
   623  		Expect(discovered).To(HaveLen(1))
   624  		Expect(discovered[0].Layouts).To(HaveLen(1))
   625  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1), uint32(1)))
   626  
   627  		By("discovering endorsers for a collection without collection EP, using chaincode EP")
   628  		endorsers.Collection = "mycc:collectionMarbles"
   629  		de = discoverEndorsers(network, endorsers)
   630  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   631  			ConsistOf(network.DiscoveredPeer(org1Peer0)),
   632  			ConsistOf(network.DiscoveredPeer(org2Peer0)),
   633  			ConsistOf(network.DiscoveredPeer(org3Peer0)),
   634  		))
   635  
   636  		By("discovering endorsers for a collection with collection EP, using collection EP")
   637  		endorsers.Collection = "mycc:collectionDetails"
   638  		de = discoverEndorsers(network, endorsers)
   639  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   640  			ConsistOf(network.DiscoveredPeer(org1Peer0)),
   641  			ConsistOf(network.DiscoveredPeer(org2Peer0)),
   642  		))
   643  		discovered = de()
   644  		Expect(discovered).To(HaveLen(1))
   645  		Expect(discovered[0].Layouts).To(HaveLen(1))
   646  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1), uint32(1)))
   647  
   648  		By("discovering endorsers for Org1 implicit collection")
   649  		endorsers.Collection = "mycc:_implicit_org_Org1MSP"
   650  		de = discoverEndorsers(network, endorsers)
   651  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   652  			ConsistOf(network.DiscoveredPeer(org1Peer0)),
   653  		))
   654  		discovered = de()
   655  		Expect(discovered).To(HaveLen(1))
   656  		Expect(discovered[0].Layouts).To(HaveLen(1))
   657  		Expect(discovered[0].Layouts[0].QuantitiesByGroup).To(ConsistOf(uint32(1)))
   658  
   659  		By("trying to discover endorsers as an org3 admin")
   660  		endorsers = commands.Endorsers{
   661  			UserCert:  network.PeerUserCert(org3Peer0, "Admin"),
   662  			UserKey:   network.PeerUserKey(org3Peer0, "Admin"),
   663  			MSPID:     network.Organization(org3Peer0.Organization).MSPID,
   664  			Server:    network.PeerAddress(org3Peer0, nwo.ListenPort),
   665  			Channel:   "testchannel",
   666  			Chaincode: "mycc",
   667  		}
   668  		de = discoverEndorsers(network, endorsers)
   669  		Eventually(endorsersByGroups(de), network.EventuallyTimeout).Should(ConsistOf(
   670  			ConsistOf(network.DiscoveredPeer(org1Peer0)),
   671  			ConsistOf(network.DiscoveredPeer(org2Peer0)),
   672  			ConsistOf(network.DiscoveredPeer(org3Peer0)),
   673  		))
   674  
   675  		By("trying to discover endorsers as an org3 member")
   676  		endorsers = commands.Endorsers{
   677  			UserCert:  network.PeerUserCert(org3Peer0, "User1"),
   678  			UserKey:   network.PeerUserKey(org3Peer0, "User1"),
   679  			MSPID:     network.Organization(org3Peer0.Organization).MSPID,
   680  			Server:    network.PeerAddress(org3Peer0, nwo.ListenPort),
   681  			Channel:   "testchannel",
   682  			Chaincode: "mycc-lifecycle",
   683  		}
   684  		sess, err = network.Discover(endorsers)
   685  		Expect(err).NotTo(HaveOccurred())
   686  		Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   687  		Expect(sess.Err).To(gbytes.Say(`access denied`))
   688  	})
   689  })
   690  
   691  type ChaincodeEndorsers struct {
   692  	Chaincode         string
   693  	EndorsersByGroups map[string][]nwo.DiscoveredPeer
   694  	Layouts           []*discovery.Layout
   695  }
   696  
   697  func discoverEndorsers(n *nwo.Network, command commands.Endorsers) func() []ChaincodeEndorsers {
   698  	return func() []ChaincodeEndorsers {
   699  		sess, err := n.Discover(command)
   700  		Expect(err).NotTo(HaveOccurred())
   701  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit())
   702  		if sess.ExitCode() != 0 {
   703  			return nil
   704  		}
   705  
   706  		discovered := []ChaincodeEndorsers{}
   707  		err = json.Unmarshal(sess.Out.Contents(), &discovered)
   708  		Expect(err).NotTo(HaveOccurred())
   709  		return discovered
   710  	}
   711  }
   712  
   713  func endorsersByGroups(discover func() []ChaincodeEndorsers) func() map[string][]nwo.DiscoveredPeer {
   714  	return func() map[string][]nwo.DiscoveredPeer {
   715  		discovered := discover()
   716  		if len(discovered) == 1 {
   717  			return discovered[0].EndorsersByGroups
   718  		}
   719  		return map[string][]nwo.DiscoveredPeer{}
   720  	}
   721  }
   722  
   723  func peersWithChaincode(discover func() []nwo.DiscoveredPeer, ccName string) func() []nwo.DiscoveredPeer {
   724  	return func() []nwo.DiscoveredPeer {
   725  		peers := []nwo.DiscoveredPeer{}
   726  		for _, p := range discover() {
   727  			for _, cc := range p.Chaincodes {
   728  				if cc == ccName {
   729  					peers = append(peers, p)
   730  				}
   731  			}
   732  		}
   733  		return peers
   734  	}
   735  }
   736  
   737  func unmarshalFabricMSPConfig(c *pm.MSPConfig) *pm.FabricMSPConfig {
   738  	fabricConfig := &pm.FabricMSPConfig{}
   739  	err := proto.Unmarshal(c.Config, fabricConfig)
   740  	Expect(err).NotTo(HaveOccurred())
   741  	return fabricConfig
   742  }
   743  
   744  func discoverConfiguration(n *nwo.Network, peer *nwo.Peer) *discovery.ConfigResult {
   745  	config := commands.Config{
   746  		UserCert: n.PeerUserCert(peer, "User1"),
   747  		UserKey:  n.PeerUserKey(peer, "User1"),
   748  		MSPID:    n.Organization(peer.Organization).MSPID,
   749  		Server:   n.PeerAddress(peer, nwo.ListenPort),
   750  		Channel:  "testchannel",
   751  	}
   752  	sess, err := n.Discover(config)
   753  	Expect(err).NotTo(HaveOccurred())
   754  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   755  
   756  	By("unmarshalling the response")
   757  	discoveredConfig := &discovery.ConfigResult{}
   758  	err = json.Unmarshal(sess.Out.Contents(), &discoveredConfig)
   759  	Expect(err).NotTo(HaveOccurred())
   760  
   761  	return discoveredConfig
   762  }
   763  
   764  func submitSnapshotRequest(n *nwo.Network, channel string, blockNum int, peer *nwo.Peer, expectedMsg string) {
   765  	sess, err := n.PeerAdminSession(peer, commands.SnapshotSubmitRequest{
   766  		ChannelID:   channel,
   767  		BlockNumber: strconv.Itoa(blockNum),
   768  		ClientAuth:  n.ClientAuthRequired,
   769  		PeerAddress: n.PeerAddress(peer, nwo.ListenPort),
   770  	})
   771  	Expect(err).NotTo(HaveOccurred())
   772  	Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   773  	Expect(sess).To(gbytes.Say(expectedMsg))
   774  }
   775  
   776  func verifyNoPendingSnapshotRequest(n *nwo.Network, peer *nwo.Peer, channelID string) {
   777  	cmd := commands.SnapshotListPending{
   778  		ChannelID:   channelID,
   779  		ClientAuth:  n.ClientAuthRequired,
   780  		PeerAddress: n.PeerAddress(peer, nwo.ListenPort),
   781  	}
   782  	checkPending := func() string {
   783  		sess, err := n.PeerAdminSession(peer, cmd)
   784  		Expect(err).NotTo(HaveOccurred())
   785  		Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0))
   786  		return string(sess.Buffer().Contents())
   787  	}
   788  	Eventually(checkPending, n.EventuallyTimeout, 10*time.Second).Should(ContainSubstring("Successfully got pending snapshot requests: []\n"))
   789  }
   790  
   791  func joinBySnapshot(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, channelID string, snapshotDir string) {
   792  	n.JoinChannelBySnapshot(snapshotDir, peer)
   793  
   794  	By("calling JoinBySnapshotStatus until joinbysnapshot is completed")
   795  	checkStatus := func() string { return n.JoinBySnapshotStatus(peer) }
   796  	Eventually(checkStatus, n.EventuallyTimeout, 10*time.Second).Should(ContainSubstring("No joinbysnapshot operation is in progress"))
   797  
   798  	By("waiting for the peer to have the same ledger height")
   799  	channelHeight := nwo.GetMaxLedgerHeight(n, channelID, n.PeersWithChannel(channelID)...)
   800  	nwo.WaitUntilEqualLedgerHeight(n, channelID, channelHeight, peer)
   801  }