github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/integration/e2e/instantiation_policy_test.go (about) 1 /* 2 Copyright hechain All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package e2e 8 9 import ( 10 "crypto/sha256" 11 "encoding/hex" 12 "io/ioutil" 13 "os" 14 "syscall" 15 "time" 16 17 docker "github.com/fsouza/go-dockerclient" 18 "github.com/golang/protobuf/proto" 19 "github.com/golang/protobuf/ptypes" 20 "github.com/hechain20/hechain/common/policydsl" 21 "github.com/hechain20/hechain/integration/nwo" 22 "github.com/hechain20/hechain/integration/nwo/commands" 23 "github.com/hechain20/hechain/integration/ordererclient" 24 "github.com/hyperledger/fabric-protos-go/common" 25 "github.com/hyperledger/fabric-protos-go/ledger/rwset" 26 "github.com/hyperledger/fabric-protos-go/ledger/rwset/kvrwset" 27 "github.com/hyperledger/fabric-protos-go/peer" 28 29 . "github.com/onsi/ginkgo" 30 . "github.com/onsi/gomega" 31 "github.com/onsi/gomega/gbytes" 32 "github.com/onsi/gomega/gexec" 33 "github.com/tedsuo/ifrit" 34 ) 35 36 var _ = Describe("InstantiationPolicy", func() { 37 var ( 38 testDir string 39 client *docker.Client 40 network *nwo.Network 41 process ifrit.Process 42 ) 43 44 BeforeEach(func() { 45 var err error 46 testDir, err = ioutil.TempDir("", "e2e") 47 Expect(err).NotTo(HaveOccurred()) 48 49 client, err = docker.NewClientFromEnv() 50 Expect(err).NotTo(HaveOccurred()) 51 }) 52 53 AfterEach(func() { 54 if process != nil { 55 process.Signal(syscall.SIGTERM) 56 Eventually(process.Wait(), network.EventuallyTimeout).Should(Receive()) 57 } 58 if network != nil { 59 network.Cleanup() 60 } 61 os.RemoveAll(testDir) 62 }) 63 64 Describe("single node etcdraft network with single peer", func() { 65 BeforeEach(func() { 66 config := nwo.MinimalRaft() 67 config.Profiles[1].Organizations = []string{"Org1", "Org2"} 68 network = nwo.New(config, testDir, client, StartPort(), components) 69 network.GenerateConfigTree() 70 network.Bootstrap() 71 72 networkRunner := network.NetworkGroupRunner() 73 process = ifrit.Invoke(networkRunner) 74 Eventually(process.Ready(), network.EventuallyTimeout).Should(BeClosed()) 75 }) 76 77 It("honors the instantiation policy", func() { 78 orderer := network.Orderer("orderer") 79 80 org1Peer := network.Peer("Org1", "peer0") 81 org2Peer := network.Peer("Org2", "peer0") 82 83 network.CreateAndJoinChannel(orderer, "testchannel") 84 85 By("attempting to deploy with an unsatisfied instantiation policy") 86 87 goodDeploy := LSCCOperation{ 88 Operation: "deploy", 89 ChannelID: "testchannel", 90 Name: "fakecc", 91 Version: "badip", 92 InstantiationOrgs: []*nwo.Organization{ 93 network.Organization("Org2"), 94 }, 95 } 96 97 ordererclient.Broadcast(network, orderer, goodDeploy.Tx(network.PeerUserSigner(org1Peer, "Admin"))) 98 99 nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 2, org1Peer) 100 101 Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).NotTo(gbytes.Say("Name: fakecc, Version: badip")) 102 103 By("attempting to deploy with a satisfied instantiation policy") 104 105 badDeploy := LSCCOperation{ 106 Operation: "deploy", 107 ChannelID: "testchannel", 108 Name: "fakecc", 109 Version: "goodip", 110 InstantiationOrgs: []*nwo.Organization{ 111 network.Organization("Org1"), 112 }, 113 } 114 115 ordererclient.Broadcast(network, orderer, badDeploy.Tx(network.PeerUserSigner(org1Peer, "Admin"))) 116 117 nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 3, org1Peer) 118 Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).To(gbytes.Say("Name: fakecc, Version: goodip")) 119 120 By("upgrading without satisfying the previous instantiation policy") 121 122 badUpgrade := LSCCOperation{ 123 Operation: "upgrade", 124 ChannelID: "testchannel", 125 Name: "fakecc", 126 Version: "wrongsubmitter", 127 InstantiationOrgs: []*nwo.Organization{ 128 network.Organization("Org2"), 129 }, 130 } 131 132 ordererclient.Broadcast(network, orderer, badUpgrade.Tx(network.PeerUserSigner(org2Peer, "Admin"))) 133 134 nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 4, org1Peer) 135 Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).NotTo(gbytes.Say("Name: fakecc, Version: wrongsubmitter")) 136 137 By("upgrading while satisfying the previous instantiation policy") 138 139 goodUpgrade := LSCCOperation{ 140 Operation: "upgrade", 141 ChannelID: "testchannel", 142 Name: "fakecc", 143 Version: "rightsubmitter", 144 InstantiationOrgs: []*nwo.Organization{ 145 network.Organization("Org1"), 146 }, 147 } 148 149 ordererclient.Broadcast(network, orderer, goodUpgrade.Tx(network.PeerUserSigner(org1Peer, "Admin"))) 150 151 nwo.WaitUntilEqualLedgerHeight(network, "testchannel", 5, org1Peer) 152 Expect(ListInstantiatedLegacy(network, org1Peer, "testchannel")).To(gbytes.Say("Name: fakecc, Version: rightsubmitter")) 153 }) 154 }) 155 }) 156 157 func ListInstantiatedLegacy(n *nwo.Network, p *nwo.Peer, channel string) *gbytes.Buffer { 158 sess, err := n.PeerAdminSession(p, commands.ChaincodeListInstantiatedLegacy{ 159 ChannelID: channel, 160 ClientAuth: n.ClientAuthRequired, 161 }) 162 Expect(err).NotTo(HaveOccurred()) 163 Eventually(sess, n.EventuallyTimeout).Should(gexec.Exit(0)) 164 return sess.Buffer() 165 } 166 167 type LSCCOperation struct { 168 Operation string 169 ChannelID string 170 Name string 171 Version string 172 InstantiationOrgs []*nwo.Organization 173 } 174 175 func (lo *LSCCOperation) Tx(signer *nwo.SigningIdentity) *common.Envelope { 176 creatorBytes, err := signer.Serialize() 177 Expect(err).NotTo(HaveOccurred()) 178 179 var instantiationMSPIDs []string 180 for _, org := range lo.InstantiationOrgs { 181 instantiationMSPIDs = append(instantiationMSPIDs, org.MSPID) 182 } 183 instantiationPolicy := policydsl.SignedByAnyMember(instantiationMSPIDs) 184 185 nonce, err := time.Now().MarshalBinary() 186 Expect(err).NotTo(HaveOccurred()) 187 188 timestamp, err := ptypes.TimestampProto(time.Now().UTC()) 189 Expect(err).NotTo(HaveOccurred()) 190 191 hasher := sha256.New() 192 hasher.Write(nonce) 193 hasher.Write(creatorBytes) 194 txid := hex.EncodeToString(hasher.Sum(nil)) 195 196 signatureHeaderBytes := protoMarshal(&common.SignatureHeader{ 197 Creator: creatorBytes, 198 Nonce: nonce, 199 }) 200 201 channelHeaderBytes := protoMarshal(&common.ChannelHeader{ 202 ChannelId: lo.ChannelID, 203 Extension: protoMarshal(&peer.ChaincodeHeaderExtension{ 204 ChaincodeId: &peer.ChaincodeID{ 205 Name: "lscc", 206 }, 207 }), 208 Timestamp: timestamp, 209 TxId: txid, 210 Type: int32(common.HeaderType_ENDORSER_TRANSACTION), 211 }) 212 213 chaincodeDataBytes := protoMarshal(&peer.ChaincodeData{ 214 Data: []byte("a-big-bunch-of-fakery"), 215 Id: []byte("a-friendly-fake-chaincode"), 216 Escc: "escc", 217 Vscc: "vscc", 218 Name: lo.Name, 219 Version: lo.Version, 220 InstantiationPolicy: instantiationPolicy, 221 Policy: nil, // EndorsementPolicy deliberately left nil 222 }) 223 224 proposalPayloadBytes := protoMarshal(&peer.ChaincodeProposalPayload{ 225 Input: protoMarshal(&peer.ChaincodeInvocationSpec{ 226 ChaincodeSpec: &peer.ChaincodeSpec{ 227 Input: &peer.ChaincodeInput{ 228 Args: [][]byte{ 229 []byte(lo.Operation), 230 []byte(lo.ChannelID), 231 protoMarshal(&peer.ChaincodeDeploymentSpec{ 232 ChaincodeSpec: &peer.ChaincodeSpec{ 233 ChaincodeId: &peer.ChaincodeID{ 234 Name: lo.Name, 235 Version: lo.Version, 236 }, 237 Input: &peer.ChaincodeInput{ 238 Args: [][]byte{[]byte("bogus-init-arg")}, 239 }, 240 Type: peer.ChaincodeSpec_GOLANG, 241 }, 242 }), 243 {}, // Endorsement policy bytes deliberately empty 244 []byte("escc"), 245 []byte("vscc"), 246 }, 247 }, 248 Type: peer.ChaincodeSpec_GOLANG, 249 }, 250 }), 251 }) 252 253 propHash := sha256.New() 254 propHash.Write(channelHeaderBytes) 255 propHash.Write(signatureHeaderBytes) 256 propHash.Write(proposalPayloadBytes) 257 proposalHash := propHash.Sum(nil)[:] 258 259 proposalResponsePayloadBytes := protoMarshal(&peer.ProposalResponsePayload{ 260 ProposalHash: proposalHash, 261 Extension: protoMarshal(&peer.ChaincodeAction{ 262 ChaincodeId: &peer.ChaincodeID{ 263 Name: "lscc", 264 Version: "syscc", 265 }, 266 Events: protoMarshal(&peer.ChaincodeEvent{ 267 ChaincodeId: "lscc", 268 EventName: lo.Operation, 269 Payload: protoMarshal(&peer.LifecycleEvent{ 270 ChaincodeName: lo.Name, 271 }), 272 }), 273 Response: &peer.Response{ 274 Payload: chaincodeDataBytes, 275 Status: 200, 276 }, 277 Results: protoMarshal(&rwset.TxReadWriteSet{ 278 DataModel: rwset.TxReadWriteSet_KV, 279 NsRwset: []*rwset.NsReadWriteSet{ 280 { 281 Namespace: "lscc", 282 Rwset: protoMarshal(&kvrwset.KVRWSet{ 283 Writes: []*kvrwset.KVWrite{ 284 { 285 Key: lo.Name, 286 Value: chaincodeDataBytes, 287 }, 288 }, 289 }), 290 }, 291 { 292 Namespace: lo.Name, 293 Rwset: protoMarshal(&kvrwset.KVRWSet{ 294 Writes: []*kvrwset.KVWrite{ 295 { 296 Key: "bogus-key", 297 Value: []byte("bogus-value"), 298 }, 299 }, 300 }), 301 }, 302 }, 303 }), 304 }), 305 }) 306 307 endorsementSignature, err := signer.Sign(append(proposalResponsePayloadBytes, creatorBytes...)) 308 Expect(err).NotTo(HaveOccurred()) 309 310 payloadBytes := protoMarshal(&common.Payload{ 311 Header: &common.Header{ 312 ChannelHeader: channelHeaderBytes, 313 SignatureHeader: signatureHeaderBytes, 314 }, 315 Data: protoMarshal(&peer.Transaction{ 316 Actions: []*peer.TransactionAction{ 317 { 318 Header: signatureHeaderBytes, 319 Payload: protoMarshal(&peer.ChaincodeActionPayload{ 320 ChaincodeProposalPayload: proposalPayloadBytes, 321 Action: &peer.ChaincodeEndorsedAction{ 322 ProposalResponsePayload: proposalResponsePayloadBytes, 323 Endorsements: []*peer.Endorsement{ 324 { 325 Endorser: creatorBytes, 326 Signature: endorsementSignature, 327 }, 328 }, 329 }, 330 }), 331 }, 332 }, 333 }), 334 }) 335 336 envSignature, err := signer.Sign(payloadBytes) 337 Expect(err).NotTo(HaveOccurred()) 338 339 return &common.Envelope{ 340 Payload: payloadBytes, 341 Signature: envSignature, 342 } 343 } 344 345 func protoMarshal(msg proto.Message) []byte { 346 b, err := proto.Marshal(msg) 347 Expect(err).NotTo(HaveOccurred()) 348 return b 349 }