github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/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/inklabsfoundation/inkchain/bccsp" 35 "github.com/inklabsfoundation/inkchain/bccsp/factory" 36 mockpolicies "github.com/inklabsfoundation/inkchain/common/mocks/policies" 37 "github.com/inklabsfoundation/inkchain/common/policies" 38 "github.com/inklabsfoundation/inkchain/common/util" 39 "github.com/inklabsfoundation/inkchain/core/chaincode" 40 "github.com/inklabsfoundation/inkchain/core/common/ccprovider" 41 "github.com/inklabsfoundation/inkchain/core/config" 42 "github.com/inklabsfoundation/inkchain/core/container" 43 "github.com/inklabsfoundation/inkchain/core/peer" 44 syscc "github.com/inklabsfoundation/inkchain/core/scc" 45 "github.com/inklabsfoundation/inkchain/core/testutil" 46 "github.com/inklabsfoundation/inkchain/msp" 47 mspmgmt "github.com/inklabsfoundation/inkchain/msp/mgmt" 48 "github.com/inklabsfoundation/inkchain/msp/mgmt/testtools" 49 "github.com/inklabsfoundation/inkchain/protos/common" 50 pb "github.com/inklabsfoundation/inkchain/protos/peer" 51 pbutils "github.com/inklabsfoundation/inkchain/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, "inkchain", "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/inklabsfoundation/inkchain/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 //TestRedeploy - deploy two times, second time should fail but example02 should remain deployed 372 func TestRedeploy(t *testing.T) { 373 chainID := util.GetTestChainID() 374 375 //invalid arguments 376 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: "ex02", Path: "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example02", Version: "0"}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("init"), []byte("a"), []byte("100"), []byte("b"), []byte("200")}}} 377 378 defer deleteChaincodeOnDisk("ex02.0") 379 380 cccid := ccprovider.NewCCContext(chainID, "ex02", "0", "", false, nil, nil) 381 382 _, _, err := deploy(endorserServer, chainID, spec, nil) 383 if err != nil { 384 t.Fail() 385 t.Logf("error in endorserServer.ProcessProposal %s", err) 386 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 387 return 388 } 389 390 deleteChaincodeOnDisk("ex02.0") 391 392 //second time should not fail as we are just simulating 393 _, _, err = deploy(endorserServer, chainID, spec, nil) 394 if err != nil { 395 t.Fail() 396 t.Logf("error in endorserServer.ProcessProposal %s", err) 397 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 398 return 399 } 400 chaincode.GetChain().Stop(context.Background(), cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 401 } 402 403 // TestDeployAndInvoke deploys and invokes chaincode_example01 404 func TestDeployAndInvoke(t *testing.T) { 405 chainID := util.GetTestChainID() 406 var ctxt = context.Background() 407 408 url := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01" 409 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01", Version: "0"} 410 411 defer deleteChaincodeOnDisk("ex01.0") 412 413 args := []string{"10"} 414 415 f := "init" 416 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 417 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 418 419 cccid := ccprovider.NewCCContext(chainID, "ex01", "0", "", false, nil, nil) 420 421 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 422 chaincodeID1 := spec.ChaincodeId.Name 423 if err != nil { 424 t.Fail() 425 t.Logf("Error deploying <%s>: %s", chaincodeID1, err) 426 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 427 return 428 } 429 var nextBlockNumber uint64 = 1 // first block needs to be block number = 1. Genesis block is block 0 430 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 431 if err != nil { 432 t.Fail() 433 t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err) 434 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 435 return 436 } 437 438 f = "invoke" 439 invokeArgs := append([]string{f}, args...) 440 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 441 prop, resp, txid, nonce, err := invoke(chainID, spec) 442 if err != nil { 443 t.Fail() 444 t.Logf("Error invoking transaction: %s", err) 445 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 446 return 447 } 448 // Commit invoke 449 nextBlockNumber++ 450 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 451 if err != nil { 452 t.Fail() 453 t.Logf("Error committing first invoke <%s>: %s", chaincodeID1, err) 454 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 455 return 456 } 457 458 // Now test for an invalid TxID 459 f = "invoke" 460 invokeArgs = append([]string{f}, args...) 461 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 462 _, err = invokeWithOverride("invalid_tx_id", chainID, spec, nonce) 463 if err == nil { 464 t.Fail() 465 t.Log("Replay attack protection faild. Transaction with invalid txid passed") 466 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 467 return 468 } 469 470 // Now test for duplicated TxID 471 f = "invoke" 472 invokeArgs = append([]string{f}, args...) 473 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 474 _, err = invokeWithOverride(txid, chainID, spec, nonce) 475 if err == nil { 476 t.Fail() 477 t.Log("Replay attack protection faild. Transaction with duplicaged txid passed") 478 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 479 return 480 } 481 482 // Test chaincode endorsement failure when invalid function name supplied 483 f = "invokeinvalid" 484 invokeArgs = append([]string{f}, args...) 485 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 486 prop, resp, txid, nonce, err = invoke(chainID, spec) 487 if err == nil { 488 t.Fail() 489 t.Logf("expecting inkchain to report error from chaincode failure") 490 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 491 return 492 } else if _, ok := err.(*chaincodeError); !ok { 493 t.Fail() 494 t.Logf("expecting chaincode error but found %v", err) 495 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 496 return 497 } 498 499 if resp != nil { 500 assert.Equal(t, int32(500), resp.Response.Status, "Unexpected response status") 501 } 502 503 t.Logf("Invoke test passed") 504 505 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 506 } 507 508 // TestUpgradeAndInvoke deploys chaincode_example01, upgrade it with chaincode_example02, then invoke it 509 func TestDeployAndUpgrade(t *testing.T) { 510 chainID := util.GetTestChainID() 511 var ctxt = context.Background() 512 513 url1 := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01" 514 url2 := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example02" 515 chaincodeID1 := &pb.ChaincodeID{Path: url1, Name: "upgradeex01", Version: "0"} 516 chaincodeID2 := &pb.ChaincodeID{Path: url2, Name: "upgradeex01", Version: "1"} 517 518 defer deleteChaincodeOnDisk("upgradeex01.0") 519 defer deleteChaincodeOnDisk("upgradeex01.1") 520 521 f := "init" 522 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 523 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID1, Input: &pb.ChaincodeInput{Args: argsDeploy}} 524 525 cccid1 := ccprovider.NewCCContext(chainID, "upgradeex01", "0", "", false, nil, nil) 526 cccid2 := ccprovider.NewCCContext(chainID, "upgradeex01", "1", "", false, nil, nil) 527 528 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 529 530 chaincodeName := spec.ChaincodeId.Name 531 if err != nil { 532 t.Fail() 533 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 534 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 535 t.Logf("Error deploying <%s>: %s", chaincodeName, err) 536 return 537 } 538 539 var nextBlockNumber uint64 = 3 // something above created block 0 540 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 541 if err != nil { 542 t.Fail() 543 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 544 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 545 t.Logf("Error committing <%s>: %s", chaincodeName, err) 546 return 547 } 548 549 argsUpgrade := util.ToChaincodeArgs(f, "a", "150", "b", "300") 550 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID2, Input: &pb.ChaincodeInput{Args: argsUpgrade}} 551 _, _, err = upgrade(endorserServer, chainID, spec, nil) 552 if err != nil { 553 t.Fail() 554 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 555 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 556 t.Logf("Error upgrading <%s>: %s", chaincodeName, err) 557 return 558 } 559 560 t.Logf("Upgrade test passed") 561 562 chaincode.GetChain().Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID1}}) 563 chaincode.GetChain().Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID2}}) 564 } 565 566 // TestWritersACLFail deploys a chaincode and then tries to invoke it; 567 // however we inject a special policy for writers to simulate 568 // the scenario in which the creator of this proposal is not among 569 // the writers for the chain 570 func TestWritersACLFail(t *testing.T) { 571 //skip pending FAB-2457 fix 572 t.Skip() 573 chainID := util.GetTestChainID() 574 var ctxt = context.Background() 575 576 url := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01" 577 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail", Version: "0"} 578 579 defer deleteChaincodeOnDisk("ex01-fail.0") 580 581 args := []string{"10"} 582 583 f := "init" 584 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 585 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 586 587 cccid := ccprovider.NewCCContext(chainID, "ex01-fail", "0", "", false, nil, nil) 588 589 resp, prop, err := deploy(endorserServer, chainID, spec, nil) 590 chaincodeID1 := spec.ChaincodeId.Name 591 if err != nil { 592 t.Fail() 593 t.Logf("Error deploying <%s>: %s", chaincodeID1, err) 594 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 595 return 596 } 597 var nextBlockNumber uint64 = 3 // The tests that ran before this test created blocks 0-2 598 err = endorserServer.(*Endorser).commitTxSimulation(prop, chainID, signer, resp, nextBlockNumber) 599 if err != nil { 600 t.Fail() 601 t.Logf("Error committing deploy <%s>: %s", chaincodeID1, err) 602 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 603 return 604 } 605 606 // here we inject a reject policy for writers 607 // to simulate the scenario in which the invoker 608 // is not authorized to issue this proposal 609 rejectpolicy := &mockpolicies.Policy{ 610 Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"), 611 } 612 pm := peer.GetPolicyManager(chainID) 613 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationWriters: rejectpolicy} 614 615 f = "invoke" 616 invokeArgs := append([]string{f}, args...) 617 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 618 prop, resp, _, _, err = invoke(chainID, spec) 619 if err == nil { 620 t.Fail() 621 t.Logf("Invocation should have failed") 622 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 623 return 624 } 625 626 t.Logf("TestWritersACLFail passed") 627 628 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 629 } 630 631 func TestHeaderExtensionNoChaincodeID(t *testing.T) { 632 creator, _ := signer.Serialize() 633 nonce := []byte{1, 2, 3} 634 digest, err := factory.GetDefault().Hash(append(nonce, creator...), &bccsp.SHA256Opts{}) 635 txID := hex.EncodeToString(digest) 636 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: nil, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs()}} 637 invocation := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 638 prop, _, _ := pbutils.CreateChaincodeProposalWithTxIDNonceAndTransient(txID, common.HeaderType_ENDORSER_TRANSACTION, util.GetTestChainID(), invocation, []byte{1, 2, 3}, creator, nil) 639 signedProp, _ := getSignedProposal(prop, signer) 640 _, err = endorserServer.ProcessProposal(context.Background(), signedProp) 641 assert.Error(t, err) 642 assert.Contains(t, err.Error(), "ChaincodeHeaderExtension.ChaincodeId is nil") 643 } 644 645 // TestAdminACLFail deploys tried to deploy a chaincode; 646 // however we inject a special policy for admins to simulate 647 // the scenario in which the creator of this proposal is not among 648 // the admins for the chain 649 func TestAdminACLFail(t *testing.T) { 650 //skip pending FAB-2457 fix 651 t.Skip() 652 chainID := util.GetTestChainID() 653 654 // here we inject a reject policy for admins 655 // to simulate the scenario in which the invoker 656 // is not authorized to issue this proposal 657 rejectpolicy := &mockpolicies.Policy{ 658 Err: errors.New("The creator of this proposal does not fulfil the writers policy of this chain"), 659 } 660 pm := peer.GetPolicyManager(chainID) 661 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{policies.ChannelApplicationAdmins: rejectpolicy} 662 663 var ctxt = context.Background() 664 665 url := "github.com/inklabsfoundation/inkchain/examples/chaincode/go/chaincode_example01" 666 chaincodeID := &pb.ChaincodeID{Path: url, Name: "ex01-fail1", Version: "0"} 667 668 defer deleteChaincodeOnDisk("ex01-fail1.0") 669 670 f := "init" 671 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 672 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 673 674 cccid := ccprovider.NewCCContext(chainID, "ex01-fail1", "0", "", false, nil, nil) 675 676 _, _, err := deploy(endorserServer, chainID, spec, nil) 677 if err == nil { 678 t.Fail() 679 t.Logf("Deploying chaincode should have failed!") 680 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 681 return 682 } 683 684 t.Logf("TestATestAdminACLFailCLFail passed") 685 686 chaincode.GetChain().Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: chaincodeID}}) 687 } 688 689 // TestInvokeSccFail makes sure that invoking a system chaincode fails 690 func TestInvokeSccFail(t *testing.T) { 691 chainID := util.GetTestChainID() 692 693 chaincodeID := &pb.ChaincodeID{Name: "escc"} 694 args := util.ToChaincodeArgs("someFunc", "someArg") 695 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: chaincodeID, Input: &pb.ChaincodeInput{Args: args}} 696 _, _, _, _, err := invoke(chainID, spec) 697 if err == nil { 698 t.Logf("Invoking escc should have failed!") 699 t.Fail() 700 return 701 } 702 } 703 704 func newTempDir() string { 705 tempDir, err := ioutil.TempDir("", "inkchain-") 706 if err != nil { 707 panic(err) 708 } 709 return tempDir 710 } 711 712 func TestMain(m *testing.M) { 713 setupTestConfig() 714 715 chainID := util.GetTestChainID() 716 tev, err := initPeer(chainID) 717 if err != nil { 718 os.Exit(-1) 719 fmt.Printf("Could not initialize tests") 720 finitPeer(tev) 721 return 722 } 723 724 endorserServer = NewEndorserServer() 725 726 // setup the MSP manager so that we can sign/verify 727 err = msptesttools.LoadMSPSetupForTesting() 728 if err != nil { 729 fmt.Printf("Could not initialize msp/signer, err %s", err) 730 finitPeer(tev) 731 os.Exit(-1) 732 return 733 } 734 signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 735 if err != nil { 736 fmt.Printf("Could not initialize msp/signer") 737 finitPeer(tev) 738 os.Exit(-1) 739 return 740 } 741 742 retVal := m.Run() 743 744 finitPeer(tev) 745 746 os.Exit(retVal) 747 } 748 749 func setupTestConfig() { 750 flag.Parse() 751 752 // Now set the configuration file 753 viper.SetEnvPrefix("CORE") 754 viper.AutomaticEnv() 755 replacer := strings.NewReplacer(".", "_") 756 viper.SetEnvKeyReplacer(replacer) 757 viper.SetConfigName("endorser_test") // name of config file (without extension) 758 viper.AddConfigPath("./") // path to look for the config file in 759 err := viper.ReadInConfig() // Find and read the config file 760 if err != nil { // Handle errors reading the config file 761 panic(fmt.Errorf("Fatal error config file: %s \n", err)) 762 } 763 764 testutil.SetupTestLogging() 765 766 // Set the number of maxprocs 767 runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) 768 769 // Init the BCCSP 770 var bccspConfig *factory.FactoryOpts 771 err = viper.UnmarshalKey("peer.BCCSP", &bccspConfig) 772 if err != nil { 773 bccspConfig = nil 774 } 775 776 msp.SetupBCCSPKeystoreConfig(bccspConfig, viper.GetString("peer.mspConfigPath")+"/keystore") 777 778 err = factory.InitFactories(bccspConfig) 779 if err != nil { 780 panic(fmt.Errorf("Could not initialize BCCSP Factories [%s]", err)) 781 } 782 }