@@ -116,12 +116,18 @@ func closeListenerAndSleep(l net.Listener) {
116
116
}
117
117
}
118
118
119
- //getProposal gets the proposal for the chaincode invocation
120
- //Currently supported only for Invokes (Queries still go through devops client)
121
- func getInvokeProposal (cis * pb.ChaincodeInvocationSpec , chainID string , creator []byte ) (* pb.Proposal , error ) {
122
- proposal , _ , err := pbutils .CreateChaincodeProposal (common .HeaderType_ENDORSER_TRANSACTION , chainID , cis , creator )
119
+ // getInvokeProposal gets the proposal for the chaincode invocation
120
+ // Currently supported only for Invokes
121
+ // It returns the proposal and the transaction id associated to the proposal
122
+ func getInvokeProposal (cis * pb.ChaincodeInvocationSpec , chainID string , creator []byte ) (* pb.Proposal , string , error ) {
123
+ return pbutils .CreateChaincodeProposal (common .HeaderType_ENDORSER_TRANSACTION , chainID , cis , creator )
124
+ }
123
125
124
- return proposal , err
126
+ // getInvokeProposalOverride allows to get a proposal for the chaincode invocation
127
+ // overriding transaction id and nonce which are by default auto-generated.
128
+ // It returns the proposal and the transaction id associated to the proposal
129
+ func getInvokeProposalOverride (txid string , cis * pb.ChaincodeInvocationSpec , chainID string , nonce , creator []byte ) (* pb.Proposal , string , error ) {
130
+ return pbutils .CreateChaincodeProposalWithTxIDNonceAndTransient (txid , common .HeaderType_ENDORSER_TRANSACTION , chainID , cis , nonce , creator , nil )
125
131
}
126
132
127
133
func getDeployProposal (cds * pb.ChaincodeDeploymentSpec , chainID string , creator []byte ) (* pb.Proposal , error ) {
@@ -152,7 +158,7 @@ func getDeployOrUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string,
152
158
153
159
//...and get the proposal for it
154
160
var prop * pb.Proposal
155
- if prop , err = getInvokeProposal (lcccSpec , chainID , creator ); err != nil {
161
+ if prop , _ , err = getInvokeProposal (lcccSpec , chainID , creator ); err != nil {
156
162
return nil , err
157
163
}
158
164
@@ -235,7 +241,40 @@ func deployOrUpgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.
235
241
return resp , prop , err
236
242
}
237
243
238
- func invoke (chainID string , spec * pb.ChaincodeSpec ) (* pb.ProposalResponse , error ) {
244
+ func invoke (chainID string , spec * pb.ChaincodeSpec ) (* pb.Proposal , * pb.ProposalResponse , string , []byte , error ) {
245
+ invocation := & pb.ChaincodeInvocationSpec {ChaincodeSpec : spec }
246
+
247
+ creator , err := signer .Serialize ()
248
+ if err != nil {
249
+ return nil , nil , "" , nil , err
250
+ }
251
+
252
+ var prop * pb.Proposal
253
+ prop , txID , err := getInvokeProposal (invocation , chainID , creator )
254
+ if err != nil {
255
+ return nil , nil , "" , nil , fmt .Errorf ("Error creating proposal %s: %s\n " , spec .ChaincodeId , err )
256
+ }
257
+
258
+ nonce , err := pbutils .GetNonce (prop )
259
+ if err != nil {
260
+ return nil , nil , "" , nil , fmt .Errorf ("Failed getting nonce %s: %s\n " , spec .ChaincodeId , err )
261
+ }
262
+
263
+ var signedProp * pb.SignedProposal
264
+ signedProp , err = getSignedProposal (prop , signer )
265
+ if err != nil {
266
+ return nil , nil , "" , nil , err
267
+ }
268
+
269
+ resp , err := endorserServer .ProcessProposal (context .Background (), signedProp )
270
+ if err != nil {
271
+ return nil , nil , "" , nil , fmt .Errorf ("Error endorsing %s: %s\n " , spec .ChaincodeId , err )
272
+ }
273
+
274
+ return prop , resp , txID , nonce , err
275
+ }
276
+
277
+ func invokeWithOverride (txid string , chainID string , spec * pb.ChaincodeSpec , nonce []byte ) (* pb.ProposalResponse , error ) {
239
278
invocation := & pb.ChaincodeInvocationSpec {ChaincodeSpec : spec }
240
279
241
280
creator , err := signer .Serialize ()
@@ -244,9 +283,9 @@ func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error
244
283
}
245
284
246
285
var prop * pb.Proposal
247
- prop , err = getInvokeProposal ( invocation , chainID , creator )
286
+ prop , _ , err = getInvokeProposalOverride ( txid , invocation , chainID , nonce , creator )
248
287
if err != nil {
249
- return nil , fmt .Errorf ("Error creating proposal %s : %s\n " , spec .ChaincodeId , err )
288
+ return nil , fmt .Errorf ("Error creating proposal with override %s %s : %s\n " , txid , spec .ChaincodeId , err )
250
289
}
251
290
252
291
var signedProp * pb.SignedProposal
@@ -257,7 +296,7 @@ func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.ProposalResponse, error
257
296
258
297
resp , err := endorserServer .ProcessProposal (context .Background (), signedProp )
259
298
if err != nil {
260
- return nil , fmt .Errorf ("Error endorsing %s: %s\n " , spec .ChaincodeId , err )
299
+ return nil , fmt .Errorf ("Error endorsing %s %s : %s\n " , txid , spec .ChaincodeId , err )
261
300
}
262
301
263
302
return resp , err
@@ -352,21 +391,54 @@ func TestDeployAndInvoke(t *testing.T) {
352
391
err = endorserServer .(* Endorser ).commitTxSimulation (prop , chainID , signer , resp , nextBlockNumber )
353
392
if err != nil {
354
393
t .Fail ()
355
- t .Logf ("Error committing <%s>: %s" , chaincodeID1 , err )
394
+ t .Logf ("Error committing deploy <%s>: %s" , chaincodeID1 , err )
356
395
chaincode .GetChain ().Stop (ctxt , cccid , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeId : chaincodeID }})
357
396
return
358
397
}
359
398
360
399
f = "invoke"
361
400
invokeArgs := append ([]string {f }, args ... )
362
401
spec = & pb.ChaincodeSpec {Type : 1 , ChaincodeId : chaincodeID , Input : & pb.ChaincodeInput {Args : util .ToChaincodeArgs (invokeArgs ... )}}
363
- _ , err = invoke (chainID , spec )
402
+ prop , resp , txid , nonce , err : = invoke (chainID , spec )
364
403
if err != nil {
365
404
t .Fail ()
366
405
t .Logf ("Error invoking transaction: %s" , err )
367
406
chaincode .GetChain ().Stop (ctxt , cccid , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeId : chaincodeID }})
368
407
return
369
408
}
409
+ // Commit invoke
410
+ nextBlockNumber ++
411
+ err = endorserServer .(* Endorser ).commitTxSimulation (prop , chainID , signer , resp , nextBlockNumber )
412
+ if err != nil {
413
+ t .Fail ()
414
+ t .Logf ("Error committing first invoke <%s>: %s" , chaincodeID1 , err )
415
+ chaincode .GetChain ().Stop (ctxt , cccid , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeId : chaincodeID }})
416
+ return
417
+ }
418
+
419
+ // Now test for an invalid TxID
420
+ f = "invoke"
421
+ invokeArgs = append ([]string {f }, args ... )
422
+ spec = & pb.ChaincodeSpec {Type : 1 , ChaincodeId : chaincodeID , Input : & pb.ChaincodeInput {Args : util .ToChaincodeArgs (invokeArgs ... )}}
423
+ _ , err = invokeWithOverride ("invalid_tx_id" , chainID , spec , nonce )
424
+ if err == nil {
425
+ t .Fail ()
426
+ t .Log ("Replay attack protection faild. Transaction with invalid txid passed" )
427
+ chaincode .GetChain ().Stop (ctxt , cccid , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeId : chaincodeID }})
428
+ return
429
+ }
430
+
431
+ // Now test for duplicated TxID
432
+ f = "invoke"
433
+ invokeArgs = append ([]string {f }, args ... )
434
+ spec = & pb.ChaincodeSpec {Type : 1 , ChaincodeId : chaincodeID , Input : & pb.ChaincodeInput {Args : util .ToChaincodeArgs (invokeArgs ... )}}
435
+ _ , err = invokeWithOverride (txid , chainID , spec , nonce )
436
+ if err == nil {
437
+ t .Fail ()
438
+ t .Log ("Replay attack protection faild. Transaction with duplicaged txid passed" )
439
+ chaincode .GetChain ().Stop (ctxt , cccid , & pb.ChaincodeDeploymentSpec {ChaincodeSpec : & pb.ChaincodeSpec {ChaincodeId : chaincodeID }})
440
+ return
441
+ }
370
442
371
443
fmt .Printf ("Invoke test passed\n " )
372
444
t .Logf ("Invoke test passed" )
@@ -405,7 +477,7 @@ func TestDeployAndUpgrade(t *testing.T) {
405
477
return
406
478
}
407
479
408
- var nextBlockNumber uint64 = 1 // something above created block 0
480
+ var nextBlockNumber uint64 = 2 // something above created block 0
409
481
err = endorserServer .(* Endorser ).commitTxSimulation (prop , chainID , signer , resp , nextBlockNumber )
410
482
if err != nil {
411
483
t .Fail ()
0 commit comments