@@ -119,24 +119,38 @@ func closeListenerAndSleep(l net.Listener) {
119
119
120
120
//getProposal gets the proposal for the chaincode invocation
121
121
//Currently supported only for Invokes (Queries still go through devops client)
122
- func getProposal (cis * pb.ChaincodeInvocationSpec , chainID string , creator []byte ) (* pb.Proposal , error ) {
122
+ func getInvokeProposal (cis * pb.ChaincodeInvocationSpec , chainID string , creator []byte ) (* pb.Proposal , error ) {
123
123
uuid := util .GenerateUUID ()
124
124
return pbutils .CreateChaincodeProposal (uuid , chainID , cis , creator )
125
125
}
126
126
127
- //getDeployProposal gets the proposal for the chaincode deployment
128
- //the payload is a ChaincodeDeploymentSpec
129
127
func getDeployProposal (cds * pb.ChaincodeDeploymentSpec , chainID string , creator []byte ) (* pb.Proposal , error ) {
128
+ return getDeployOrUpgradeProposal (cds , chainID , creator , false )
129
+ }
130
+
131
+ func getUpgradeProposal (cds * pb.ChaincodeDeploymentSpec , chainID string , creator []byte ) (* pb.Proposal , error ) {
132
+ return getDeployOrUpgradeProposal (cds , chainID , creator , true )
133
+ }
134
+
135
+ //getDeployOrUpgradeProposal gets the proposal for the chaincode deploy or upgrade
136
+ //the payload is a ChaincodeDeploymentSpec
137
+ func getDeployOrUpgradeProposal (cds * pb.ChaincodeDeploymentSpec , chainID string , creator []byte , upgrade bool ) (* pb.Proposal , error ) {
130
138
b , err := proto .Marshal (cds )
131
139
if err != nil {
132
140
return nil , err
133
141
}
134
142
143
+ var propType string
144
+ if upgrade {
145
+ propType = "upgrade"
146
+ } else {
147
+ propType = "deploy"
148
+ }
135
149
//wrap the deployment in an invocation spec to lccc...
136
- lcccSpec := & pb.ChaincodeInvocationSpec {ChaincodeSpec : & pb.ChaincodeSpec {Type : pb .ChaincodeSpec_GOLANG , ChaincodeID : & pb.ChaincodeID {Name : "lccc" }, CtorMsg : & pb.ChaincodeInput {Args : [][]byte {[]byte ("deploy" ), []byte (chainID ), b }}}}
150
+ lcccSpec := & pb.ChaincodeInvocationSpec {ChaincodeSpec : & pb.ChaincodeSpec {Type : pb .ChaincodeSpec_GOLANG , ChaincodeID : & pb.ChaincodeID {Name : "lccc" }, CtorMsg : & pb.ChaincodeInput {Args : [][]byte {[]byte (propType ), []byte (chainID ), b }}}}
137
151
138
152
//...and get the proposal for it
139
- return getProposal (lcccSpec , chainID , creator )
153
+ return getInvokeProposal (lcccSpec , chainID , creator )
140
154
}
141
155
142
156
func getSignedProposal (prop * pb.Proposal , signer msp.SigningIdentity ) (* pb.SignedProposal , error ) {
@@ -163,6 +177,14 @@ func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.Cha
163
177
}
164
178
165
179
func deploy (endorserServer pb.EndorserServer , chainID string , spec * pb.ChaincodeSpec , f func (* pb.ChaincodeDeploymentSpec )) (* pb.ProposalResponse , * pb.Proposal , error ) {
180
+ return deployOrUpgrade (endorserServer , chainID , spec , f , false )
181
+ }
182
+
183
+ func upgrade (endorserServer pb.EndorserServer , chainID string , spec * pb.ChaincodeSpec , f func (* pb.ChaincodeDeploymentSpec )) (* pb.ProposalResponse , * pb.Proposal , error ) {
184
+ return deployOrUpgrade (endorserServer , chainID , spec , f , true )
185
+ }
186
+
187
+ func deployOrUpgrade (endorserServer pb.EndorserServer , chainID string , spec * pb.ChaincodeSpec , f func (* pb.ChaincodeDeploymentSpec ), upgrade bool ) (* pb.ProposalResponse , * pb.Proposal , error ) {
166
188
var err error
167
189
var depSpec * pb.ChaincodeDeploymentSpec
168
190
@@ -182,7 +204,11 @@ func deploy(endorserServer pb.EndorserServer, chainID string, spec *pb.Chaincode
182
204
}
183
205
184
206
var prop * pb.Proposal
185
- prop , err = getDeployProposal (depSpec , chainID , creator )
207
+ if upgrade {
208
+ prop , err = getUpgradeProposal (depSpec , chainID , creator )
209
+ } else {
210
+ prop , err = getDeployProposal (depSpec , chainID , creator )
211
+ }
186
212
if err != nil {
187
213
return nil , nil , err
188
214
}
@@ -208,7 +234,7 @@ func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error
208
234
}
209
235
210
236
var prop * pb.Proposal
211
- prop , err = getProposal (invocation , chainID , creator )
237
+ prop , err = getInvokeProposal (invocation , chainID , creator )
212
238
if err != nil {
213
239
return nil , fmt .Errorf ("Error creating proposal %s: %s\n " , spec .ChaincodeID , err )
214
240
}
@@ -352,6 +378,49 @@ func TestDeployAndInvoke(t *testing.T) {
352
378
chaincode .GetChain ().Stop (ctxt , chainID , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeID : chaincodeID }})
353
379
}
354
380
381
+ // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it
382
+ func TestDeployAndUpgrade (t * testing.T ) {
383
+ chainID := util .GetTestChainID ()
384
+ var ctxt = context .Background ()
385
+
386
+ url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01"
387
+ url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02"
388
+ chaincodeID1 := & pb.ChaincodeID {Path : url1 , Name : "upgradeex01" }
389
+ chaincodeID2 := & pb.ChaincodeID {Path : url2 , Name : "upgradeex01" }
390
+
391
+ f := "init"
392
+ argsDeploy := util .ToChaincodeArgs (f , "a" , "100" , "b" , "200" )
393
+ spec := & pb.ChaincodeSpec {Type : 1 , ChaincodeID : chaincodeID1 , CtorMsg : & pb.ChaincodeInput {Args : argsDeploy }}
394
+ resp , prop , err := deploy (endorserServer , chainID , spec , nil )
395
+ chaincodeName := spec .ChaincodeID .Name
396
+ if err != nil {
397
+ t .Fail ()
398
+ t .Logf ("Error deploying <%s>: %s" , chaincodeName , err )
399
+ return
400
+ }
401
+
402
+ err = endorserServer .(* Endorser ).commitTxSimulation (prop , chainID , signer , resp )
403
+ if err != nil {
404
+ t .Fail ()
405
+ t .Logf ("Error committing <%s>: %s" , chaincodeName , err )
406
+ return
407
+ }
408
+
409
+ argsUpgrade := util .ToChaincodeArgs (f , "a" , "150" , "b" , "300" )
410
+ spec = & pb.ChaincodeSpec {Type : 1 , ChaincodeID : chaincodeID2 , CtorMsg : & pb.ChaincodeInput {Args : argsUpgrade }}
411
+ resp , prop , err = upgrade (endorserServer , chainID , spec , nil )
412
+ if err != nil {
413
+ t .Fail ()
414
+ t .Logf ("Error upgrading <%s>: %s" , chaincodeName , err )
415
+ return
416
+ }
417
+
418
+ fmt .Printf ("Upgrade test passed\n " )
419
+ t .Logf ("Upgrade test passed" )
420
+
421
+ chaincode .GetChain ().Stop (ctxt , chainID , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeID : chaincodeID2 }})
422
+ }
423
+
355
424
func TestMain (m * testing.M ) {
356
425
SetupTestConfig ()
357
426
viper .Set ("peer.fileSystemPath" , filepath .Join (os .TempDir (), "hyperledger" , "production" ))
0 commit comments