github.com/anjalikarhana/fabric@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  })