github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/gateway/gateway_discovery_test.go (about) 1 /* 2 Copyright hechain All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package gateway 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/golang/protobuf/proto" 18 "github.com/hechain20/hechain/integration/nwo" 19 "github.com/hechain20/hechain/protoutil" 20 "github.com/hyperledger/fabric-protos-go/gateway" 21 "github.com/hyperledger/fabric-protos-go/peer" 22 . "github.com/onsi/ginkgo" 23 . "github.com/onsi/gomega" 24 "github.com/tedsuo/ifrit" 25 ) 26 27 var _ = Describe("GatewayService with endorser discovery", func() { 28 var ( 29 testDir string 30 network *nwo.Network 31 orderer *nwo.Orderer 32 org1Peer0 *nwo.Peer 33 org2Peer0 *nwo.Peer 34 org3Peer0 *nwo.Peer 35 process ifrit.Process 36 peerCerts map[string]string 37 ) 38 39 loadPeerCert := func(peer *nwo.Peer) string { 40 peerCert, err := ioutil.ReadFile(network.PeerCert(peer)) 41 Expect(err).NotTo(HaveOccurred()) 42 return string(peerCert) 43 } 44 45 BeforeEach(func() { 46 var err error 47 testDir, err = ioutil.TempDir("", "gateway") 48 Expect(err).NotTo(HaveOccurred()) 49 50 client, err := docker.NewClientFromEnv() 51 Expect(err).NotTo(HaveOccurred()) 52 53 config := nwo.ThreeOrgRaft() 54 network = nwo.New(config, testDir, client, StartPort(), components) 55 56 network.GenerateConfigTree() 57 network.Bootstrap() 58 59 networkRunner := network.NetworkGroupRunner() 60 process = ifrit.Invoke(networkRunner) 61 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 62 63 orderer = network.Orderer("orderer") 64 network.CreateAndJoinChannel(orderer, "testchannel") 65 network.UpdateChannelAnchors(orderer, "testchannel") 66 network.VerifyMembership( 67 network.PeersWithChannel("testchannel"), 68 "testchannel", 69 ) 70 nwo.EnableCapabilities( 71 network, 72 "testchannel", 73 "Application", "V2_0", 74 orderer, 75 network.PeersWithChannel("testchannel")..., 76 ) 77 78 org1Peer0 = network.Peer("Org1", "peer0") 79 org2Peer0 = network.Peer("Org2", "peer0") 80 org3Peer0 = network.Peer("Org3", "peer0") 81 82 peerCerts = map[string]string{ 83 loadPeerCert(org1Peer0): org1Peer0.ID(), 84 loadPeerCert(org2Peer0): org2Peer0.ID(), 85 loadPeerCert(org3Peer0): org3Peer0.ID(), 86 } 87 88 chaincode := nwo.Chaincode{ 89 Name: "gatewaycc", 90 Version: "0.0", 91 Path: components.Build("github.com/hechain20/hechain/integration/chaincode/simple/cmd"), 92 Lang: "binary", 93 PackageFile: filepath.Join(testDir, "gatewaycc.tar.gz"), 94 Ctor: `{"Args":["init","a","100","b","200"]}`, 95 SignaturePolicy: `AND ('Org1MSP.peer')`, 96 Sequence: "1", 97 InitRequired: true, 98 Label: "gatewaycc_label", 99 } 100 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 101 102 chaincode = nwo.Chaincode{ 103 Name: "sbecc", 104 Version: "0.0", 105 Path: components.Build("github.com/hechain20/hechain/integration/chaincode/keylevelep/cmd"), 106 Ctor: `{"Args":["init"]}`, 107 Lang: "binary", 108 PackageFile: filepath.Join(testDir, "sbecc.tar.gz"), 109 SignaturePolicy: `OR ('Org3MSP.member')`, 110 Sequence: "1", 111 InitRequired: true, 112 Label: "sbecc_label", 113 CollectionsConfig: filepath.Join("testdata", "collections_config_sbe.json"), 114 } 115 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 116 117 chaincode = nwo.Chaincode{ 118 Name: "readpvtcc", 119 Version: "0.0", 120 Path: components.Build("github.com/hechain20/hechain/integration/chaincode/keylevelep/cmd"), 121 Ctor: `{"Args":["init"]}`, 122 Lang: "binary", 123 PackageFile: filepath.Join(testDir, "readpvtcc.tar.gz"), 124 SignaturePolicy: `OR ('Org1MSP.member', 'Org3MSP.member')`, 125 Sequence: "1", 126 InitRequired: true, 127 Label: "readpvtcc_label", 128 CollectionsConfig: filepath.Join("testdata", "collections_config_read.json"), 129 } 130 nwo.DeployChaincode(network, "testchannel", orderer, chaincode) 131 }) 132 133 AfterEach(func() { 134 if process != nil { 135 process.Signal(syscall.SIGTERM) 136 Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) 137 } 138 if network != nil { 139 network.Cleanup() 140 } 141 os.RemoveAll(testDir) 142 }) 143 144 verifyEndorsers := func(endorseResponse *gateway.EndorseResponse, expectedEndorsers []string) { 145 preparedTransaction := endorseResponse.GetPreparedTransaction() 146 payload, err := protoutil.UnmarshalPayload(preparedTransaction.GetPayload()) 147 Expect(err).NotTo(HaveOccurred()) 148 transaction, err := protoutil.UnmarshalTransaction(payload.GetData()) 149 Expect(err).NotTo(HaveOccurred()) 150 Expect(transaction.GetActions()).To(HaveLen(1)) 151 action, err := protoutil.UnmarshalChaincodeActionPayload(transaction.Actions[0].GetPayload()) 152 Expect(err).NotTo(HaveOccurred()) 153 endorsements := action.GetAction().GetEndorsements() 154 155 actualEndorsers := []string{} 156 for _, endorsement := range endorsements { 157 id, err := protoutil.UnmarshalSerializedIdentity(endorsement.GetEndorser()) 158 Expect(err).NotTo(HaveOccurred()) 159 actualEndorsers = append(actualEndorsers, peerCerts[string(id.IdBytes)]) 160 } 161 162 Expect(actualEndorsers).To(ConsistOf(expectedEndorsers)) 163 } 164 165 submitTransaction := func( 166 gatewayClient gateway.GatewayClient, 167 signer *nwo.SigningIdentity, 168 channel string, 169 chaincode string, 170 transactionName string, 171 arguments []string, 172 transientData map[string][]byte, 173 expectedEndorsers []string, 174 ) *peer.Response { 175 args := [][]byte{} 176 for _, arg := range arguments { 177 args = append(args, []byte(arg)) 178 } 179 proposedTransaction, transactionID := NewProposedTransaction( 180 signer, 181 channel, 182 chaincode, 183 transactionName, 184 transientData, 185 args..., 186 ) 187 188 endorseRequest := &gateway.EndorseRequest{ 189 TransactionId: transactionID, 190 ChannelId: channel, 191 ProposedTransaction: proposedTransaction, 192 } 193 194 ctx, cancel := context.WithTimeout(context.Background(), network.EventuallyTimeout) 195 defer cancel() 196 197 endorseResponse, err := gatewayClient.Endorse(ctx, endorseRequest) 198 Expect(err).NotTo(HaveOccurred()) 199 200 preparedTransaction := endorseResponse.GetPreparedTransaction() 201 preparedTransaction.Signature, err = signer.Sign(preparedTransaction.Payload) 202 Expect(err).NotTo(HaveOccurred()) 203 204 if expectedEndorsers != nil { 205 verifyEndorsers(endorseResponse, expectedEndorsers) 206 } 207 208 submitRequest := &gateway.SubmitRequest{ 209 TransactionId: transactionID, 210 ChannelId: channel, 211 PreparedTransaction: preparedTransaction, 212 } 213 _, err = gatewayClient.Submit(ctx, submitRequest) 214 Expect(err).NotTo(HaveOccurred()) 215 216 idBytes, err := signer.Serialize() 217 Expect(err).NotTo(HaveOccurred()) 218 219 statusRequest := &gateway.CommitStatusRequest{ 220 ChannelId: "testchannel", 221 Identity: idBytes, 222 TransactionId: transactionID, 223 } 224 statusRequestBytes, err := proto.Marshal(statusRequest) 225 Expect(err).NotTo(HaveOccurred()) 226 227 signature, err := signer.Sign(statusRequestBytes) 228 Expect(err).NotTo(HaveOccurred()) 229 230 signedStatusRequest := &gateway.SignedCommitStatusRequest{ 231 Request: statusRequestBytes, 232 Signature: signature, 233 } 234 235 statusResponse, err := gatewayClient.CommitStatus(ctx, signedStatusRequest) 236 Expect(err).NotTo(HaveOccurred()) 237 Expect(statusResponse.Result).To(Equal(peer.TxValidationCode_VALID)) 238 239 chaincodeAction, err := protoutil.GetActionFromEnvelopeMsg(endorseResponse.GetPreparedTransaction()) 240 Expect(err).NotTo(HaveOccurred()) 241 242 return chaincodeAction.GetResponse() 243 } 244 245 evaluateTransaction := func( 246 gatewayClient gateway.GatewayClient, 247 signer *nwo.SigningIdentity, 248 channel string, 249 chaincode string, 250 transactionName string, 251 arguments []string, 252 transientData map[string][]byte, 253 ) *peer.Response { 254 args := [][]byte{} 255 for _, arg := range arguments { 256 args = append(args, []byte(arg)) 257 } 258 proposedTransaction, transactionID := NewProposedTransaction( 259 signer, 260 channel, 261 chaincode, 262 transactionName, 263 transientData, 264 args..., 265 ) 266 267 evaluateRequest := &gateway.EvaluateRequest{ 268 TransactionId: transactionID, 269 ChannelId: channel, 270 ProposedTransaction: proposedTransaction, 271 } 272 273 ctx, cancel := context.WithTimeout(context.Background(), network.EventuallyTimeout) 274 defer cancel() 275 276 evaluateResponse, err := gatewayClient.Evaluate(ctx, evaluateRequest) 277 Expect(err).NotTo(HaveOccurred()) 278 279 return evaluateResponse.GetResult() 280 } 281 282 It("setting SBE policy should override chaincode policy", func() { 283 conn := network.PeerClientConn(org1Peer0) 284 defer conn.Close() 285 gatewayClient := gateway.NewGatewayClient(conn) 286 signingIdentity := network.PeerUserSigner(org1Peer0, "User1") 287 288 // add org2 to SBE policy - requires endorsement from org3 peer (chaincode policy) 289 submitTransaction( 290 gatewayClient, 291 signingIdentity, 292 "testchannel", 293 "sbecc", 294 "addorgs", 295 []string{"pub", "Org2MSP"}, 296 nil, 297 []string{org3Peer0.ID()}, 298 ) 299 300 // add org1 to SBE policy - requires endorsement from org2 peer (SBE policy) 301 submitTransaction( 302 gatewayClient, 303 signingIdentity, 304 "testchannel", 305 "sbecc", 306 "addorgs", 307 []string{"pub", "Org1MSP"}, 308 nil, 309 []string{org2Peer0.ID()}, 310 ) 311 312 // remove org2 to SBE policy - requires endorsement from org1, org2 peers (SBE policy) 313 submitTransaction( 314 gatewayClient, 315 signingIdentity, 316 "testchannel", 317 "sbecc", 318 "delorgs", 319 []string{"pub", "Org2MSP"}, 320 nil, 321 []string{org1Peer0.ID(), org2Peer0.ID()}, 322 ) 323 }) 324 325 It("setting SBE policy on private key then writing to should override the collection & chaincode policies", func() { 326 conn := network.PeerClientConn(org1Peer0) 327 defer conn.Close() 328 gatewayClient := gateway.NewGatewayClient(conn) 329 signingIdentity := network.PeerUserSigner(org1Peer0, "User1") 330 331 // write to private collection - requires endorsement from org2 peer (collection policy) 332 submitTransaction( 333 gatewayClient, 334 signingIdentity, 335 "testchannel", 336 "sbecc", 337 "setval", 338 []string{"priv", "initial private value"}, 339 nil, 340 []string{org2Peer0.ID()}, 341 ) 342 343 // check the value was set 344 result := evaluateTransaction( 345 gatewayClient, 346 signingIdentity, 347 "testchannel", 348 "sbecc", 349 "getval", 350 []string{"priv"}, 351 nil, 352 ) 353 Expect(result.Payload).To(Equal([]byte("initial private value"))) 354 355 // add org1 to SBE policy - requires endorsement from org2 peer (collection policy) 356 submitTransaction( 357 gatewayClient, 358 signingIdentity, 359 "testchannel", 360 "sbecc", 361 "addorgs", 362 []string{"priv", "Org1MSP"}, 363 nil, 364 []string{org2Peer0.ID()}, 365 ) 366 367 // write to private collection - requires endorsement from org1 peer (SBE policy) 368 submitTransaction( 369 gatewayClient, 370 signingIdentity, 371 "testchannel", 372 "sbecc", 373 "setval", 374 []string{"priv", "updated private value"}, 375 nil, 376 []string{org1Peer0.ID()}, 377 ) 378 379 // check the value was set 380 result = evaluateTransaction( 381 gatewayClient, 382 signingIdentity, 383 "testchannel", 384 "sbecc", 385 "getval", 386 []string{"priv"}, 387 nil, 388 ) 389 390 Expect(result.Payload).To(Equal([]byte("updated private value"))) 391 }) 392 393 It("writing to public and private keys should combine the collection & chaincode policies", func() { 394 conn := network.PeerClientConn(org1Peer0) 395 defer conn.Close() 396 gatewayClient := gateway.NewGatewayClient(conn) 397 signingIdentity := network.PeerUserSigner(org1Peer0, "User1") 398 399 // write to both pub&priv - requires endorsement from org2 (collection policy) and org3 (chaincode policy) 400 submitTransaction( 401 gatewayClient, 402 signingIdentity, 403 "testchannel", 404 "sbecc", 405 "setval", 406 []string{"both", "initial value"}, 407 nil, 408 []string{org2Peer0.ID(), org3Peer0.ID()}, 409 ) 410 411 // check the private value was set 412 result := evaluateTransaction( 413 gatewayClient, 414 signingIdentity, 415 "testchannel", 416 "sbecc", 417 "getval", 418 []string{"priv"}, 419 nil, 420 ) 421 Expect(result.Payload).To(Equal([]byte("initial value"))) 422 423 // check the public value was set 424 result = evaluateTransaction( 425 gatewayClient, 426 signingIdentity, 427 "testchannel", 428 "sbecc", 429 "getval", 430 []string{"pub"}, 431 nil, 432 ) 433 Expect(result.Payload).To(Equal([]byte("initial value"))) 434 }) 435 436 It("should combine chaincode and private SBE policies", func() { 437 conn := network.PeerClientConn(org1Peer0) 438 defer conn.Close() 439 gatewayClient := gateway.NewGatewayClient(conn) 440 signingIdentity := network.PeerUserSigner(org1Peer0, "User1") 441 442 // write to both public & private states - requires endorsement from org2 peer (collection policy) and org3 peer (chaincode) policy 443 submitTransaction( 444 gatewayClient, 445 signingIdentity, 446 "testchannel", 447 "sbecc", 448 "setval", 449 []string{"both", "initial private & public value"}, 450 nil, 451 []string{org2Peer0.ID(), org3Peer0.ID()}, 452 ) 453 454 // add org1 to SBE policy for private state - requires endorsement from org2 peer (collection policy) 455 submitTransaction( 456 gatewayClient, 457 signingIdentity, 458 "testchannel", 459 "sbecc", 460 "addorgs", 461 []string{"priv", "Org1MSP"}, 462 nil, 463 []string{org2Peer0.ID()}, 464 ) 465 466 // write to both pub&priv - requires endorsement from org1 (SBE policy) and org3 (chaincode policy) 467 submitTransaction( 468 gatewayClient, 469 signingIdentity, 470 "testchannel", 471 "sbecc", 472 "setval", 473 []string{"both", "chaincode and SBE policies"}, 474 nil, 475 []string{org1Peer0.ID(), org3Peer0.ID()}, 476 ) 477 478 // check the private value was set 479 result := evaluateTransaction( 480 gatewayClient, 481 signingIdentity, 482 "testchannel", 483 "sbecc", 484 "getval", 485 []string{"priv"}, 486 nil, 487 ) 488 Expect(result.Payload).To(Equal([]byte("chaincode and SBE policies"))) 489 }) 490 491 It("should combine collection and public SBE policies", func() { 492 conn := network.PeerClientConn(org3Peer0) 493 defer conn.Close() 494 gatewayClient := gateway.NewGatewayClient(conn) 495 signingIdentity := network.PeerUserSigner(org3Peer0, "User1") 496 497 // add org1 to SBE policy - requires endorsement from org3 peer (chaincode policy) 498 submitTransaction( 499 gatewayClient, 500 signingIdentity, 501 "testchannel", 502 "sbecc", 503 "addorgs", 504 []string{"pub", "Org1MSP"}, 505 nil, 506 []string{org3Peer0.ID()}, 507 ) 508 509 // write to both pub&priv - requires endorsement from org1 (SBE policy) and org2 (collection policy) 510 submitTransaction( 511 gatewayClient, 512 signingIdentity, 513 "testchannel", 514 "sbecc", 515 "setval", 516 []string{"both", "collection and SBE policies"}, 517 nil, 518 []string{org1Peer0.ID(), org2Peer0.ID()}, 519 ) 520 521 // check the private value was set 522 result := evaluateTransaction( 523 gatewayClient, 524 signingIdentity, 525 "testchannel", 526 "sbecc", 527 "getval", 528 []string{"pub"}, 529 nil, 530 ) 531 Expect(result.Payload).To(Equal([]byte("collection and SBE policies"))) 532 }) 533 534 It("should endorse chaincode on org3 and also seek endorsement from another org for cc2cc call", func() { 535 conn := network.PeerClientConn(org3Peer0) 536 defer conn.Close() 537 gatewayClient := gateway.NewGatewayClient(conn) 538 signingIdentity := network.PeerUserSigner(org3Peer0, "User1") 539 540 submitTransaction( 541 gatewayClient, 542 signingIdentity, 543 "testchannel", 544 "sbecc", 545 "cc2cc", 546 []string{"testchannel", "gatewaycc", "invoke", "a", "b", "10"}, 547 nil, 548 []string{org1Peer0.ID(), org3Peer0.ID()}, 549 ) 550 551 // check the transaction really worked - query via cc2cc call 552 result := evaluateTransaction( 553 gatewayClient, 554 signingIdentity, 555 "testchannel", 556 "sbecc", 557 "cc2cc", 558 []string{"testchannel", "gatewaycc", "query", "a"}, 559 nil, 560 ) 561 562 Expect(result.Payload).To(Equal([]byte("90"))) 563 }) 564 565 It("reading private data should use the collection ownership policy, not signature policy", func() { 566 conn := network.PeerClientConn(org1Peer0) 567 defer conn.Close() 568 gatewayClient := gateway.NewGatewayClient(conn) 569 signingIdentity := network.PeerUserSigner(org1Peer0, "User1") 570 571 submitTransaction( 572 gatewayClient, 573 signingIdentity, 574 "testchannel", 575 "readpvtcc", 576 "setval", 577 []string{"priv", "abcd"}, 578 nil, 579 nil, // don't care - not testing this part 580 ) 581 582 result := submitTransaction( 583 gatewayClient, 584 signingIdentity, 585 "testchannel", 586 "readpvtcc", 587 "getval", 588 []string{"priv"}, 589 nil, 590 []string{org1Peer0.ID()}, 591 ) 592 593 Expect(result.GetPayload()).To(Equal([]byte("abcd"))) 594 }) 595 })