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

     1  /*
     2  Copyright hechain. 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  	"github.com/hechain20/hechain/integration/nwo"
    18  	"github.com/hechain20/hechain/integration/nwo/commands"
    19  	"github.com/hechain20/hechain/protoutil"
    20  	ab "github.com/hyperledger/fabric-protos-go/orderer"
    21  	pb "github.com/hyperledger/fabric-protos-go/peer"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  	"github.com/onsi/gomega/gbytes"
    25  	"github.com/onsi/gomega/gexec"
    26  	"github.com/tedsuo/ifrit"
    27  	"google.golang.org/grpc"
    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/hechain20/hechain/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  		process = 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/hechain20/hechain/integration/chaincode/simple/cmd"),
   118  			Lang:            "binary",
   119  			PackageFile:     filepath.Join(testDir, "simplecc.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  		process = 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  			occ, pcc       *grpc.ClientConn
   140  			userSigner     *nwo.SigningIdentity
   141  			endorserClient pb.EndorserClient
   142  			deliveryClient pb.DeliverClient
   143  			ordererClient  ab.AtomicBroadcast_BroadcastClient
   144  		)
   145  
   146  		BeforeEach(func() {
   147  			userSigner = network.PeerUserSigner(endorsers[0], "User1")
   148  
   149  			pcc = network.PeerClientConn(endorsers[0])
   150  			endorserClient = pb.NewEndorserClient(pcc)
   151  			deliveryClient = pb.NewDeliverClient(pcc)
   152  
   153  			var err error
   154  			occ = network.OrdererClientConn(orderer)
   155  			ordererClient, err = ab.NewAtomicBroadcastClient(occ).Broadcast(context.Background())
   156  			Expect(err).NotTo(HaveOccurred())
   157  		})
   158  
   159  		AfterEach(func() {
   160  			if occ != nil {
   161  				occ.Close()
   162  			}
   163  			if pcc != nil {
   164  				pcc.Close()
   165  			}
   166  		})
   167  
   168  		It("deploys a chaincode with the legacy lifecycle, invokes it and the tx is committed only after the chaincode is upgraded via _lifecycle", func() {
   169  			By("deploying the chaincode using the legacy lifecycle")
   170  			chaincode := nwo.Chaincode{
   171  				Name:    "mycc",
   172  				Version: "0.0",
   173  				Path:    "github.com/hechain20/hechain/integration/chaincode/simple/cmd",
   174  				Ctor:    `{"Args":["init","a","100","b","200"]}`,
   175  				Policy:  `OR ('Org1MSP.member','Org2MSP.member')`,
   176  			}
   177  
   178  			network.CreateAndJoinChannels(orderer)
   179  			nwo.DeployChaincodeLegacy(network, "testchannel", orderer, chaincode)
   180  			RunQueryInvokeQuery(network, orderer, "mycc", 100, endorsers...)
   181  
   182  			By("invoking the chaincode with the legacy definition and keeping the transaction")
   183  			signedProp, prop, txid := SignedProposal(
   184  				"testchannel",
   185  				"mycc",
   186  				userSigner,
   187  				"invoke",
   188  				"a",
   189  				"b",
   190  				"10",
   191  			)
   192  			presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   193  			Expect(err).NotTo(HaveOccurred())
   194  			Expect(presp).NotTo(BeNil())
   195  
   196  			env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   197  			Expect(err).NotTo(HaveOccurred())
   198  			Expect(env).NotTo(BeNil())
   199  
   200  			By("enabling V2_0 application capabilities")
   201  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   202  
   203  			By("upgrading the chaincode definition using _lifecycle")
   204  			chaincode = nwo.Chaincode{
   205  				Name:            "mycc",
   206  				Version:         "0.0",
   207  				Path:            components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd"),
   208  				Lang:            "binary",
   209  				PackageFile:     filepath.Join(testDir, "simplecc.tar.gz"),
   210  				SignaturePolicy: `OR ('Org1MSP.member','Org2MSP.member')`,
   211  				Sequence:        "1",
   212  				InitRequired:    false,
   213  				Label:           "my_prebuilt_chaincode",
   214  			}
   215  			nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
   216  
   217  			By("committing the old transaction")
   218  			// FAB-17458: because the endorsed tx doesn't have _lifecycle in read set,
   219  			// it has no read conflict with the cc upgrade via new lifecycle.
   220  			err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   221  			Expect(err).NotTo(HaveOccurred())
   222  		})
   223  
   224  		It("deploys a chaincode with the new lifecycle, invokes it and the tx is committed only after the chaincode is upgraded via _lifecycle", func() {
   225  			By("enabling V2_0 application capabilities")
   226  			network.CreateAndJoinChannels(orderer)
   227  			nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   228  
   229  			By("deploying the chaincode definition using _lifecycle")
   230  			chaincode := nwo.Chaincode{
   231  				Name:            "mycc",
   232  				Version:         "0.0",
   233  				Path:            components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd"),
   234  				Lang:            "binary",
   235  				PackageFile:     filepath.Join(testDir, "simplecc.tar.gz"),
   236  				SignaturePolicy: `AND ('Org1MSP.member','Org2MSP.member')`,
   237  				Sequence:        "1",
   238  				InitRequired:    true,
   239  				Label:           "my_prebuilt_chaincode",
   240  				Ctor:            `{"Args":["init","a","100","b","200"]}`,
   241  			}
   242  			nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
   243  
   244  			By("Invoking the chaincode with the first definition and keeping the transaction")
   245  			signedProp, prop, txid := SignedProposal(
   246  				"testchannel",
   247  				"mycc",
   248  				userSigner,
   249  				"invoke",
   250  				"a",
   251  				"b",
   252  				"10",
   253  			)
   254  			presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   255  			Expect(err).NotTo(HaveOccurred())
   256  			Expect(presp).NotTo(BeNil())
   257  
   258  			env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   259  			Expect(err).NotTo(HaveOccurred())
   260  			Expect(env).NotTo(BeNil())
   261  
   262  			By("upgrading the chaincode definition using _lifecycle")
   263  			chaincode.Sequence = "2"
   264  			chaincode.SignaturePolicy = `OR ('Org1MSP.member','Org2MSP.member')`
   265  			chaincode.InitRequired = false
   266  			nwo.DeployChaincode(network, "testchannel", orderer, chaincode)
   267  
   268  			By("committing the old transaction, expecting to hit an MVCC conflict")
   269  			err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   270  			Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)")))
   271  		})
   272  
   273  		Describe("Chaincode-to-chaincode interoperability", func() {
   274  			var (
   275  				callerDefOld nwo.Chaincode
   276  				callerDefNew nwo.Chaincode
   277  				calleeDefOld nwo.Chaincode
   278  				calleeDefNew nwo.Chaincode
   279  			)
   280  
   281  			BeforeEach(func() {
   282  				ccEP := `OR ('Org1MSP.member','Org2MSP.member')`
   283  				callerDefOld = nwo.Chaincode{
   284  					Name:    "caller",
   285  					Version: "0.0",
   286  					Path:    "github.com/hechain20/hechain/integration/lifecycle/chaincode/caller/cmd",
   287  					Ctor:    `{"Args":[""]}`,
   288  					Policy:  ccEP,
   289  				}
   290  				calleeDefOld = nwo.Chaincode{
   291  					Name:    "callee",
   292  					Version: "0.0",
   293  					Path:    "github.com/hechain20/hechain/integration/lifecycle/chaincode/callee/cmd",
   294  					Ctor:    `{"Args":[""]}`,
   295  					Policy:  ccEP,
   296  				}
   297  				callerDefNew = nwo.Chaincode{
   298  					Name:            "caller",
   299  					Version:         "0.0",
   300  					Path:            components.Build("github.com/hechain20/hechain/integration/lifecycle/chaincode/caller/cmd"),
   301  					Lang:            "binary",
   302  					PackageFile:     filepath.Join(testDir, "caller.tar.gz"),
   303  					SignaturePolicy: ccEP,
   304  					Sequence:        "1",
   305  					Label:           "my_prebuilt_caller_chaincode",
   306  					InitRequired:    true,
   307  					Ctor:            `{"Args":[""]}`,
   308  				}
   309  				calleeDefNew = nwo.Chaincode{
   310  					Name:            "callee",
   311  					Version:         "0.0",
   312  					Path:            components.Build("github.com/hechain20/hechain/integration/lifecycle/chaincode/callee/cmd"),
   313  					Lang:            "binary",
   314  					PackageFile:     filepath.Join(testDir, "callee.tar.gz"),
   315  					SignaturePolicy: ccEP,
   316  					Sequence:        "1",
   317  					Label:           "my_prebuilt_callee_chaincode",
   318  					InitRequired:    true,
   319  					Ctor:            `{"Args":[""]}`,
   320  				}
   321  				By("Creating and joining the channel")
   322  				network.CreateAndJoinChannels(orderer)
   323  			})
   324  
   325  			It("Deploys two chaincodes with the new lifecycle and performs a successful cc2cc invocation", func() {
   326  				By("enabling the 2.0 capability on the channel")
   327  				nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   328  
   329  				By("deploying the caller chaincode using _lifecycle")
   330  				nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew)
   331  
   332  				By("deploying the callee chaincode using _lifecycle")
   333  				nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew)
   334  
   335  				By("invoking the chaincode and generating a transaction")
   336  				signedProp, prop, txid := SignedProposal(
   337  					"testchannel",
   338  					"caller",
   339  					userSigner,
   340  					"INVOKE",
   341  					"callee",
   342  				)
   343  				presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   344  				Expect(err).NotTo(HaveOccurred())
   345  				Expect(presp).NotTo(BeNil())
   346  
   347  				env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   348  				Expect(err).NotTo(HaveOccurred())
   349  				Expect(env).NotTo(BeNil())
   350  
   351  				By("committing the transaction")
   352  				err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   353  				Expect(err).NotTo(HaveOccurred())
   354  
   355  				By("querying the caller chaincode")
   356  				sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   357  					ChannelID: "testchannel",
   358  					Name:      "caller",
   359  					Ctor:      `{"Args":["QUERY"]}`,
   360  				})
   361  				Expect(err).NotTo(HaveOccurred())
   362  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   363  				Expect(sess).To(gbytes.Say("caller:bar"))
   364  
   365  				By("querying the callee chaincode")
   366  				sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   367  					ChannelID: "testchannel",
   368  					Name:      "callee",
   369  					Ctor:      `{"Args":["QUERY"]}`,
   370  				})
   371  				Expect(err).NotTo(HaveOccurred())
   372  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   373  				Expect(sess).To(gbytes.Say("callee:bar"))
   374  
   375  				By("enabling the 2.0 capability on channel2")
   376  				nwo.EnableCapabilities(network, "testchannel2", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   377  
   378  				By("deploying the callee chaincode using _lifecycle on channel2")
   379  				nwo.DeployChaincode(network, "testchannel2", orderer, calleeDefNew)
   380  
   381  				By("invoking the chaincode on callee on channel2")
   382  				sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeInvoke{
   383  					ChannelID:    "testchannel2",
   384  					Orderer:      network.OrdererAddress(orderer, nwo.ListenPort),
   385  					Name:         "callee",
   386  					Ctor:         `{"Args":["INVOKE"]}`,
   387  					WaitForEvent: true,
   388  				})
   389  				Expect(err).NotTo(HaveOccurred())
   390  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   391  				Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))
   392  
   393  				By("querying the callee chaincode on channel2")
   394  				sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   395  					ChannelID: "testchannel2",
   396  					Name:      "callee",
   397  					Ctor:      `{"Args":["QUERY"]}`,
   398  				})
   399  				Expect(err).NotTo(HaveOccurred())
   400  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   401  				Expect(sess).To(gbytes.Say("callee:bar"))
   402  
   403  				By("querying (QUERYCALLEE) the callee chaincode on channel2 from caller on channel")
   404  				sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   405  					ChannelID: "testchannel",
   406  					Name:      "caller",
   407  					Ctor:      `{"Args":["QUERYCALLEE", "callee", "testchannel2"]}`,
   408  				})
   409  				Expect(err).NotTo(HaveOccurred())
   410  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   411  				Expect(sess).To(gbytes.Say("callee:bar"))
   412  
   413  				By("querying (QUERYCALLEE) the callee chaincode from caller on non-existing channel and expecting the invocation to fail")
   414  				sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   415  					ChannelID: "testchannel",
   416  					Name:      "caller",
   417  					Ctor:      `{"Args":["QUERYCALLEE", "callee", "nonExistingChannel2"]}`,
   418  				})
   419  				Expect(err).NotTo(HaveOccurred())
   420  				Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(1))
   421  				Expect(sess.Err).To(gbytes.Say(`Error: endorsement failure during query. response: status:500`))
   422  			})
   423  
   424  			When("the network starts with new definitions", func() {
   425  				BeforeEach(func() {
   426  					By("enabling the 2.0 capability on the channel")
   427  					nwo.EnableCapabilities(network, "testchannel", "Application", "V2_0", orderer, network.Peer("Org1", "peer0"), network.Peer("Org2", "peer0"))
   428  
   429  					By("upgrading the caller with the new definition")
   430  					nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew)
   431  
   432  					By("upgrading the callee with the new definition")
   433  					nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew)
   434  				})
   435  
   436  				It("performs a successful cc2cc invocation", func() {
   437  					By("invoking the chaincode and generating a transaction")
   438  					signedProp, prop, txid := SignedProposal(
   439  						"testchannel",
   440  						"caller",
   441  						userSigner,
   442  						"INVOKE",
   443  						"callee",
   444  					)
   445  					presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   446  					Expect(err).NotTo(HaveOccurred())
   447  					Expect(presp).NotTo(BeNil())
   448  
   449  					env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   450  					Expect(err).NotTo(HaveOccurred())
   451  					Expect(env).NotTo(BeNil())
   452  
   453  					By("committing the transaction")
   454  					err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   455  					Expect(err).NotTo(HaveOccurred())
   456  
   457  					By("querying the caller chaincode")
   458  					sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   459  						ChannelID: "testchannel",
   460  						Name:      "caller",
   461  						Ctor:      `{"Args":["QUERY"]}`,
   462  					})
   463  					Expect(err).NotTo(HaveOccurred())
   464  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   465  					Expect(sess).To(gbytes.Say("caller:bar"))
   466  
   467  					By("querying the callee chaincode")
   468  					sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   469  						ChannelID: "testchannel",
   470  						Name:      "callee",
   471  						Ctor:      `{"Args":["QUERY"]}`,
   472  					})
   473  					Expect(err).NotTo(HaveOccurred())
   474  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   475  					Expect(sess).To(gbytes.Say("callee:bar"))
   476  				})
   477  
   478  				It("performs a successful cc2cc invocation which doesn't commit because the caller is further upgraded", func() {
   479  					By("invoking the chaincode and generating a transaction")
   480  					signedProp, prop, txid := SignedProposal(
   481  						"testchannel",
   482  						"caller",
   483  						userSigner,
   484  						"INVOKE",
   485  						"callee",
   486  					)
   487  					presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   488  					Expect(err).NotTo(HaveOccurred())
   489  					Expect(presp).NotTo(BeNil())
   490  
   491  					env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   492  					Expect(err).NotTo(HaveOccurred())
   493  					Expect(env).NotTo(BeNil())
   494  
   495  					By("further upgrading the caller with the new definition")
   496  					callerDefNew.Sequence = "2"
   497  					callerDefNew.InitRequired = false
   498  					nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew)
   499  
   500  					By("committing the transaction")
   501  					err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   502  					Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)")))
   503  
   504  					By("querying the caller chaincode")
   505  					sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   506  						ChannelID: "testchannel",
   507  						Name:      "caller",
   508  						Ctor:      `{"Args":["QUERY"]}`,
   509  					})
   510  					Expect(err).NotTo(HaveOccurred())
   511  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   512  					Expect(sess).To(gbytes.Say("caller:foo"))
   513  
   514  					By("querying the callee chaincode")
   515  					sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   516  						ChannelID: "testchannel",
   517  						Name:      "callee",
   518  						Ctor:      `{"Args":["QUERY"]}`,
   519  					})
   520  					Expect(err).NotTo(HaveOccurred())
   521  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   522  					Expect(sess).To(gbytes.Say("callee:foo"))
   523  				})
   524  
   525  				It("performs a successful cc2cc invocation which doesn't commit because the callee is further upgraded", func() {
   526  					By("invoking the chaincode and generating a transaction")
   527  					signedProp, prop, txid := SignedProposal(
   528  						"testchannel",
   529  						"caller",
   530  						userSigner,
   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  						"INVOKE",
   595  						"callee",
   596  					)
   597  					presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   598  					Expect(err).NotTo(HaveOccurred())
   599  					Expect(presp).NotTo(BeNil())
   600  
   601  					env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   602  					Expect(err).NotTo(HaveOccurred())
   603  					Expect(env).NotTo(BeNil())
   604  
   605  					By("committing the transaction")
   606  					err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   607  					Expect(err).NotTo(HaveOccurred())
   608  
   609  					By("querying the caller chaincode")
   610  					sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   611  						ChannelID: "testchannel",
   612  						Name:      "caller",
   613  						Ctor:      `{"Args":["QUERY"]}`,
   614  					})
   615  					Expect(err).NotTo(HaveOccurred())
   616  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   617  					Expect(sess).To(gbytes.Say("caller:bar"))
   618  
   619  					By("querying the callee chaincode")
   620  					sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   621  						ChannelID: "testchannel",
   622  						Name:      "callee",
   623  						Ctor:      `{"Args":["QUERY"]}`,
   624  					})
   625  					Expect(err).NotTo(HaveOccurred())
   626  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   627  					Expect(sess).To(gbytes.Say("callee:bar"))
   628  				})
   629  
   630  				It("upgrades the callee with the new and performs a successful cc2cc invocation", func() {
   631  					By("upgrading the callee with the new definition")
   632  					nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew)
   633  
   634  					By("invoking the chaincode and generating a transaction")
   635  					signedProp, prop, txid := SignedProposal(
   636  						"testchannel",
   637  						"caller",
   638  						userSigner,
   639  						"INVOKE",
   640  						"callee",
   641  					)
   642  					presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   643  					Expect(err).NotTo(HaveOccurred())
   644  					Expect(presp).NotTo(BeNil())
   645  
   646  					env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   647  					Expect(err).NotTo(HaveOccurred())
   648  					Expect(env).NotTo(BeNil())
   649  
   650  					By("committing the transaction")
   651  					err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   652  					Expect(err).NotTo(HaveOccurred())
   653  
   654  					By("querying the caller chaincode")
   655  					sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   656  						ChannelID: "testchannel",
   657  						Name:      "caller",
   658  						Ctor:      `{"Args":["QUERY"]}`,
   659  					})
   660  					Expect(err).NotTo(HaveOccurred())
   661  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   662  					Expect(sess).To(gbytes.Say("caller:bar"))
   663  
   664  					By("querying the callee chaincode")
   665  					sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   666  						ChannelID: "testchannel",
   667  						Name:      "callee",
   668  						Ctor:      `{"Args":["QUERY"]}`,
   669  					})
   670  					Expect(err).NotTo(HaveOccurred())
   671  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   672  					Expect(sess).To(gbytes.Say("callee:bar"))
   673  				})
   674  
   675  				It("performs a cc2cc invocation which fails because in the meantime, the callee is upgraded with the new lifecycle", func() {
   676  					By("invoking the chaincode and generating a transaction")
   677  					signedProp, prop, txid := SignedProposal(
   678  						"testchannel",
   679  						"caller",
   680  						userSigner,
   681  						"INVOKE",
   682  						"callee",
   683  					)
   684  					presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   685  					Expect(err).NotTo(HaveOccurred())
   686  					Expect(presp).NotTo(BeNil())
   687  
   688  					env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   689  					Expect(err).NotTo(HaveOccurred())
   690  					Expect(env).NotTo(BeNil())
   691  
   692  					By("upgrading the callee with the new definition")
   693  					nwo.DeployChaincode(network, "testchannel", orderer, calleeDefNew)
   694  
   695  					By("committing the transaction")
   696  					err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   697  					Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)")))
   698  
   699  					By("querying the caller chaincode")
   700  					sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   701  						ChannelID: "testchannel",
   702  						Name:      "caller",
   703  						Ctor:      `{"Args":["QUERY"]}`,
   704  					})
   705  					Expect(err).NotTo(HaveOccurred())
   706  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   707  					Expect(sess).To(gbytes.Say("caller:foo"))
   708  
   709  					By("querying the callee chaincode")
   710  					sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   711  						ChannelID: "testchannel",
   712  						Name:      "callee",
   713  						Ctor:      `{"Args":["QUERY"]}`,
   714  					})
   715  					Expect(err).NotTo(HaveOccurred())
   716  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   717  					Expect(sess).To(gbytes.Say("callee:foo"))
   718  				})
   719  
   720  				It("performs a cc2cc invocation which fails because in the meantime, the caller is upgraded with the new lifecycle", func() {
   721  					By("invoking the chaincode and generating a transaction")
   722  					signedProp, prop, txid := SignedProposal(
   723  						"testchannel",
   724  						"caller",
   725  						userSigner,
   726  						"INVOKE",
   727  						"callee",
   728  					)
   729  					presp, err := endorserClient.ProcessProposal(context.Background(), signedProp)
   730  					Expect(err).NotTo(HaveOccurred())
   731  					Expect(presp).NotTo(BeNil())
   732  
   733  					env, err := protoutil.CreateSignedTx(prop, userSigner, presp)
   734  					Expect(err).NotTo(HaveOccurred())
   735  					Expect(env).NotTo(BeNil())
   736  
   737  					By("upgrading the caller with the new definition")
   738  					nwo.DeployChaincode(network, "testchannel", orderer, callerDefNew)
   739  
   740  					By("committing the transaction")
   741  					err = CommitTx(network, env, endorsers[0], deliveryClient, ordererClient, userSigner, txid)
   742  					Expect(err).To(MatchError(ContainSubstring("transaction invalidated with status (MVCC_READ_CONFLICT)")))
   743  
   744  					By("querying the caller chaincode")
   745  					sess, err := network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   746  						ChannelID: "testchannel",
   747  						Name:      "caller",
   748  						Ctor:      `{"Args":["QUERY"]}`,
   749  					})
   750  					Expect(err).NotTo(HaveOccurred())
   751  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   752  					Expect(sess).To(gbytes.Say("caller:foo"))
   753  
   754  					By("querying the callee chaincode")
   755  					sess, err = network.PeerUserSession(endorsers[0], "User1", commands.ChaincodeQuery{
   756  						ChannelID: "testchannel",
   757  						Name:      "callee",
   758  						Ctor:      `{"Args":["QUERY"]}`,
   759  					})
   760  					Expect(err).NotTo(HaveOccurred())
   761  					Eventually(sess, network.EventuallyTimeout).Should(gexec.Exit(0))
   762  					Expect(sess).To(gbytes.Say("callee:foo"))
   763  				})
   764  			})
   765  		})
   766  	})
   767  })