github.com/hyperledger-labs/bdls@v2.1.1+incompatible/integration/pvtdata/implicit_coll_test.go (about) 1 /* 2 Copyright IBM Corp All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package pvtdata 8 9 import ( 10 "encoding/base64" 11 "encoding/json" 12 "fmt" 13 "path/filepath" 14 "time" 15 16 "github.com/hyperledger/fabric/integration/chaincode/kvexecutor" 17 "github.com/hyperledger/fabric/integration/nwo" 18 "github.com/hyperledger/fabric/integration/nwo/commands" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 22 "github.com/tedsuo/ifrit" 23 ) 24 25 var _ bool = Describe("Pvtdata dissemination for implicit collection", func() { 26 var ( 27 network *nwo.Network 28 process ifrit.Process 29 orderer *nwo.Orderer 30 testChaincode chaincode 31 ) 32 33 BeforeEach(func() { 34 By("setting up the network") 35 network = initThreeOrgsSetup(false) 36 37 By("disabling pvtdata pull/dissemination/reconciliation on all peers except for enabling dissemination on org1 peers") 38 for _, p := range network.Peers { 39 core := network.ReadPeerConfig(p) 40 core.Peer.Gossip.PvtData.PullRetryThreshold = 0 41 core.Peer.Gossip.PvtData.ReconciliationEnabled = false 42 // set timeout and reconnect interval to prevent test flake 43 core.Peer.Gossip.DialTimeout = 5 * time.Second 44 core.Peer.Gossip.ConnTimeout = 5 * time.Second 45 core.Peer.Gossip.ReconnectInterval = 7 * time.Second 46 if p.Organization == "Org1" { 47 // enable dissemination on org1 peers 48 core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.RequiredPeerCount = 1 49 core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.MaxPeerCount = 3 50 core.Peer.Gossip.PvtData.PushAckTimeout = 10 * time.Second 51 } else { 52 // disable dissemination on non-org1 peers 53 core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.RequiredPeerCount = 0 54 core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.MaxPeerCount = 0 55 } 56 network.WritePeerConfig(p, core) 57 } 58 59 By("starting the network") 60 process, orderer = startNetwork(network) 61 62 By("deploying new lifecycle chaincode") 63 testChaincode = chaincode{ 64 Chaincode: nwo.Chaincode{ 65 Name: "kvexecutor", 66 Version: "1.0", 67 Path: components.Build("github.com/hyperledger/fabric/integration/chaincode/kvexecutor/cmd"), 68 Lang: "binary", 69 PackageFile: filepath.Join(network.RootDir, "kvexcutor.tar.gz"), 70 Label: "kvexcutor", 71 Sequence: "1", 72 }, 73 isLegacy: false, 74 } 75 nwo.EnableCapabilities(network, channelID, "Application", "V2_0", orderer, network.Peers...) 76 77 By("verifying org1.peer0 discovers all peers to ensure that gossip has been initialized") 78 discoverAllPeers(network, network.Peer("Org1", "peer0"), channelID, 3, 5*time.Second) 79 80 By("verifying org1.peer1 discovers all peers to ensure that gossip has been initialized") 81 discoverAllPeers(network, network.Peer("Org1", "peer1"), channelID, 3, 5*time.Second) 82 83 By("deploying chaincode to all peers") 84 deployChaincode(network, orderer, testChaincode) 85 }) 86 87 AfterEach(func() { 88 testCleanup(network, process) 89 }) 90 91 It("disseminates pvtdata of implicit collection for the peer's own org but not implicit collection for another org", func() { 92 org1peer0 := network.Peer("Org1", "peer0") 93 org1peer1 := network.Peer("Org1", "peer1") 94 org2peer0 := network.Peer("Org2", "peer0") 95 org2peer1 := network.Peer("Org2", "peer1") 96 97 By("writing private data to org1's and org2's implicit collections") 98 writeInput := []kvexecutor.KVData{ 99 {Collection: "_implicit_org_Org1MSP", Key: "org1_key1", Value: "org1_value1"}, 100 {Collection: "_implicit_org_Org2MSP", Key: "org2_key1", Value: "org2_value1"}, 101 } 102 writeImplicitCollection(network, orderer, testChaincode.Name, writeInput, org1peer0, org2peer0) 103 104 By("querying org1.peer0 for _implicit_org_Org1MSP collection data, expecting pvtdata") 105 readInput1 := []kvexecutor.KVData{{Collection: "_implicit_org_Org1MSP", Key: "org1_key1"}} 106 expectedMsg1, err := json.Marshal(writeInput[:1]) 107 Expect(err).NotTo(HaveOccurred()) 108 readImplicitCollection(network, org1peer0, testChaincode.Name, readInput1, string(expectedMsg1), true) 109 110 // org1.peer1 should have _implicit_org_Org1MSP pvtdata because dissemination is enabled on org1 peers 111 By("querying org1.peer1 for _implicit_org_Org1MSP collection data, expecting pvtdata") 112 readImplicitCollection(network, org1peer1, testChaincode.Name, readInput1, string(expectedMsg1), true) 113 114 By("querying org2.peer0 for _implicit_org_Org1MSP collection data, expecting error") 115 readImplicitCollection(network, org2peer0, testChaincode.Name, readInput1, 116 "private data matching public hash version is not available", false) 117 118 By("querying org2.peer1 for _implicit_org_Org1MSP collection data, expecting error") 119 readImplicitCollection(network, org2peer1, testChaincode.Name, readInput1, 120 "private data matching public hash version is not available", false) 121 122 By("querying org2.peer0 for _implicit_org_Org2MSP collection data, expecting pvtdata") 123 readInput2 := []kvexecutor.KVData{{Collection: "_implicit_org_Org2MSP", Key: "org2_key1"}} 124 expectedMsg2, err := json.Marshal(writeInput[1:]) 125 Expect(err).NotTo(HaveOccurred()) 126 readImplicitCollection(network, org2peer0, testChaincode.Name, readInput2, string(expectedMsg2), true) 127 128 // org2.peer1 should have no _implicit_org_Org2MSP pvtdata because pull/dissemination/reconciliation are disabled on org2 peers 129 By("querying org2.peer1 for _implicit_org_Org2MSP collection data, expecting error") 130 readImplicitCollection(network, org2peer1, testChaincode.Name, readInput2, 131 "private data matching public hash version is not available", false) 132 133 By("querying org1.peer0 for _implicit_org_Org2MSP collection data, expecting error") 134 readImplicitCollection(network, org1peer0, testChaincode.Name, readInput2, 135 "private data matching public hash version is not available", false) 136 137 By("querying org1.peer1 for _implicit_org_Org2MSP collection data, expecting error") 138 readImplicitCollection(network, org1peer1, testChaincode.Name, readInput2, 139 "private data matching public hash version is not available", false) 140 }) 141 }) 142 143 func writeImplicitCollection(n *nwo.Network, orderer *nwo.Orderer, chaincodeName string, writeInput []kvexecutor.KVData, peers ...*nwo.Peer) { 144 writeInputBytes, err := json.Marshal(writeInput) 145 Expect(err).NotTo(HaveOccurred()) 146 writeInputBase64 := base64.StdEncoding.EncodeToString(writeInputBytes) 147 148 peerAddresses := make([]string, 0) 149 for _, peer := range peers { 150 peerAddresses = append(peerAddresses, n.PeerAddress(peer, nwo.ListenPort)) 151 } 152 command := commands.ChaincodeInvoke{ 153 ChannelID: channelID, 154 Orderer: n.OrdererAddress(orderer, nwo.ListenPort), 155 Name: chaincodeName, 156 Ctor: fmt.Sprintf(`{"Args":["readWriteKVs","%s","%s"]}`, "", writeInputBase64), 157 PeerAddresses: peerAddresses, 158 WaitForEvent: true, 159 } 160 invokeChaincode(n, peers[0], command) 161 nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peers[0], channelID), n.Peers...) 162 } 163 164 func readImplicitCollection(n *nwo.Network, peer *nwo.Peer, chaincodeName string, readInput []kvexecutor.KVData, expectedMsg string, expectSuccess bool) { 165 readInputBytes, err := json.Marshal(readInput) 166 Expect(err).NotTo(HaveOccurred()) 167 readInputBase64 := base64.StdEncoding.EncodeToString(readInputBytes) 168 169 command := commands.ChaincodeQuery{ 170 ChannelID: channelID, 171 Name: chaincodeName, 172 Ctor: fmt.Sprintf(`{"Args":["readWriteKVs","%s","%s"]}`, readInputBase64, ""), 173 } 174 queryChaincode(n, peer, command, expectedMsg, expectSuccess) 175 } 176 177 func discoverAllPeers(n *nwo.Network, peer *nwo.Peer, channelID string, retries int, retryInterval time.Duration) { 178 var discoveredPeers []nwo.DiscoveredPeer 179 numPeers := len(n.Peers) 180 for i := 0; i < retries; i++ { 181 discoveredPeers = nwo.DiscoverPeers(n, peer, "User1", channelID)() 182 if len(discoveredPeers) == numPeers || i == retries-1 { 183 break 184 } 185 time.Sleep(retryInterval) 186 } 187 Expect(discoveredPeers).To(HaveLen(numPeers)) 188 }