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