github.com/hyperledger-labs/bdls@v2.1.1+incompatible/integration/lifecycle/interop_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package lifecycle 8 9 import ( 10 "context" 11 "io/ioutil" 12 "os" 13 "path/filepath" 14 "syscall" 15 16 docker "github.com/fsouza/go-dockerclient" 17 pb "github.com/hyperledger/fabric-protos-go/peer" 18 "github.com/hyperledger/fabric/integration/nwo" 19 "github.com/hyperledger/fabric/integration/nwo/commands" 20 "github.com/hyperledger/fabric/internal/peer/common" 21 "github.com/hyperledger/fabric/msp" 22 "github.com/hyperledger/fabric/protoutil" 23 . "github.com/onsi/ginkgo" 24 . "github.com/onsi/gomega" 25 "github.com/onsi/gomega/gbytes" 26 "github.com/onsi/gomega/gexec" 27 "github.com/tedsuo/ifrit" 28 ) 29 30 var _ = Describe("Release interoperability", func() { 31 var ( 32 client *docker.Client 33 testDir string 34 35 network *nwo.Network 36 process ifrit.Process 37 orderer *nwo.Orderer 38 endorsers []*nwo.Peer 39 ) 40 41 BeforeEach(func() { 42 var err error 43 testDir, err = ioutil.TempDir("", "lifecycle") 44 Expect(err).NotTo(HaveOccurred()) 45 46 client, err = docker.NewClientFromEnv() 47 Expect(err).NotTo(HaveOccurred()) 48 49 network = nwo.New(nwo.MultiChannelBasicSolo(), testDir, client, StartPort(), components) 50 network.GenerateConfigTree() 51 network.Bootstrap() 52 53 // Start all of the fabric processes 54 networkRunner := network.NetworkGroupRunner() 55 process = ifrit.Invoke(networkRunner) 56 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 57 58 orderer = network.Orderer("orderer") 59 endorsers = []*nwo.Peer{ 60 network.Peer("Org1", "peer0"), 61 network.Peer("Org2", "peer0"), 62 } 63 }) 64 65 AfterEach(func() { 66 process.Signal(syscall.SIGTERM) 67 Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) 68 network.Cleanup() 69 os.RemoveAll(testDir) 70 }) 71 72 It("deploys and executes chaincode, upgrades the channel application capabilities to V2_0, and uses _lifecycle to update the endorsement policy", func() { 73 By("deploying the chaincode using LSCC on a channel with V1_4 application capabilities") 74 chaincode := nwo.Chaincode{ 75 Name: "mycc", 76 Version: "0.0", 77 Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd", 78 Ctor: `{"Args":["init","a","100","b","200"]}`, 79 Policy: `AND ('Org1MSP.member','Org2MSP.member')`, 80 } 81 82 network.CreateAndJoinChannels(orderer) 83 nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincode) 84 RunQueryInvokeQuery(network, orderer, "mycc", 100, endorsers...) 85 86 By("enabling V2_0 application capabilities") 87 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, endorsers...) 88 89 By("ensuring that the chaincode is still operational after the upgrade") 90 RunQueryInvokeQuery(network, orderer, "mycc", 90, endorsers...) 91 92 By("restarting the network from persistence") 93 RestartNetwork(&process, network) 94 95 By("ensuring that the chaincode is still operational after the upgrade and restart") 96 RunQueryInvokeQuery(network, orderer, "mycc", 80, endorsers...) 97 98 By("attempting to invoke the chaincode without sufficient endorsements") 99 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeInvoke{ 100 ChannelID: "testchannel", 101 Orderer: network.OrdererAddress(orderer, nwo.ListenPort), 102 Name: "mycc", 103 Ctor: `{"Args":["invoke","a","b","10"]}`, 104 PeerAddresses: []string{ 105 network.PeerAddress(endorsers[0], nwo.ListenPort), 106 }, 107 WaitForEvent: true, 108 }) 109 Expect(err).NotTo(HaveOccurred()) 110 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1)) 111 Expect(sess.Err).To(gbytes.Say(`\Qcommitted with status (ENDORSEMENT_POLICY_FAILURE)\E`)) 112 113 By("upgrading the chaincode definition using _lifecycle") 114 chaincode = nwo.Chaincode{ 115 Name: "mycc", 116 Version: "0.0", 117 Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/module"), 118 Lang: "binary", 119 PackageFile: filepath.Join(testDir, "modulecc.tar.gz"), 120 SignaturePolicy: `OR ('Org1MSP.member','Org2MSP.member')`, 121 Sequence: "1", 122 InitRequired: false, 123 Label: "my_prebuilt_chaincode", 124 } 125 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 126 127 By("querying/invoking/querying the chaincode with the new definition") 128 RunQueryInvokeQuery(network, orderer, "mycc", 70, endorsers[0]) 129 130 By("restarting the network from persistence") 131 RestartNetwork(&process, network) 132 133 By("querying/invoking/querying the chaincode with the new definition again") 134 RunQueryInvokeQuery(network, orderer, "mycc", 60, endorsers[1]) 135 }) 136 137 Describe("Interoperability scenarios", func() { 138 var ( 139 userSigner msp.SigningIdentity 140 serialisedUserSigner []byte 141 endorserClient pb.EndorserClient 142 deliveryClient pb.DeliverClient 143 ordererClient common.BroadcastClient 144 ) 145 146 BeforeEach(func() { 147 userSigner, serialisedUserSigner = Signer(network.PeerUserMSPDir(endorsers[0], "User1")) 148 endorserClient = EndorserClient( 149 network.PeerAddress(endorsers[0], nwo.ListenPort), 150 filepath.Join(network.PeerLocalTLSDir(endorsers[0]), "ca.crt"), 151 ) 152 deliveryClient = DeliverClient( 153 network.PeerAddress(endorsers[0], nwo.ListenPort), 154 filepath.Join(network.PeerLocalTLSDir(endorsers[0]), "ca.crt"), 155 ) 156 ordererClient = OrdererClient( 157 network.OrdererAddress(orderer, nwo.ListenPort), 158 filepath.Join(network.OrdererLocalTLSDir(orderer), "ca.crt"), 159 ) 160 }) 161 162 It("deploys a chaincode with the legacy lifecycle, invokes it and the tx is committed only after the chaincode is upgraded via _lifecycle", func() { 163 By("deploying the chaincode using the legacy lifecycle") 164 chaincode := nwo.Chaincode{ 165 Name: "mycc", 166 Version: "0.0", 167 Path: "github.com/hyperledger/fabric/integration/chaincode/simple/cmd", 168 Ctor: `{"Args":["init","a","100","b","200"]}`, 169 Policy: `OR ('Org1MSP.member','Org2MSP.member')`, 170 } 171 172 network.CreateAndJoinChannels(orderer) 173 nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincode) 174 RunQueryInvokeQuery(network, orderer, "mycc", 100, endorsers...) 175 176 By("invoking the chaincode with the legacy definition and keeping the transaction") 177 signedProp, prop, txid := SignedProposal( 178 "testchannel", 179 "mycc", 180 userSigner, 181 serialisedUserSigner, 182 "invoke", 183 "a", 184 "b", 185 "10", 186 ) 187 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 188 Expect(err).NotTo(HaveOccurred()) 189 Expect(presp).NotTo(BeNil()) 190 191 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 192 Expect(err).NotTo(HaveOccurred()) 193 Expect(env).NotTo(BeNil()) 194 195 By("enabling V2_0 application capabilities") 196 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 197 198 By("upgrading the chaincode definition using _lifecycle") 199 chaincode = nwo.Chaincode{ 200 Name: "mycc", 201 Version: "0.0", 202 Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/module"), 203 Lang: "binary", 204 PackageFile: filepath.Join(testDir, "modulecc.tar.gz"), 205 SignaturePolicy: `OR ('Org1MSP.member','Org2MSP.member')`, 206 Sequence: "1", 207 InitRequired: false, 208 Label: "my_prebuilt_chaincode", 209 } 210 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 211 212 By("committing the old transaction") 213 // FAB-17458: because the endorsed tx doesn't have _lifecycle in read set, 214 // it has no read conflict with the cc upgrade via new lifecycle. 215 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 216 Expect(err).NotTo(HaveOccurred()) 217 }) 218 219 It("deploys a chaincode with the new lifecycle, invokes it and the tx is committed only after the chaincode is upgraded via _lifecycle", func() { 220 By("enabling V2_0 application capabilities") 221 network.CreateAndJoinChannels(orderer) 222 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 223 224 By("deploying the chaincode definition using _lifecycle") 225 chaincode := nwo.Chaincode{ 226 Name: "mycc", 227 Version: "0.0", 228 Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/module"), 229 Lang: "binary", 230 PackageFile: filepath.Join(testDir, "modulecc.tar.gz"), 231 SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`, 232 Sequence: "1", 233 InitRequired: true, 234 Label: "my_prebuilt_chaincode", 235 Ctor: `{"Args":["init","a","100","b","200"]}`, 236 } 237 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 238 239 By("Invoking the chaincode with the first definition and keeping the transaction") 240 signedProp, prop, txid := SignedProposal( 241 "testchannel", 242 "mycc", 243 userSigner, 244 serialisedUserSigner, 245 "invoke", 246 "a", 247 "b", 248 "10", 249 ) 250 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 251 Expect(err).NotTo(HaveOccurred()) 252 Expect(presp).NotTo(BeNil()) 253 254 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 255 Expect(err).NotTo(HaveOccurred()) 256 Expect(env).NotTo(BeNil()) 257 258 By("upgrading the chaincode definition using _lifecycle") 259 chaincode.Sequence = "2" 260 chaincode.SignaturePolicy = `OR ('Org1MSP.member','Org2MSP.member')` 261 chaincode.InitRequired = false 262 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 263 264 By("committing the old transaction, expecting to hit an MVCC conflict") 265 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 266 Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)"))) 267 }) 268 269 Describe("Chaincode-to-chaincode interoperability", func() { 270 var ( 271 callerDefOld nwo.Chaincode 272 callerDefNew nwo.Chaincode 273 calleeDefOld nwo.Chaincode 274 calleeDefNew nwo.Chaincode 275 ) 276 277 BeforeEach(func() { 278 ccEP := `OR ('Org1MSP.member','Org2MSP.member')` 279 callerDefOld = nwo.Chaincode{ 280 Name: "caller", 281 Version: "0.0", 282 Path: "github.com/hyperledger/fabric/integration/lifecycle/chaincode/caller/cmd", 283 Ctor: `{"Args":[""]}`, 284 Policy: ccEP, 285 } 286 calleeDefOld = nwo.Chaincode{ 287 Name: "callee", 288 Version: "0.0", 289 Path: "github.com/hyperledger/fabric/integration/lifecycle/chaincode/callee/cmd", 290 Ctor: `{"Args":[""]}`, 291 Policy: ccEP, 292 } 293 callerDefNew = nwo.Chaincode{ 294 Name: "caller", 295 Version: "0.0", 296 Path: components.Build("github.com/hyperledger/fabric/integration/lifecycle/chaincode/caller/cmd"), 297 Lang: "binary", 298 PackageFile: filepath.Join(testDir, "caller.tar.gz"), 299 SignaturePolicy: ccEP, 300 Sequence: "1", 301 Label: "my_prebuilt_caller_chaincode", 302 InitRequired: true, 303 Ctor: `{"Args":[""]}`, 304 } 305 calleeDefNew = nwo.Chaincode{ 306 Name: "callee", 307 Version: "0.0", 308 Path: components.Build("github.com/hyperledger/fabric/integration/lifecycle/chaincode/callee/cmd"), 309 Lang: "binary", 310 PackageFile: filepath.Join(testDir, "callee.tar.gz"), 311 SignaturePolicy: ccEP, 312 Sequence: "1", 313 Label: "my_prebuilt_callee_chaincode", 314 InitRequired: true, 315 Ctor: `{"Args":[""]}`, 316 } 317 By("Creating and joining the channel") 318 network.CreateAndJoinChannels(orderer) 319 }) 320 321 It("Deploys two chaincodes with the new lifecycle and performs a successful cc2cc invocation", func() { 322 By("enabling the 2.0 capability on the channel") 323 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 324 325 By("deploying the caller chaincode using _lifecycle") 326 nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew) 327 328 By("deploying the callee chaincode using _lifecycle") 329 nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew) 330 331 By("invoking the chaincode and generating a transaction") 332 signedProp, prop, txid := SignedProposal( 333 "testchannel", 334 "caller", 335 userSigner, 336 serialisedUserSigner, 337 "INVOKE", 338 "callee", 339 ) 340 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 341 Expect(err).NotTo(HaveOccurred()) 342 Expect(presp).NotTo(BeNil()) 343 344 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 345 Expect(err).NotTo(HaveOccurred()) 346 Expect(env).NotTo(BeNil()) 347 348 By("committing the transaction") 349 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 350 Expect(err).NotTo(HaveOccurred()) 351 352 By("querying the caller chaincode") 353 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 354 ChannelID: "testchannel", 355 Name: "caller", 356 Ctor: `{"Args":["QUERY"]}`, 357 }) 358 Expect(err).NotTo(HaveOccurred()) 359 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 360 Expect(sess).To(gbytes.Say("caller:bar")) 361 362 By("querying the callee chaincode") 363 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 364 ChannelID: "testchannel", 365 Name: "callee", 366 Ctor: `{"Args":["QUERY"]}`, 367 }) 368 Expect(err).NotTo(HaveOccurred()) 369 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 370 Expect(sess).To(gbytes.Say("callee:bar")) 371 372 By("enabling the 2.0 capability on channel2") 373 nwo.EnableCapabilities(network, "testchannel2", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 374 375 By("deploying the callee chaincode using _lifecycle on channel2") 376 nwo.DeployChaincode(network, "testchannel2", orderer, calleeDefNew) 377 378 By("invoking the chaincode on callee on channel2") 379 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeInvoke{ 380 ChannelID: "testchannel2", 381 Orderer: network.OrdererAddress(orderer, nwo.ListenPort), 382 Name: "callee", 383 Ctor: `{"Args":["INVOKE"]}`, 384 WaitForEvent: true, 385 }) 386 Expect(err).NotTo(HaveOccurred()) 387 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 388 Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200")) 389 390 By("querying the callee chaincode on channel2") 391 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 392 ChannelID: "testchannel2", 393 Name: "callee", 394 Ctor: `{"Args":["QUERY"]}`, 395 }) 396 Expect(err).NotTo(HaveOccurred()) 397 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 398 Expect(sess).To(gbytes.Say("callee:bar")) 399 400 By("querying (QUERYCALLEE) the callee chaincode on channel2 from caller on channel") 401 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 402 ChannelID: "testchannel", 403 Name: "caller", 404 Ctor: `{"Args":["QUERYCALLEE", "callee", "testchannel2"]}`, 405 }) 406 Expect(err).NotTo(HaveOccurred()) 407 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 408 Expect(sess).To(gbytes.Say("callee:bar")) 409 410 By("querying (QUERYCALLEE) the callee chaincode from caller on non-existing channel and expecting the invocation to fail") 411 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 412 ChannelID: "testchannel", 413 Name: "caller", 414 Ctor: `{"Args":["QUERYCALLEE", "callee", "nonExistingChannel2"]}`, 415 }) 416 Expect(err).NotTo(HaveOccurred()) 417 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1)) 418 Expect(sess.Err).To(gbytes.Say(`Error: endorsement failure during query. response: status:500`)) 419 }) 420 421 When("the network starts with new definitions", func() { 422 BeforeEach(func() { 423 By("enabling the 2.0 capability on the channel") 424 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 425 426 By("upgrading the caller with the new definition") 427 nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew) 428 429 By("upgrading the callee with the new definition") 430 nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew) 431 }) 432 433 It("performs a successful cc2cc invocation", func() { 434 By("invoking the chaincode and generating a transaction") 435 signedProp, prop, txid := SignedProposal( 436 "testchannel", 437 "caller", 438 userSigner, 439 serialisedUserSigner, 440 "INVOKE", 441 "callee", 442 ) 443 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 444 Expect(err).NotTo(HaveOccurred()) 445 Expect(presp).NotTo(BeNil()) 446 447 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 448 Expect(err).NotTo(HaveOccurred()) 449 Expect(env).NotTo(BeNil()) 450 451 By("committing the transaction") 452 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 453 Expect(err).NotTo(HaveOccurred()) 454 455 By("querying the caller chaincode") 456 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 457 ChannelID: "testchannel", 458 Name: "caller", 459 Ctor: `{"Args":["QUERY"]}`, 460 }) 461 Expect(err).NotTo(HaveOccurred()) 462 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 463 Expect(sess).To(gbytes.Say("caller:bar")) 464 465 By("querying the callee chaincode") 466 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 467 ChannelID: "testchannel", 468 Name: "callee", 469 Ctor: `{"Args":["QUERY"]}`, 470 }) 471 Expect(err).NotTo(HaveOccurred()) 472 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 473 Expect(sess).To(gbytes.Say("callee:bar")) 474 }) 475 476 It("performs a successful cc2cc invocation which doesn't commit because the caller is further upgraded", func() { 477 By("invoking the chaincode and generating a transaction") 478 signedProp, prop, txid := SignedProposal( 479 "testchannel", 480 "caller", 481 userSigner, 482 serialisedUserSigner, 483 "INVOKE", 484 "callee", 485 ) 486 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 487 Expect(err).NotTo(HaveOccurred()) 488 Expect(presp).NotTo(BeNil()) 489 490 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 491 Expect(err).NotTo(HaveOccurred()) 492 Expect(env).NotTo(BeNil()) 493 494 By("further upgrading the caller with the new definition") 495 callerDefNew.Sequence = "2" 496 callerDefNew.InitRequired = false 497 nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew) 498 499 By("committing the transaction") 500 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 501 Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)"))) 502 503 By("querying the caller chaincode") 504 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 505 ChannelID: "testchannel", 506 Name: "caller", 507 Ctor: `{"Args":["QUERY"]}`, 508 }) 509 Expect(err).NotTo(HaveOccurred()) 510 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 511 Expect(sess).To(gbytes.Say("caller:foo")) 512 513 By("querying the callee chaincode") 514 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 515 ChannelID: "testchannel", 516 Name: "callee", 517 Ctor: `{"Args":["QUERY"]}`, 518 }) 519 Expect(err).NotTo(HaveOccurred()) 520 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 521 Expect(sess).To(gbytes.Say("callee:foo")) 522 }) 523 524 It("performs a successful cc2cc invocation which doesn't commit because the callee is further upgraded", func() { 525 By("invoking the chaincode and generating a transaction") 526 signedProp, prop, txid := SignedProposal( 527 "testchannel", 528 "caller", 529 userSigner, 530 serialisedUserSigner, 531 "INVOKE", 532 "callee", 533 ) 534 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 535 Expect(err).NotTo(HaveOccurred()) 536 Expect(presp).NotTo(BeNil()) 537 538 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 539 Expect(err).NotTo(HaveOccurred()) 540 Expect(env).NotTo(BeNil()) 541 542 By("further upgrading the callee with the new definition") 543 calleeDefNew.Sequence = "2" 544 calleeDefNew.InitRequired = false 545 nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew) 546 547 By("committing the transaction") 548 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 549 Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)"))) 550 551 By("querying the caller chaincode") 552 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 553 ChannelID: "testchannel", 554 Name: "caller", 555 Ctor: `{"Args":["QUERY"]}`, 556 }) 557 Expect(err).NotTo(HaveOccurred()) 558 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 559 Expect(sess).To(gbytes.Say("caller:foo")) 560 561 By("querying the callee chaincode") 562 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 563 ChannelID: "testchannel", 564 Name: "callee", 565 Ctor: `{"Args":["QUERY"]}`, 566 }) 567 Expect(err).NotTo(HaveOccurred()) 568 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 569 Expect(sess).To(gbytes.Say("callee:foo")) 570 }) 571 }) 572 573 When("the network starts with legacy definitions and then upgrades to 2.0", func() { 574 BeforeEach(func() { 575 By("deploying the caller chaincode using the legacy lifecycle") 576 nwo.DeployChaincodeLegacy(network, "testchannel", orderer, callerDefOld) 577 578 By("deploying the callee chaincode using the legacy lifecycle") 579 nwo.DeployChaincodeLegacy(network, "testchannel", orderer, calleeDefOld) 580 581 By("enabling the 2.0 capability on the channel") 582 nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0")) 583 }) 584 585 It("upgrades the caller with the new and performs a successful cc2cc invocation", func() { 586 By("upgrading the caller with the new definition") 587 nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew) 588 589 By("invoking the chaincode and generating a transaction") 590 signedProp, prop, txid := SignedProposal( 591 "testchannel", 592 "caller", 593 userSigner, 594 serialisedUserSigner, 595 "INVOKE", 596 "callee", 597 ) 598 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 599 Expect(err).NotTo(HaveOccurred()) 600 Expect(presp).NotTo(BeNil()) 601 602 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 603 Expect(err).NotTo(HaveOccurred()) 604 Expect(env).NotTo(BeNil()) 605 606 By("committing the transaction") 607 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 608 Expect(err).NotTo(HaveOccurred()) 609 610 By("querying the caller chaincode") 611 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 612 ChannelID: "testchannel", 613 Name: "caller", 614 Ctor: `{"Args":["QUERY"]}`, 615 }) 616 Expect(err).NotTo(HaveOccurred()) 617 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 618 Expect(sess).To(gbytes.Say("caller:bar")) 619 620 By("querying the callee chaincode") 621 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 622 ChannelID: "testchannel", 623 Name: "callee", 624 Ctor: `{"Args":["QUERY"]}`, 625 }) 626 Expect(err).NotTo(HaveOccurred()) 627 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 628 Expect(sess).To(gbytes.Say("callee:bar")) 629 }) 630 631 It("upgrades the callee with the new and performs a successful cc2cc invocation", func() { 632 By("upgrading the callee with the new definition") 633 nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew) 634 635 By("invoking the chaincode and generating a transaction") 636 signedProp, prop, txid := SignedProposal( 637 "testchannel", 638 "caller", 639 userSigner, 640 serialisedUserSigner, 641 "INVOKE", 642 "callee", 643 ) 644 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 645 Expect(err).NotTo(HaveOccurred()) 646 Expect(presp).NotTo(BeNil()) 647 648 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 649 Expect(err).NotTo(HaveOccurred()) 650 Expect(env).NotTo(BeNil()) 651 652 By("committing the transaction") 653 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 654 Expect(err).NotTo(HaveOccurred()) 655 656 By("querying the caller chaincode") 657 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 658 ChannelID: "testchannel", 659 Name: "caller", 660 Ctor: `{"Args":["QUERY"]}`, 661 }) 662 Expect(err).NotTo(HaveOccurred()) 663 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 664 Expect(sess).To(gbytes.Say("caller:bar")) 665 666 By("querying the callee chaincode") 667 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 668 ChannelID: "testchannel", 669 Name: "callee", 670 Ctor: `{"Args":["QUERY"]}`, 671 }) 672 Expect(err).NotTo(HaveOccurred()) 673 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 674 Expect(sess).To(gbytes.Say("callee:bar")) 675 }) 676 677 It("performs a cc2cc invocation which fails because in the meantime, the callee is upgraded with the new lifecycle", func() { 678 By("invoking the chaincode and generating a transaction") 679 signedProp, prop, txid := SignedProposal( 680 "testchannel", 681 "caller", 682 userSigner, 683 serialisedUserSigner, 684 "INVOKE", 685 "callee", 686 ) 687 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 688 Expect(err).NotTo(HaveOccurred()) 689 Expect(presp).NotTo(BeNil()) 690 691 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 692 Expect(err).NotTo(HaveOccurred()) 693 Expect(env).NotTo(BeNil()) 694 695 By("upgrading the callee with the new definition") 696 nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew) 697 698 By("committing the transaction") 699 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 700 Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)"))) 701 702 By("querying the caller chaincode") 703 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 704 ChannelID: "testchannel", 705 Name: "caller", 706 Ctor: `{"Args":["QUERY"]}`, 707 }) 708 Expect(err).NotTo(HaveOccurred()) 709 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 710 Expect(sess).To(gbytes.Say("caller:foo")) 711 712 By("querying the callee chaincode") 713 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 714 ChannelID: "testchannel", 715 Name: "callee", 716 Ctor: `{"Args":["QUERY"]}`, 717 }) 718 Expect(err).NotTo(HaveOccurred()) 719 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 720 Expect(sess).To(gbytes.Say("callee:foo")) 721 }) 722 723 It("performs a cc2cc invocation which fails because in the meantime, the caller is upgraded with the new lifecycle", func() { 724 By("invoking the chaincode and generating a transaction") 725 signedProp, prop, txid := SignedProposal( 726 "testchannel", 727 "caller", 728 userSigner, 729 serialisedUserSigner, 730 "INVOKE", 731 "callee", 732 ) 733 presp, err := endorserClient.ProcessProposal(context.Background(), signedProp) 734 Expect(err).NotTo(HaveOccurred()) 735 Expect(presp).NotTo(BeNil()) 736 737 env, err := protoutil.CreateSignedTx(prop, userSigner, presp) 738 Expect(err).NotTo(HaveOccurred()) 739 Expect(env).NotTo(BeNil()) 740 741 By("upgrading the caller with the new definition") 742 nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew) 743 744 By("committing the transaction") 745 err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid) 746 Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)"))) 747 748 By("querying the caller chaincode") 749 sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 750 ChannelID: "testchannel", 751 Name: "caller", 752 Ctor: `{"Args":["QUERY"]}`, 753 }) 754 Expect(err).NotTo(HaveOccurred()) 755 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 756 Expect(sess).To(gbytes.Say("caller:foo")) 757 758 By("querying the callee chaincode") 759 sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{ 760 ChannelID: "testchannel", 761 Name: "callee", 762 Ctor: `{"Args":["QUERY"]}`, 763 }) 764 Expect(err).NotTo(HaveOccurred()) 765 Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0)) 766 Expect(sess).To(gbytes.Say("callee:foo")) 767 }) 768 }) 769 }) 770 }) 771 })