github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/core/endorser/endorser_test.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package endorser 18 19 import ( 20 "encoding/hex" 21 "errors" 22 "flag" 23 "fmt" 24 "io/ioutil" 25 "net" 26 "os" 27 "path/filepath" 28 "runtime" 29 "strings" 30 "testing" 31 "time" 32 33 "github.com/golang/protobuf/proto" 34 "github.com/hyperledger/fabric/bccsp" 35 "github.com/hyperledger/fabric/bccsp/factory" 36 mockpolicies "github.com/hyperledger/fabric/common/mocks/policies" 37 "github.com/hyperledger/fabric/common/policies" 38 "github.com/hyperledger/fabric/common/util" 39 "github.com/hyperledger/fabric/core/chaincode" 40 "github.com/hyperledger/fabric/core/common/ccprovider" 41 "github.com/hyperledger/fabric/core/config" 42 "github.com/hyperledger/fabric/core/container" 43 "github.com/hyperledger/fabric/core/peer" 44 syscc "github.com/hyperledger/fabric/core/scc" 45 "github.com/hyperledger/fabric/core/testutil" 46 "github.com/hyperledger/fabric/msp" 47 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 48 "github.com/hyperledger/fabric/msp/mgmt/testtools" 49 "github.com/hyperledger/fabric/protos/common" 50 pb "github.com/hyperledger/fabric/protos/peer" 51 pbutils "github.com/hyperledger/fabric/protos/utils" 52 "github.com/spf13/viper" 53 "github.com/stretchr/testify/assert" 54 "golang.org/x/net/context" 55 "google.golang.org/grpc" 56 "google.golang.org/grpc/credentials" 57 ) 58 59 var endorserServer pb.EndorserServer 60 var signer msp.SigningIdentity 61 62 type testEnvironment struct { 63 tempDir string 64 listener net.Listener 65 } 66 67 //initialize peer and start up. If security==enabled, login as vp 68 func initPeer(chainID string) (*testEnvironment, error) { 69 //start clean 70 // finitPeer(nil) 71 var opts []grpc.ServerOption 72 if viper.GetBool("peer.tls.enabled") { 73 creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file")) 74 if err != nil { 75 return nil, fmt.Errorf("Failed to generate credentials %v", err) 76 } 77 opts = []grpc.ServerOption{grpc.Creds(creds)} 78 } 79 grpcServer := grpc.NewServer(opts...) 80 81 tempDir := newTempDir() 82 viper.Set("peer.fileSystemPath", filepath.Join(tempDir, "hyperledger", "production")) 83 84 peerAddress, err := peer.GetLocalAddress() 85 if err != nil { 86 return nil, fmt.Errorf("Error obtaining peer address: %s", err) 87 } 88 lis, err := net.Listen("tcp", peerAddress) 89 if err != nil { 90 return nil, fmt.Errorf("Error starting peer listener %s", err) 91 } 92 93 //initialize ledger 94 peer.MockInitialize() 95 96 mspGetter := func(cid string) []string { 97 return []string{"DEFAULT"} 98 } 99 100 peer.MockSetMSPIDGetter(mspGetter) 101 102 getPeerEndpoint := func() (*pb.PeerEndpoint, error) { 103 return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil 104 } 105 106 ccStartupTimeout := time.Duration(30000) * time.Millisecond 107 pb.RegisterChaincodeSupportServer(grpcServer, chaincode.NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) 108 109 syscc.RegisterSysCCs() 110 111 if err = peer.MockCreateChain(chainID); err != nil { 112 closeListenerAndSleep(lis) 113 return nil, err 114 } 115 116 syscc.DeploySysCCs(chainID) 117 118 go grpcServer.Serve(lis) 119 120 return &testEnvironment{tempDir: tempDir, listener: lis}, nil 121 } 122 123 func finitPeer(tev *testEnvironment) { 124 closeListenerAndSleep(tev.listener) 125 os.RemoveAll(tev.tempDir) 126 } 127 128 func closeListenerAndSleep(l net.Listener) { 129 if l != nil { 130 l.Close() 131 time.Sleep(2 * time.Second) 132 } 133 } 134 135 // getInvokeProposal gets the proposal for the chaincode invocation 136 // Currently supported only for Invokes 137 // It returns the proposal and the transaction id associated to the proposal 138 func getInvokeProposal(cis *pb.ChaincodeInvocationSpec, chainID string, creator []byte) (*pb.Proposal, string, error) { 139 return pbutils.CreateChaincodeProposal(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, creator) 140 } 141 142 // getInvokeProposalOverride allows to get a proposal for the chaincode invocation 143 // overriding transaction id and nonce which are by default auto-generated. 144 // It returns the proposal and the transaction id associated to the proposal 145 func getInvokeProposalOverride(txid string, cis *pb.ChaincodeInvocationSpec, chainID string, nonce, creator []byte) (*pb.Proposal, string, error) { 146 return pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txid, common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, nonce, creator, nil) 147 } 148 149 func getDeployProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) { 150 return getDeployOrUpgradeProposal(cds, chainID, creator, false) 151 } 152 153 func getUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte) (*pb.Proposal, error) { 154 return getDeployOrUpgradeProposal(cds, chainID, creator, true) 155 } 156 157 //getDeployOrUpgradeProposal gets the proposal for the chaincode deploy or upgrade 158 //the payload is a ChaincodeDeploymentSpec 159 func getDeployOrUpgradeProposal(cds *pb.ChaincodeDeploymentSpec, chainID string, creator []byte, upgrade bool) (*pb.Proposal, error) { 160 //we need to save off the chaincode as we have to instantiate with nil CodePackage 161 var err error 162 if err = ccprovider.PutChaincodeIntoFS(cds); err != nil { 163 return nil, err 164 } 165 166 cds.CodePackage = nil 167 168 b, err := proto.Marshal(cds) 169 if err != nil { 170 return nil, err 171 } 172 173 var propType string 174 if upgrade { 175 propType = "upgrade" 176 } else { 177 propType = "deploy" 178 } 179 sccver := util.GetSysCCVersion() 180 //wrap the deployment in an invocation spec to lscc... 181 lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc", Version: sccver}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte(propType), []byte(chainID), b}}}} 182 183 //...and get the proposal for it 184 var prop *pb.Proposal 185 if prop, _, err = getInvokeProposal(lsccSpec, chainID, creator); err != nil { 186 return nil, err 187 } 188 189 return prop, nil 190 } 191 192 func getSignedProposal(prop *pb.Proposal, signer msp.SigningIdentity) (*pb.SignedProposal, error) { 193 propBytes, err := pbutils.GetBytesProposal(prop) 194 if err != nil { 195 return nil, err 196 } 197 198 signature, err := signer.Sign(propBytes) 199 if err != nil { 200 return nil, err 201 } 202 203 return &pb.SignedProposal{ProposalBytes: propBytes, Signature: signature}, nil 204 } 205 206 func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 207 codePackageBytes, err := container.GetChaincodePackageBytes(spec) 208 if err != nil { 209 return nil, err 210 } 211 chaincodeDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} 212 return chaincodeDeploymentSpec, nil 213 } 214 215 func deploy(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) { 216 return deployOrUpgrade(endorserServer, chainID, spec, f, false) 217 } 218 219 func upgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec)) (*pb.ProposalResponse, *pb.Proposal, error) { 220 return deployOrUpgrade(endorserServer, chainID, spec, f, true) 221 } 222 223 func deployOrUpgrade(endorserServer pb.EndorserServer, chainID string, spec *pb.ChaincodeSpec, f func(*pb.ChaincodeDeploymentSpec), upgrade bool) (*pb.ProposalResponse, *pb.Proposal, error) { 224 var err error 225 var depSpec *pb.ChaincodeDeploymentSpec 226 227 ctxt := context.Background() 228 depSpec, err = getDeploymentSpec(ctxt, spec) 229 if err != nil { 230 return nil, nil, err 231 } 232 233 if f != nil { 234 f(depSpec) 235 } 236 237 creator, err := signer.Serialize() 238 if err != nil { 239 return nil, nil, err 240 } 241 242 var prop *pb.Proposal 243 if upgrade { 244 prop, err = getUpgradeProposal(depSpec, chainID, creator) 245 } else { 246 prop, err = getDeployProposal(depSpec, chainID, creator) 247 } 248 if err != nil { 249 return nil, nil, err 250 } 251 252 var signedProp *pb.SignedProposal 253 signedProp, err = getSignedProposal(prop, signer) 254 if err != nil { 255 return nil, nil, err 256 } 257 258 var resp *pb.ProposalResponse 259 resp, err = endorserServer.ProcessProposal(context.Background(), signedProp) 260 261 return resp, prop, err 262 } 263 264 func invoke(chainID string, spec *pb.ChaincodeSpec) (*pb.Proposal, *pb.ProposalResponse, string, []byte, error) { 265 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 266 267 creator, err := signer.Serialize() 268 if err != nil { 269 return nil, nil, "", nil, err 270 } 271 272 var prop *pb.Proposal 273 prop, txID, err := getInvokeProposal(invocation, chainID, creator) 274 if err != nil { 275 return nil, nil, "", nil, fmt.Errorf("Error creating proposal %s: %s\n", spec.ChaincodeId, err) 276 } 277 278 nonce, err := pbutils.GetNonce(prop) 279 if err != nil { 280 return nil, nil, "", nil, fmt.Errorf("Failed getting nonce %s: %s\n", spec.ChaincodeId, err) 281 } 282 283 var signedProp *pb.SignedProposal 284 signedProp, err = getSignedProposal(prop, signer) 285 if err != nil { 286 return nil, nil, "", nil, err 287 } 288 289 resp, err := endorserServer.ProcessProposal(context.Background(), signedProp) 290 if err != nil { 291 return nil, nil, "", nil, err 292 } 293 294 return prop, resp, txID, nonce, err 295 } 296 297 func invokeWithOverride(txid string, chainID string, spec *pb.ChaincodeSpec, nonce []byte) (*pb.ProposalResponse, error) { 298 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 299 300 creator, err := signer.Serialize() 301 if err != nil { 302 return nil, err 303 } 304 305 var prop *pb.Proposal 306 prop, _, err = getInvokeProposalOverride(txid, invocation, chainID, nonce, creator) 307 if err != nil { 308 return nil, fmt.Errorf("Error creating proposal with override %s %s: %s\n", txid, spec.ChaincodeId, err) 309 } 310 311 var signedProp *pb.SignedProposal 312 signedProp, err = getSignedProposal(prop, signer) 313 if err != nil { 314 return nil, err 315 } 316 317 resp, err := endorserServer.ProcessProposal(context.Background(), signedProp) 318 if err != nil { 319 return nil, fmt.Errorf("Error endorsing %s %s: %s\n", txid, spec.ChaincodeId, err) 320 } 321 322 return resp, err 323 } 324 325 func deleteChaincodeOnDisk(chaincodeID string) { 326 os.RemoveAll(filepath.Join(config.GetPath("peer.fileSystemPath"), "chaincodes", chaincodeID)) 327 } 328 329 //begin tests. Note that we rely upon the system chaincode and peer to be created 330 //once and be used for all the tests. In order to avoid dependencies / collisions 331 //due to deployed chaincodes, trying to use different chaincodes for different 332 //tests 333 334 //TestDeploy deploy chaincode example01 335 func TestDeploy(t *testing.T) { 336 chainID := util.GetTestChainID() 337 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex01", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 338 defer deleteChaincodeOnDisk("ex01.0") 339 340 cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil) 341 342 _, _, err := deploy(endorserServer, chainID, spec, nil) 343 if err != nil { 344 t.Fail() 345 t.Logf("Deploy-error in deploy %s", err) 346 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 347 return 348 } 349 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 350 } 351 352 //REMOVE WHEN JAVA CC IS ENABLED 353 func TestJavaDeploy(t *testing.T) { 354 chainID := util.GetTestChainID() 355 //pretend this is a java CC (type 4) 356 spec := &pb.ChaincodeSpec{Type: 4, ChaincodeId: &pb.ChaincodeID{Name: "javacc", Path: "../../examples/chaincode/java/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 357 defer deleteChaincodeOnDisk("javacc.0") 358 359 cccid := ccprovider.NewCCContext(chainID, "javacc", "0", "", false, nil, nil) 360 361 _, _, err := deploy(endorserServer, chainID, spec, nil) 362 if err == nil { 363 t.Fail() 364 t.Logf("expected java CC deploy to fail") 365 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 366 return 367 } 368 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 369 } 370 371 func TestJavaCheckWithDifferentPackageTypes(t *testing.T) { 372 //try SignedChaincodeDeploymentSpec with go chaincode (type 1) 373 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "gocc", Path: "path/to/cc", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("someargs")}}} 374 cds := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: []byte("some code")} 375 env := &common.Envelope{Payload: pbutils.MarshalOrPanic(&common.Payload{Data: pbutils.MarshalOrPanic(&pb.SignedChaincodeDeploymentSpec{ChaincodeDeploymentSpec: pbutils.MarshalOrPanic(cds)})})} 376 //wrap the package in an invocation spec to lscc... 377 b := pbutils.MarshalOrPanic(env) 378 379 lsccCID := &pb.ChaincodeID{Name: "lscc", Version: util.GetSysCCVersion()} 380 lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: lsccCID, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("install"), b}}}} 381 382 e := &Endorser{} 383 err := e.disableJavaCCInst(lsccCID, lsccSpec) 384 assert.Nil(t, err) 385 386 //now try plain ChaincodeDeploymentSpec...should succeed (go chaincode) 387 b = pbutils.MarshalOrPanic(cds) 388 389 lsccSpec = &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: lsccCID, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("install"), b}}}} 390 err = e.disableJavaCCInst(lsccCID, lsccSpec) 391 assert.Nil(t, err) 392 } 393 394 //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed 395 func TestRedeploy(t *testing.T) { 396 chainID := util.GetTestChainID() 397 398 //invalid arguments 399 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 400 401 defer deleteChaincodeOnDisk("ex02.0") 402 403 cccid := ccprovider.NewCCContext(chainID, "ex02", "0", "", false, nil, nil) 404 405 _, _, err := deploy(endorserServer, chainID, spec, nil) 406 if err != nil { 407 t.Fail() 408 t.Logf("error in endorserServer.ProcessProposal %s", err) 409 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 410 return 411 } 412 413 deleteChaincodeOnDisk("ex02.0") 414 415 //second time should not fail as we are just simulating 416 _, _, err = deploy(endorserServer, chainID, spec, nil) 417 if err != nil { 418 t.Fail() 419 t.Logf("error in endorserServer.ProcessProposal %s", err) 420 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 421 return 422 } 423 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 424 } 425 426 // TestDeployAndInvoke deploys and invokes chaincode_example01 427 func TestDeployAndInvoke(t *testing.T) { 428 chainID := util.GetTestChainID() 429 var ctxt = context.Background() 430 431 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 432 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01", Version: "0"} 433 434 defer deleteChaincodeOnDisk("ex01.0") 435 436 args := []string{"10"} 437 438 f := "init" 439 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 440 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 441 442 cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil) 443 444 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 445 chaincodeID1 := spec.ChaincodeId.Name 446 if err != nil { 447 t.Fail() 448 t.Logf("Error deploying <%s>: %s", chaincodeID1, err) 449 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 450 return 451 } 452 var nextBlockNumber uint64 = 1 // first block needs to be block number = 1. Genesis block is block 0 453 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 454 if err != nil { 455 t.Fail() 456 t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err) 457 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 458 return 459 } 460 461 f = "invoke" 462 invokeArgs := append([]string{f}, args...) 463 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 464 prop, resp, txid, nonce, err := invoke(chainID, spec) 465 if err != nil { 466 t.Fail() 467 t.Logf("Error invoking transaction: %s", err) 468 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 469 return 470 } 471 // Commit invoke 472 nextBlockNumber++ 473 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 474 if err != nil { 475 t.Fail() 476 t.Logf("Error committing first invoke <%s>: %s", chaincodeID1, err) 477 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 478 return 479 } 480 481 // Now test for an invalid TxID 482 f = "invoke" 483 invokeArgs = append([]string{f}, args...) 484 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 485 _, err = invokeWithOverride("invalid_tx_id", chainID, spec, nonce) 486 if err == nil { 487 t.Fail() 488 t.Log("Replay attack protection faild. Transaction with invalid txid passed") 489 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 490 return 491 } 492 493 // Now test for duplicated TxID 494 f = "invoke" 495 invokeArgs = append([]string{f}, args...) 496 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 497 _, err = invokeWithOverride(txid, chainID, spec, nonce) 498 if err == nil { 499 t.Fail() 500 t.Log("Replay attack protection faild. Transaction with duplicaged txid passed") 501 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 502 return 503 } 504 505 // Test chaincode endorsement failure when invalid function name supplied 506 f = "invokeinvalid" 507 invokeArgs = append([]string{f}, args...) 508 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 509 prop, resp, txid, nonce, err = invoke(chainID, spec) 510 if err == nil { 511 t.Fail() 512 t.Logf("expecting fabric to report error from chaincode failure") 513 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 514 return 515 } else if _, ok := err.(*chaincodeError); !ok { 516 t.Fail() 517 t.Logf("expecting chaincode error but found %v", err) 518 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 519 return 520 } 521 522 if resp != nil { 523 assert.Equal(t, int32(500), resp.Response.Status, "Unexpected response status") 524 } 525 526 t.Logf("Invoke test passed") 527 528 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 529 } 530 531 // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it 532 func TestDeployAndUpgrade(t *testing.T) { 533 chainID := util.GetTestChainID() 534 var ctxt = context.Background() 535 536 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 537 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 538 chaincodeID1 := &pb.ChaincodeID{Path: url1, Name: "upgradeex01", Version: "0"} 539 chaincodeID2 := &pb.ChaincodeID{Path: url2, Name: "upgradeex01", Version: "1"} 540 541 defer deleteChaincodeOnDisk("upgradeex01.0") 542 defer deleteChaincodeOnDisk("upgradeex01.1") 543 544 f := "init" 545 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 546 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID1, Input: &pb.ChaincodeInput{Args: argsDeploy}} 547 548 cccid1 := ccprovider.NewCCContext(chainID, "upgradeex01", "0", "", false, nil, nil) 549 cccid2 := ccprovider.NewCCContext(chainID, "upgradeex01", "1", "", false, nil, nil) 550 551 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 552 553 chaincodeName := spec.ChaincodeId.Name 554 if err != nil { 555 t.Fail() 556 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 557 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 558 t.Logf("Error deploying <%s>: %s", chaincodeName, err) 559 return 560 } 561 562 var nextBlockNumber uint64 = 3 // something above created block 0 563 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 564 if err != nil { 565 t.Fail() 566 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 567 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 568 t.Logf("Error committing <%s>: %s", chaincodeName, err) 569 return 570 } 571 572 argsUpgrade := util.ToChaincodeArgs(f, "a", "150", "b", "300") 573 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID2, Input: &pb.ChaincodeInput{Args: argsUpgrade}} 574 _, _, err = upgrade(endorserServer, chainID, spec, nil) 575 if err != nil { 576 t.Fail() 577 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 578 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 579 t.Logf("Error upgrading <%s>: %s", chaincodeName, err) 580 return 581 } 582 583 t.Logf("Upgrade test passed") 584 585 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 586 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 587 } 588 589 // TestWritersACLFail deploys a chaincode and then tries to invoke it; 590 // however we inject a special policy for writers to simulate 591 // the scenario in which the creator of this proposal is not among 592 // the writers for the chain 593 func TestWritersACLFail(t *testing.T) { 594 //skip pending FAB-2457 fix 595 t.Skip() 596 chainID := util.GetTestChainID() 597 var ctxt = context.Background() 598 599 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 600 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail", Version: "0"} 601 602 defer deleteChaincodeOnDisk("ex01-fail.0") 603 604 args := []string{"10"} 605 606 f := "init" 607 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 608 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 609 610 cccid := ccprovider.NewCCContext(chainID, "ex01-fail", "0", "", false, nil, nil) 611 612 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 613 chaincodeID1 := spec.ChaincodeId.Name 614 if err != nil { 615 t.Fail() 616 t.Logf("Error deploying <%s>: %s", chaincodeID1, err) 617 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 618 return 619 } 620 var nextBlockNumber uint64 = 3 // The tests that ran before this test created blocks 0-2 621 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 622 if err != nil { 623 t.Fail() 624 t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err) 625 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 626 return 627 } 628 629 // here we inject a reject policy for writers 630 // to simulate the scenario in which the invoker 631 // is not authorized to issue this proposal 632 rejectpolicy := &mockpolicies.Policy{ 633 Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"), 634 } 635 pm := peer.GetPolicyManager(chainID) 636 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationWriters: rejectpolicy} 637 638 f = "invoke" 639 invokeArgs := append([]string{f}, args...) 640 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 641 prop, resp, _, _, err = invoke(chainID, spec) 642 if err == nil { 643 t.Fail() 644 t.Logf("Invocation should have failed") 645 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 646 return 647 } 648 649 t.Logf("TestWritersACLFail passed") 650 651 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 652 } 653 654 func TestHeaderExtensionNoChaincodeID(t *testing.T) { 655 creator, _ := signer.Serialize() 656 nonce := []byte{1, 2, 3} 657 digest, err := factory.GetDefault().Hash(append(nonce, creator...), &bccsp.SHA256Opts{}) 658 txID := hex.EncodeToString(digest) 659 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: nil, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs()}} 660 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 661 prop, _, _ := pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txID, common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), invocation, []byte{1, 2, 3}, creator, nil) 662 signedProp, _ := getSignedProposal(prop, signer) 663 _, err = endorserServer.ProcessProposal(context.Background(), signedProp) 664 assert.Error(t, err) 665 assert.Contains(t, err.Error(), "ChaincodeHeaderExtension.ChaincodeId is nil") 666 } 667 668 // TestAdminACLFail deploys tried to deploy a chaincode; 669 // however we inject a special policy for admins to simulate 670 // the scenario in which the creator of this proposal is not among 671 // the admins for the chain 672 func TestAdminACLFail(t *testing.T) { 673 //skip pending FAB-2457 fix 674 t.Skip() 675 chainID := util.GetTestChainID() 676 677 // here we inject a reject policy for admins 678 // to simulate the scenario in which the invoker 679 // is not authorized to issue this proposal 680 rejectpolicy := &mockpolicies.Policy{ 681 Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"), 682 } 683 pm := peer.GetPolicyManager(chainID) 684 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationAdmins: rejectpolicy} 685 686 var ctxt = context.Background() 687 688 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01" 689 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail1", Version: "0"} 690 691 defer deleteChaincodeOnDisk("ex01-fail1.0") 692 693 f := "init" 694 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 695 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 696 697 cccid := ccprovider.NewCCContext(chainID, "ex01-fail1", "0", "", false, nil, nil) 698 699 _, _, err := deploy(endorserServer, chainID, spec, nil) 700 if err == nil { 701 t.Fail() 702 t.Logf("Deploying chaincode should have failed!") 703 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 704 return 705 } 706 707 t.Logf("TestATestAdminACLFailCLFail passed") 708 709 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 710 } 711 712 // TestInvokeSccFail makes sure that invoking a system chaincode fails 713 func TestInvokeSccFail(t *testing.T) { 714 chainID := util.GetTestChainID() 715 716 chaincodeID := &pb.ChaincodeID{Name: "escc"} 717 args := util.ToChaincodeArgs("someFunc", "someArg") 718 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} 719 _, _, _, _, err := invoke(chainID, spec) 720 if err == nil { 721 t.Logf("Invoking escc should have failed!") 722 t.Fail() 723 return 724 } 725 } 726 727 func newTempDir() string { 728 tempDir, err := ioutil.TempDir("", "fabric-") 729 if err != nil { 730 panic(err) 731 } 732 return tempDir 733 } 734 735 func TestMain(m *testing.M) { 736 setupTestConfig() 737 738 chainID := util.GetTestChainID() 739 tev, err := initPeer(chainID) 740 if err != nil { 741 os.Exit(-1) 742 fmt.Printf("Could not initialize tests") 743 finitPeer(tev) 744 return 745 } 746 747 endorserServer = NewEndorserServer() 748 749 // setup the MSP manager so that we can sign/verify 750 err = msptesttools.LoadMSPSetupForTesting() 751 if err != nil { 752 fmt.Printf("Could not initialize msp/signer, err %s", err) 753 finitPeer(tev) 754 os.Exit(-1) 755 return 756 } 757 signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 758 if err != nil { 759 fmt.Printf("Could not initialize msp/signer") 760 finitPeer(tev) 761 os.Exit(-1) 762 return 763 } 764 765 retVal := m.Run() 766 767 finitPeer(tev) 768 769 os.Exit(retVal) 770 } 771 772 func setupTestConfig() { 773 flag.Parse() 774 775 // Now set the configuration file 776 viper.SetEnvPrefix("CORE") 777 viper.AutomaticEnv() 778 replacer := strings.NewReplacer(".", "_") 779 viper.SetEnvKeyReplacer(replacer) 780 viper.SetConfigName("endorser_test") // name of config file (without extension) 781 viper.AddConfigPath("./") // path to look for the config file in 782 err := viper.ReadInConfig() // Find and read the config file 783 if err != nil { // Handle errors reading the config file 784 panic(fmt.Errorf("Fatal error config file: %s \n", err)) 785 } 786 787 testutil.SetupTestLogging() 788 789 // Set the number of maxprocs 790 runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) 791 792 // Init the BCCSP 793 var bccspConfig *factory.FactoryOpts 794 err = viper.UnmarshalKey("peer.BCCSP", &bccspConfig) 795 if err != nil { 796 bccspConfig = nil 797 } 798 799 msp.SetupBCCSPKeystoreConfig(bccspConfig, viper.GetString("peer.mspConfigPath")+"/keystore") 800 801 err = factory.InitFactories(bccspConfig) 802 if err != nil { 803 panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err)) 804 } 805 }