github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/chaincode/exectransaction_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 chaincode 18 19 import ( 20 "fmt" 21 "math/rand" 22 "net" 23 "os" 24 "path/filepath" 25 "runtime" 26 "strconv" 27 "sync" 28 "testing" 29 "time" 30 31 "encoding/json" 32 "strings" 33 34 "github.com/golang/protobuf/proto" 35 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/common/ccprovider" 40 "github.com/hyperledger/fabric/core/config" 41 "github.com/hyperledger/fabric/core/container" 42 "github.com/hyperledger/fabric/core/container/ccintf" 43 "github.com/hyperledger/fabric/core/ledger" 44 "github.com/hyperledger/fabric/core/ledger/util/couchdb" 45 "github.com/hyperledger/fabric/core/peer" 46 "github.com/hyperledger/fabric/core/policy" 47 "github.com/hyperledger/fabric/core/scc" 48 pb "github.com/hyperledger/fabric/protos/peer" 49 putils "github.com/hyperledger/fabric/protos/utils" 50 51 "bytes" 52 53 "github.com/hyperledger/fabric/core/ledger/ledgerconfig" 54 "github.com/hyperledger/fabric/core/ledger/ledgermgmt" 55 "github.com/hyperledger/fabric/msp" 56 mspmgmt "github.com/hyperledger/fabric/msp/mgmt" 57 "github.com/hyperledger/fabric/msp/mgmt/testtools" 58 "github.com/hyperledger/fabric/protos/common" 59 "github.com/spf13/viper" 60 "golang.org/x/net/context" 61 "google.golang.org/grpc" 62 "google.golang.org/grpc/credentials" 63 ) 64 65 //initialize peer and start up. If security==enabled, login as vp 66 func initPeer(chainIDs ...string) (net.Listener, error) { 67 //start clean 68 finitPeer(nil, chainIDs...) 69 70 peer.MockInitialize() 71 72 var opts []grpc.ServerOption 73 if viper.GetBool("peer.tls.enabled") { 74 creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file")) 75 if err != nil { 76 return nil, fmt.Errorf("Failed to generate credentials %v", err) 77 } 78 opts = []grpc.ServerOption{grpc.Creds(creds)} 79 } 80 grpcServer := grpc.NewServer(opts...) 81 82 peerAddress, err := peer.GetLocalAddress() 83 if err != nil { 84 return nil, fmt.Errorf("Error obtaining peer address: %s", err) 85 } 86 lis, err := net.Listen("tcp", peerAddress) 87 if err != nil { 88 return nil, fmt.Errorf("Error starting peer listener %s", err) 89 } 90 91 getPeerEndpoint := func() (*pb.PeerEndpoint, error) { 92 return &pb.PeerEndpoint{Id: &pb.PeerID{Name: "testpeer"}, Address: peerAddress}, nil 93 } 94 95 ccStartupTimeout := time.Duration(chaincodeStartupTimeoutDefault) * time.Millisecond 96 pb.RegisterChaincodeSupportServer(grpcServer, NewChaincodeSupport(getPeerEndpoint, false, ccStartupTimeout)) 97 98 // Mock policy checker 99 policy.RegisterPolicyCheckerFactory(&mockPolicyCheckerFactory{}) 100 101 scc.RegisterSysCCs() 102 103 for _, id := range chainIDs { 104 scc.DeDeploySysCCs(id) 105 if err = peer.MockCreateChain(id); err != nil { 106 closeListenerAndSleep(lis) 107 return nil, err 108 } 109 scc.DeploySysCCs(id) 110 } 111 112 go grpcServer.Serve(lis) 113 114 return lis, nil 115 } 116 117 func finitPeer(lis net.Listener, chainIDs ...string) { 118 if lis != nil { 119 for _, c := range chainIDs { 120 scc.DeDeploySysCCs(c) 121 if lgr := peer.GetLedger(c); lgr != nil { 122 lgr.Close() 123 } 124 } 125 closeListenerAndSleep(lis) 126 } 127 ledgermgmt.CleanupTestEnv() 128 ledgerPath := config.GetPath("peer.fileSystemPath") 129 os.RemoveAll(ledgerPath) 130 os.RemoveAll(filepath.Join(os.TempDir(), "hyperledger")) 131 132 //if couchdb is enabled, then cleanup the test couchdb 133 if ledgerconfig.IsCouchDBEnabled() == true { 134 135 chainID := util.GetTestChainID() 136 137 connectURL := viper.GetString("ledger.state.couchDBConfig.couchDBAddress") 138 username := viper.GetString("ledger.state.couchDBConfig.username") 139 password := viper.GetString("ledger.state.couchDBConfig.password") 140 maxRetries := viper.GetInt("ledger.state.couchDBConfig.maxRetries") 141 maxRetriesOnStartup := viper.GetInt("ledger.state.couchDBConfig.maxRetriesOnStartup") 142 requestTimeout := viper.GetDuration("ledger.state.couchDBConfig.requestTimeout") 143 144 couchInstance, _ := couchdb.CreateCouchInstance(connectURL, username, password, maxRetries, maxRetriesOnStartup, requestTimeout) 145 db := couchdb.CouchDatabase{CouchInstance: *couchInstance, DBName: chainID} 146 //drop the test database 147 db.DropDatabase() 148 149 } 150 } 151 152 func startTxSimulation(ctxt context.Context, chainID string) (context.Context, ledger.TxSimulator, error) { 153 lgr := peer.GetLedger(chainID) 154 txsim, err := lgr.NewTxSimulator() 155 if err != nil { 156 return nil, nil, err 157 } 158 historyQueryExecutor, err := lgr.NewHistoryQueryExecutor() 159 if err != nil { 160 return nil, nil, err 161 } 162 163 ctxt = context.WithValue(ctxt, TXSimulatorKey, txsim) 164 ctxt = context.WithValue(ctxt, HistoryQueryExecutorKey, historyQueryExecutor) 165 return ctxt, txsim, nil 166 } 167 168 func endTxSimulationCDS(chainID string, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cds *pb.ChaincodeDeploymentSpec, blockNumber uint64) error { 169 // get serialized version of the signer 170 ss, err := signer.Serialize() 171 if err != nil { 172 return err 173 } 174 175 // get lscc ChaincodeID 176 lsccid := &pb.ChaincodeID{ 177 Name: "lscc", 178 Version: util.GetSysCCVersion(), 179 } 180 181 // get a proposal - we need it to get a transaction 182 prop, _, err := putils.CreateDeployProposalFromCDS(chainID, cds, ss, nil, nil, nil) 183 if err != nil { 184 return err 185 } 186 187 return endTxSimulation(chainID, lsccid, txsim, payload, commit, prop, blockNumber) 188 } 189 190 func endTxSimulationCIS(chainID string, ccid *pb.ChaincodeID, _ string, txsim ledger.TxSimulator, payload []byte, commit bool, cis *pb.ChaincodeInvocationSpec, blockNumber uint64) error { 191 // get serialized version of the signer 192 ss, err := signer.Serialize() 193 if err != nil { 194 return err 195 } 196 197 // get a proposal - we need it to get a transaction 198 prop, _, err := putils.CreateProposalFromCIS(common.HeaderType_ENDORSER_TRANSACTION, chainID, cis, ss) 199 if err != nil { 200 return err 201 } 202 203 return endTxSimulation(chainID, ccid, txsim, payload, commit, prop, blockNumber) 204 } 205 206 //getting a crash from ledger.Commit when doing concurrent invokes 207 //It is likely intentional that ledger.Commit is serial (ie, the real 208 //Committer will invoke this serially on each block). Mimic that here 209 //by forcing serialization of the ledger.Commit call. 210 // 211 //NOTE-this should NOT have any effect on the older serial tests. 212 //This affects only the tests in concurrent_test.go which call these 213 //concurrently (100 concurrent invokes followed by 100 concurrent queries) 214 var _commitLock_ sync.Mutex 215 216 func endTxSimulation(chainID string, ccid *pb.ChaincodeID, txsim ledger.TxSimulator, _ []byte, commit bool, prop *pb.Proposal, blockNumber uint64) error { 217 txsim.Done() 218 if lgr := peer.GetLedger(chainID); lgr != nil { 219 if commit { 220 var txSimulationResults []byte 221 var err error 222 223 //get simulation results 224 if txSimulationResults, err = txsim.GetTxSimulationResults(); err != nil { 225 return err 226 } 227 228 // assemble a (signed) proposal response message 229 resp, err := putils.CreateProposalResponse(prop.Header, prop.Payload, &pb.Response{Status: 200}, txSimulationResults, nil, ccid, nil, signer) 230 if err != nil { 231 return err 232 } 233 234 // get the envelope 235 env, err := putils.CreateSignedTx(prop, signer, resp) 236 if err != nil { 237 return err 238 } 239 240 envBytes, err := putils.GetBytesEnvelope(env) 241 if err != nil { 242 return err 243 } 244 245 //create the block with 1 transaction 246 block := common.NewBlock(blockNumber, []byte{}) 247 block.Data.Data = [][]byte{envBytes} 248 //commit the block 249 250 //see comment on _commitLock_ 251 _commitLock_.Lock() 252 defer _commitLock_.Unlock() 253 if err := lgr.Commit(block); err != nil { 254 return err 255 } 256 } 257 } 258 259 return nil 260 } 261 262 // Build a chaincode. 263 func getDeploymentSpec(_ context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { 264 fmt.Printf("getting deployment spec for chaincode spec: %v\n", spec) 265 codePackageBytes, err := container.GetChaincodePackageBytes(spec) 266 if err != nil { 267 return nil, err 268 } 269 cdDeploymentSpec := &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec, CodePackage: codePackageBytes} 270 return cdDeploymentSpec, nil 271 } 272 273 //getDeployLSCCSpec gets the spec for the chaincode deployment to be sent to LSCC 274 func getDeployLSCCSpec(chainID string, cds *pb.ChaincodeDeploymentSpec) (*pb.ChaincodeInvocationSpec, error) { 275 b, err := proto.Marshal(cds) 276 if err != nil { 277 return nil, err 278 } 279 280 sysCCVers := util.GetSysCCVersion() 281 282 //wrap the deployment in an invocation spec to lscc... 283 lsccSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: &pb.ChaincodeSpec{Type: pb.ChaincodeSpec_GOLANG, ChaincodeId: &pb.ChaincodeID{Name: "lscc", Version: sysCCVers}, Input: &pb.ChaincodeInput{Args: [][]byte{[]byte("deploy"), []byte(chainID), b}}}} 284 285 return lsccSpec, nil 286 } 287 288 // Deploy a chaincode - i.e., build and initialize. 289 func deploy(ctx context.Context, cccid *ccprovider.CCContext, spec *pb.ChaincodeSpec, blockNumber uint64) (b []byte, err error) { 290 // First build and get the deployment spec 291 cdDeploymentSpec, err := getDeploymentSpec(ctx, spec) 292 if err != nil { 293 return nil, err 294 } 295 296 return deploy2(ctx, cccid, cdDeploymentSpec, blockNumber) 297 } 298 299 func deploy2(ctx context.Context, cccid *ccprovider.CCContext, chaincodeDeploymentSpec *pb.ChaincodeDeploymentSpec, blockNumber uint64) (b []byte, err error) { 300 cis, err := getDeployLSCCSpec(cccid.ChainID, chaincodeDeploymentSpec) 301 if err != nil { 302 return nil, fmt.Errorf("Error creating lscc spec : %s\n", err) 303 } 304 305 ctx, txsim, err := startTxSimulation(ctx, cccid.ChainID) 306 if err != nil { 307 return nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) 308 } 309 310 uuid := util.GenerateUUID() 311 312 cccid.TxID = uuid 313 314 defer func() { 315 //no error, lets try commit 316 if err == nil { 317 //capture returned error from commit 318 err = endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), true, chaincodeDeploymentSpec, blockNumber) 319 } else { 320 //there was an error, just close simulation and return that 321 endTxSimulationCDS(cccid.ChainID, uuid, txsim, []byte("deployed"), false, chaincodeDeploymentSpec, blockNumber) 322 } 323 }() 324 325 //ignore existence errors 326 ccprovider.PutChaincodeIntoFS(chaincodeDeploymentSpec) 327 328 sysCCVers := util.GetSysCCVersion() 329 sprop, prop := putils.MockSignedEndorserProposalOrPanic(cccid.ChainID, cis.ChaincodeSpec, []byte("Admin"), []byte("msg1")) 330 lsccid := ccprovider.NewCCContext(cccid.ChainID, cis.ChaincodeSpec.ChaincodeId.Name, sysCCVers, uuid, true, sprop, prop) 331 332 //write to lscc 333 if _, _, err = ExecuteWithErrorFilter(ctx, lsccid, cis); err != nil { 334 return nil, fmt.Errorf("Error deploying chaincode (1): %s", err) 335 } 336 337 if b, _, err = ExecuteWithErrorFilter(ctx, cccid, chaincodeDeploymentSpec); err != nil { 338 return nil, fmt.Errorf("Error deploying chaincode(2): %s", err) 339 } 340 341 return b, nil 342 } 343 344 // Invoke a chaincode. 345 func invoke(ctx context.Context, chainID string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { 346 return invokeWithVersion(ctx, chainID, spec.GetChaincodeId().Version, spec, blockNumber, creator) 347 } 348 349 // Invoke a chaincode with version (needed for upgrade) 350 func invokeWithVersion(ctx context.Context, chainID string, version string, spec *pb.ChaincodeSpec, blockNumber uint64, creator []byte) (ccevt *pb.ChaincodeEvent, uuid string, retval []byte, err error) { 351 cdInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} 352 353 // Now create the Transactions message and send to Peer. 354 uuid = util.GenerateUUID() 355 356 var txsim ledger.TxSimulator 357 ctx, txsim, err = startTxSimulation(ctx, chainID) 358 if err != nil { 359 return nil, uuid, nil, fmt.Errorf("Failed to get handle to simulator: %s ", err) 360 } 361 362 defer func() { 363 //no error, lets try commit 364 if err == nil { 365 //capture returned error from commit 366 err = endTxSimulationCIS(chainID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), true, cdInvocationSpec, blockNumber) 367 } else { 368 //there was an error, just close simulation and return that 369 endTxSimulationCIS(chainID, spec.ChaincodeId, uuid, txsim, []byte("invoke"), false, cdInvocationSpec, blockNumber) 370 } 371 }() 372 373 if len(creator) == 0 { 374 creator = []byte("Admin") 375 } 376 sprop, prop := putils.MockSignedEndorserProposalOrPanic(chainID, spec, creator, []byte("msg1")) 377 cccid := ccprovider.NewCCContext(chainID, cdInvocationSpec.ChaincodeSpec.ChaincodeId.Name, version, uuid, false, sprop, prop) 378 retval, ccevt, err = ExecuteWithErrorFilter(ctx, cccid, cdInvocationSpec) 379 if err != nil { 380 return nil, uuid, nil, fmt.Errorf("Error invoking chaincode: %s", err) 381 } 382 383 return ccevt, uuid, retval, err 384 } 385 386 func closeListenerAndSleep(l net.Listener) { 387 if l != nil { 388 l.Close() 389 time.Sleep(2 * time.Second) 390 } 391 } 392 393 func executeDeployTransaction(t *testing.T, chainID string, name string, url string) { 394 lis, err := initPeer(chainID) 395 if err != nil { 396 t.Fail() 397 t.Logf("Error creating peer: %s", err) 398 } 399 400 defer finitPeer(lis, chainID) 401 402 var ctxt = context.Background() 403 404 f := "init" 405 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 406 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: &pb.ChaincodeID{Name: name, Path: url, Version: "0"}, Input: &pb.ChaincodeInput{Args: args}} 407 408 cccid := ccprovider.NewCCContext(chainID, name, "0", "", false, nil, nil) 409 410 _, err = deploy(ctxt, cccid, spec, 0) 411 412 cID := spec.ChaincodeId.Name 413 if err != nil { 414 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 415 t.Fail() 416 t.Logf("Error deploying <%s>: %s", cID, err) 417 return 418 } 419 420 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 421 } 422 423 // chaincodeQueryChaincode function 424 func _(chainID string, _ string) error { 425 var ctxt = context.Background() 426 427 // Deploy first chaincode 428 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 429 430 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 431 f := "init" 432 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 433 434 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 435 436 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 437 438 var nextBlockNumber uint64 439 440 _, err := deploy(ctxt, cccid1, spec1, nextBlockNumber) 441 nextBlockNumber++ 442 443 ccID1 := spec1.ChaincodeId.Name 444 if err != nil { 445 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 446 return fmt.Errorf("Error initializing chaincode %s(%s)", ccID1, err) 447 } 448 449 time.Sleep(time.Second) 450 451 // Deploy second chaincode 452 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05" 453 454 cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"} 455 f = "init" 456 args = util.ToChaincodeArgs(f, "sum", "0") 457 458 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 459 460 cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, nil, nil) 461 462 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 463 nextBlockNumber++ 464 ccID2 := spec2.ChaincodeId.Name 465 if err != nil { 466 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 467 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 468 return fmt.Errorf("Error initializing chaincode %s(%s)", ccID2, err) 469 } 470 471 time.Sleep(time.Second) 472 473 // Invoke second chaincode, which will inturn query the first chaincode 474 f = "invoke" 475 args = util.ToChaincodeArgs(f, ccID1, "sum") 476 477 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 478 // Invoke chaincode 479 var retVal []byte 480 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice")) 481 nextBlockNumber++ 482 483 if err != nil { 484 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 485 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 486 return fmt.Errorf("Error invoking <%s>: %s", ccID2, err) 487 } 488 489 // Check the return value 490 result, err := strconv.Atoi(string(retVal)) 491 if err != nil || result != 300 { 492 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 493 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 494 return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID1, err) 495 } 496 497 // Query second chaincode, which will inturn query the first chaincode 498 f = "query" 499 args = util.ToChaincodeArgs(f, ccID1, "sum") 500 501 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 502 // Invoke chaincode 503 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice")) 504 505 if err != nil { 506 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 507 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 508 return fmt.Errorf("Error querying <%s>: %s", ccID2, err) 509 } 510 511 // Check the return value 512 result, err = strconv.Atoi(string(retVal)) 513 if err != nil || result != 300 { 514 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 515 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 516 return fmt.Errorf("Incorrect final value after query for <%s>: %s", ccID1, err) 517 } 518 519 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 520 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 521 522 return nil 523 } 524 525 // Disable this temporarily. 526 // TODO: Need to enable this after update chaincode interface of chaincode repo. 527 // Test deploy of a transaction with a chaincode over HTTP. 528 //func TestHTTPExecuteDeployTransaction(t *testing.T) { 529 // chainID := util.GetTestChainID() 530 531 // // The chaincode used here cannot be from the fabric repo 532 // // itself or it won't be downloaded because it will be found 533 // // in GOPATH, which would defeat the test 534 // executeDeployTransaction(t, chainID, "example01", "http://gopkg.in/mastersingh24/fabric-test-resources.v1") 535 //} 536 537 // Check the correctness of the final state after transaction execution. 538 func checkFinalState(cccid *ccprovider.CCContext) error { 539 _, txsim, err := startTxSimulation(context.Background(), cccid.ChainID) 540 if err != nil { 541 return fmt.Errorf("Failed to get handle to simulator: %s ", err) 542 } 543 544 defer txsim.Done() 545 546 cName := cccid.GetCanonicalName() 547 548 // Invoke ledger to get state 549 var Aval, Bval int 550 resbytes, resErr := txsim.GetState(cccid.Name, "a") 551 if resErr != nil { 552 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 553 } 554 fmt.Printf("Got string: %s\n", string(resbytes)) 555 Aval, resErr = strconv.Atoi(string(resbytes)) 556 if resErr != nil { 557 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 558 } 559 if Aval != 90 { 560 return fmt.Errorf("Incorrect result. Aval %d != 90 <%s>", Aval, cName) 561 } 562 563 resbytes, resErr = txsim.GetState(cccid.Name, "b") 564 if resErr != nil { 565 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 566 } 567 Bval, resErr = strconv.Atoi(string(resbytes)) 568 if resErr != nil { 569 return fmt.Errorf("Error retrieving state from ledger for <%s>: %s", cName, resErr) 570 } 571 if Bval != 210 { 572 return fmt.Errorf("Incorrect result. Bval %d != 210 <%s>", Bval, cName) 573 } 574 575 // Success 576 fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval) 577 return nil 578 } 579 580 // Invoke chaincode_example02 581 func invokeExample02Transaction(ctxt context.Context, cccid *ccprovider.CCContext, cID *pb.ChaincodeID, chaincodeType pb.ChaincodeSpec_Type, args []string, destroyImage bool) error { 582 // the ledger is created with genesis block. Start block number 1 onwards 583 var nextBlockNumber uint64 = 1 584 f := "init" 585 argsDeploy := util.ToChaincodeArgs(f, "a", "100", "b", "200") 586 spec := &pb.ChaincodeSpec{Type: chaincodeType, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: argsDeploy}} 587 _, err := deploy(ctxt, cccid, spec, nextBlockNumber) 588 nextBlockNumber++ 589 ccID := spec.ChaincodeId.Name 590 if err != nil { 591 return fmt.Errorf("Error deploying <%s>: %s", ccID, err) 592 } 593 594 time.Sleep(time.Second) 595 596 if destroyImage { 597 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 598 dir := container.DestroyImageReq{CCID: ccintf.CCID{ChaincodeSpec: spec, NetworkID: theChaincodeSupport.peerNetworkID, PeerID: theChaincodeSupport.peerID, ChainID: cccid.ChainID}, Force: true, NoPrune: true} 599 600 _, err = container.VMCProcess(ctxt, container.DOCKER, dir) 601 if err != nil { 602 err = fmt.Errorf("Error destroying image: %s", err) 603 return err 604 } 605 } 606 607 f = "invoke" 608 invokeArgs := append([]string{f}, args...) 609 spec = &pb.ChaincodeSpec{ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(invokeArgs...)}} 610 _, uuid, _, err := invoke(ctxt, cccid.ChainID, spec, nextBlockNumber, nil) 611 nextBlockNumber++ 612 if err != nil { 613 return fmt.Errorf("Error invoking <%s>: %s", cccid.Name, err) 614 } 615 616 cccid.TxID = uuid 617 err = checkFinalState(cccid) 618 if err != nil { 619 return fmt.Errorf("Incorrect final state after transaction for <%s>: %s", ccID, err) 620 } 621 622 // Test for delete state 623 f = "delete" 624 delArgs := util.ToChaincodeArgs(f, "a") 625 spec = &pb.ChaincodeSpec{ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: delArgs}} 626 _, _, _, err = invoke(ctxt, cccid.ChainID, spec, nextBlockNumber, nil) 627 if err != nil { 628 return fmt.Errorf("Error deleting state in <%s>: %s", cccid.Name, err) 629 } 630 631 return nil 632 } 633 634 const ( 635 chaincodeExample02GolangPath = "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 636 chaincodeEventSenderGolangPath = "github.com/hyperledger/fabric/examples/chaincode/go/eventsender" 637 chaincodeExample02JavaPath = "../../examples/chaincode/java/chaincode_example02" 638 chaincodeExample06JavaPath = "../../examples/chaincode/java/chaincode_example06" 639 chaincodeEventSenderJavaPath = "../../examples/chaincode/java/eventsender" 640 ) 641 642 func runChaincodeInvokeChaincode(t *testing.T, chainID1 string, chainID2 string, _ string) (err error) { 643 var ctxt = context.Background() 644 645 // Deploy first chaincode 646 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 647 648 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 649 f := "init" 650 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 651 652 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 653 654 sProp, prop := putils.MockSignedEndorserProposalOrPanic(chainID1, spec1, []byte([]byte("Alice")), nil) 655 cccid1 := ccprovider.NewCCContext(chainID1, "example02", "0", "", false, sProp, prop) 656 657 var nextBlockNumber uint64 = 1 658 659 _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber) 660 nextBlockNumber++ 661 ccID1 := spec1.ChaincodeId.Name 662 if err != nil { 663 t.Fail() 664 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 665 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 666 return 667 } 668 669 t.Logf("deployed chaincode_example02 got cID1:% s,\n ccID1:% s", cID1, ccID1) 670 671 time.Sleep(time.Second) 672 673 // Deploy second chaincode 674 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04" 675 676 cID2 := &pb.ChaincodeID{Name: "example04", Path: url2, Version: "0"} 677 f = "init" 678 args = util.ToChaincodeArgs(f, "e", "0") 679 680 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 681 682 sProp, prop = putils.MockSignedEndorserProposalOrPanic(chainID1, spec2, []byte([]byte("Alice")), nil) 683 cccid2 := ccprovider.NewCCContext(chainID1, "example04", "0", "", false, sProp, prop) 684 685 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 686 nextBlockNumber++ 687 ccID2 := spec2.ChaincodeId.Name 688 if err != nil { 689 t.Fail() 690 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 691 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 692 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 693 return 694 } 695 696 time.Sleep(time.Second) 697 698 // Invoke second chaincode passing the first chaincode's name as first param, 699 // which will inturn invoke the first chaincode 700 f = "invoke" 701 cid := spec1.ChaincodeId.Name 702 args = util.ToChaincodeArgs(f, cid, "e", "1") 703 704 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 705 // Invoke chaincode 706 var uuid string 707 _, uuid, _, err = invoke(ctxt, chainID1, spec2, nextBlockNumber, []byte("Alice")) 708 709 if err != nil { 710 t.Fail() 711 t.Logf("Error invoking <%s>: %s", ccID2, err) 712 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 713 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 714 return 715 } 716 717 cccid1.TxID = uuid 718 719 // Check the state in the ledger 720 err = checkFinalState(cccid1) 721 if err != nil { 722 t.Fail() 723 t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err) 724 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 725 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 726 return 727 } 728 729 // Change the policies of the two channels in such a way: 730 // 1. Alice has reader access to both the channels. 731 // 2. Bob has access only to chainID2. 732 // Therefore the chaincode invocation should fail. 733 pm := peer.GetPolicyManager(chainID1) 734 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{ 735 policies.ChannelApplicationWriters: &CreatorPolicy{Creators: [][]byte{[]byte("Alice")}}, 736 } 737 738 pm = peer.GetPolicyManager(chainID2) 739 pm.(*mockpolicies.Manager).PolicyMap = map[string]policies.Policy{ 740 policies.ChannelApplicationWriters: &CreatorPolicy{Creators: [][]byte{[]byte("Alice"), []byte("Bob")}}, 741 } 742 743 url2 = "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example04" 744 745 cID2 = &pb.ChaincodeID{Name: "example04", Path: url2, Version: "0"} 746 f = "init" 747 args = util.ToChaincodeArgs(f, "e", "0") 748 749 spec3 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 750 sProp, prop = putils.MockSignedEndorserProposalOrPanic(chainID2, spec3, []byte([]byte("Alice")), nil) 751 cccid3 := ccprovider.NewCCContext(chainID2, "example04", "0", "", false, sProp, prop) 752 753 _, err = deploy(ctxt, cccid3, spec3, 1) 754 chaincodeID2 := spec2.ChaincodeId.Name 755 if err != nil { 756 t.Fail() 757 t.Logf("Error initializing chaincode %s(%s)", chaincodeID2, err) 758 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 759 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 760 theChaincodeSupport.Stop(ctxt, cccid3, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec3}) 761 return 762 } 763 764 time.Sleep(time.Second) 765 // 766 // - Invoke second chaincode passing the first chaincode's name as first param, which will in turn invoke the first chaincode 767 f = "invoke" 768 cid = spec1.ChaincodeId.Name 769 args = util.ToChaincodeArgs(f, cid, "e", "1", chainID1) 770 771 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 772 // Invoke chaincode 773 //var uuid string 774 775 // Bob should not be able to call 776 _, _, _, err = invoke(ctxt, chainID2, spec2, 2, []byte("Bob")) 777 if err == nil { 778 t.Fail() 779 t.Logf("Bob invoking <%s> should fail. It did not happen instead: %s", chaincodeID2, err) 780 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 781 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 782 theChaincodeSupport.Stop(ctxt, cccid3, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec3}) 783 return 784 } 785 786 // Alice should be able to call 787 _, _, _, err = invoke(ctxt, chainID2, spec2, 2, []byte("Alice")) 788 if err != nil { 789 t.Fail() 790 t.Logf("Alice invoking <%s> should not fail. It did happen instead: %s", chaincodeID2, err) 791 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 792 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 793 theChaincodeSupport.Stop(ctxt, cccid3, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec3}) 794 return 795 } 796 797 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 798 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 799 theChaincodeSupport.Stop(ctxt, cccid3, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec3}) 800 801 return nil 802 } 803 804 // Test deploy of a transaction 805 func TestExecuteDeployTransaction(t *testing.T) { 806 //chaincoe is deployed as part of many tests. No need for a separate one for this 807 t.Skip() 808 chainID := util.GetTestChainID() 809 810 executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") 811 } 812 813 // Test deploy of a transaction with a GOPATH with multiple elements 814 func TestGopathExecuteDeployTransaction(t *testing.T) { 815 //this is no longer critical as chaincode is assembled in the client side (SDK) 816 t.Skip() 817 chainID := util.GetTestChainID() 818 819 // add a trailing slash to GOPATH 820 // and a couple of elements - it doesn't matter what they are 821 os.Setenv("GOPATH", os.Getenv("GOPATH")+string(os.PathSeparator)+string(os.PathListSeparator)+"/tmp/foo"+string(os.PathListSeparator)+"/tmp/bar") 822 executeDeployTransaction(t, chainID, "example01", "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example01") 823 } 824 825 func TestExecuteInvokeTransaction(t *testing.T) { 826 827 testCases := []struct { 828 chaincodeType pb.ChaincodeSpec_Type 829 chaincodePath string 830 }{ 831 {pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath}, 832 {pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath}, 833 } 834 835 for _, tc := range testCases { 836 t.Run(tc.chaincodeType.String(), func(t *testing.T) { 837 838 if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" { 839 t.Skip("No Java chaincode support yet on non-x86_64.") 840 } 841 842 chainID := util.GetTestChainID() 843 844 lis, err := initPeer(chainID) 845 if err != nil { 846 t.Fail() 847 t.Logf("Error creating peer: %s", err) 848 } 849 850 defer finitPeer(lis, chainID) 851 852 var ctxt = context.Background() 853 chaincodeName := generateChaincodeName(tc.chaincodeType) 854 chaincodeVersion := "1.0.0.0" 855 cccid := ccprovider.NewCCContext(chainID, chaincodeName, chaincodeVersion, "", false, nil, nil) 856 ccID := &pb.ChaincodeID{Name: chaincodeName, Path: tc.chaincodePath, Version: chaincodeVersion} 857 858 args := []string{"a", "b", "10"} 859 err = invokeExample02Transaction(ctxt, cccid, ccID, tc.chaincodeType, args, true) 860 if err != nil { 861 t.Fail() 862 t.Logf("Error invoking transaction: %s", err) 863 } else { 864 fmt.Print("Invoke test passed\n") 865 t.Log("Invoke test passed") 866 } 867 868 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}}) 869 870 }) 871 } 872 873 } 874 875 // Test the execution of an invalid transaction. 876 func TestExecuteInvokeInvalidTransaction(t *testing.T) { 877 chainID := util.GetTestChainID() 878 879 lis, err := initPeer(chainID) 880 if err != nil { 881 t.Fail() 882 t.Logf("Error creating peer: %s", err) 883 } 884 885 defer finitPeer(lis, chainID) 886 887 var ctxt = context.Background() 888 889 url := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 890 ccID := &pb.ChaincodeID{Name: "example02", Path: url, Version: "0"} 891 892 cccid := ccprovider.NewCCContext(chainID, "example02", "0", "", false, nil, nil) 893 894 //FAIL, FAIL! 895 args := []string{"x", "-1"} 896 err = invokeExample02Transaction(ctxt, cccid, ccID, pb.ChaincodeSpec_GOLANG, args, false) 897 898 //this HAS to fail with expectedDeltaStringPrefix 899 if err != nil { 900 errStr := err.Error() 901 t.Logf("Got error %s\n", errStr) 902 t.Log("InvalidInvoke test passed") 903 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}}) 904 905 return 906 } 907 908 t.Fail() 909 t.Logf("Error invoking transaction %s", err) 910 911 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: &pb.ChaincodeSpec{ChaincodeId: ccID}}) 912 } 913 914 // Test the execution of a chaincode that invokes another chaincode. 915 func TestChaincodeInvokeChaincode(t *testing.T) { 916 chainID1 := util.GetTestChainID() 917 chainID2 := chainID1 + "2" 918 919 lis, err := initPeer(chainID1, chainID2) 920 if err != nil { 921 t.Fail() 922 t.Logf("Error creating peer: %s", err) 923 } 924 925 defer finitPeer(lis, chainID1, chainID2) 926 927 err = runChaincodeInvokeChaincode(t, chainID1, chainID2, "") 928 if err != nil { 929 t.Fail() 930 t.Logf("Failed chaincode invoke chaincode : %s", err) 931 closeListenerAndSleep(lis) 932 return 933 } 934 935 closeListenerAndSleep(lis) 936 } 937 938 // Test the execution of a chaincode that invokes another chaincode with wrong parameters. Should receive error from 939 // from the called chaincode 940 func TestChaincodeInvokeChaincodeErrorCase(t *testing.T) { 941 chainID := util.GetTestChainID() 942 943 lis, err := initPeer(chainID) 944 if err != nil { 945 t.Fail() 946 t.Logf("Error creating peer: %s", err) 947 } 948 949 defer finitPeer(lis, chainID) 950 951 var ctxt = context.Background() 952 953 // Deploy first chaincode 954 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 955 956 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 957 f := "init" 958 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 959 960 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 961 962 sProp, prop := putils.MockSignedEndorserProposalOrPanic(util.GetTestChainID(), spec1, []byte([]byte("Alice")), nil) 963 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, sProp, prop) 964 965 var nextBlockNumber uint64 = 1 966 967 _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber) 968 nextBlockNumber++ 969 ccID1 := spec1.ChaincodeId.Name 970 if err != nil { 971 t.Fail() 972 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 973 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 974 return 975 } 976 977 time.Sleep(time.Second) 978 979 // Deploy second chaincode 980 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/passthru" 981 982 cID2 := &pb.ChaincodeID{Name: "pthru", Path: url2, Version: "0"} 983 f = "init" 984 args = util.ToChaincodeArgs(f) 985 986 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 987 988 cccid2 := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, sProp, prop) 989 990 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 991 nextBlockNumber++ 992 ccID2 := spec2.ChaincodeId.Name 993 if err != nil { 994 t.Fail() 995 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 996 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 997 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 998 return 999 } 1000 1001 time.Sleep(time.Second) 1002 1003 // Invoke second chaincode, which will inturn invoke the first chaincode but pass bad params 1004 f = ccID1 1005 args = util.ToChaincodeArgs(f, "invoke", "a") 1006 1007 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1008 // Invoke chaincode 1009 _, _, _, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice")) 1010 1011 if err == nil { 1012 t.Fail() 1013 t.Logf("Error invoking <%s>: %s", ccID2, err) 1014 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1015 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1016 return 1017 } 1018 1019 if strings.Index(err.Error(), "Error invoking chaincode: Incorrect number of arguments. Expecting 3") < 0 { 1020 t.Fail() 1021 t.Logf("Unexpected error %s", err) 1022 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1023 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1024 return 1025 } 1026 1027 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1028 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1029 } 1030 1031 // Test the invocation of a transaction. 1032 func TestQueries(t *testing.T) { 1033 1034 chainID := util.GetTestChainID() 1035 1036 lis, err := initPeer(chainID) 1037 if err != nil { 1038 t.Fail() 1039 t.Logf("Error creating peer: %s", err) 1040 } 1041 1042 defer finitPeer(lis, chainID) 1043 1044 var ctxt = context.Background() 1045 1046 url := "github.com/hyperledger/fabric/examples/chaincode/go/map" 1047 cID := &pb.ChaincodeID{Name: "tmap", Path: url, Version: "0"} 1048 1049 f := "init" 1050 args := util.ToChaincodeArgs(f) 1051 1052 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1053 1054 cccid := ccprovider.NewCCContext(chainID, "tmap", "0", "", false, nil, nil) 1055 1056 var nextBlockNumber uint64 = 1 1057 _, err = deploy(ctxt, cccid, spec, nextBlockNumber) 1058 nextBlockNumber++ 1059 ccID := spec.ChaincodeId.Name 1060 if err != nil { 1061 t.Fail() 1062 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 1063 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1064 return 1065 } 1066 1067 // Add 101 marbles for testing range queries and rich queries (for capable ledgers) 1068 // The tests will test both range and rich queries and queries with query limits 1069 for i := 1; i <= 101; i++ { 1070 f = "put" 1071 1072 // 51 owned by tom, 50 by jerry 1073 owner := "tom" 1074 if i%2 == 0 { 1075 owner = "jerry" 1076 } 1077 1078 // one marble color is red, 100 are blue 1079 color := "blue" 1080 if i == 12 { 1081 color = "red" 1082 } 1083 1084 key := fmt.Sprintf("marble%03d", i) 1085 argsString := fmt.Sprintf("{\"docType\":\"marble\",\"name\":\"%s\",\"color\":\"%s\",\"size\":35,\"owner\":\"%s\"}", key, color, owner) 1086 args = util.ToChaincodeArgs(f, key, argsString) 1087 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1088 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1089 nextBlockNumber++ 1090 1091 if err != nil { 1092 t.Fail() 1093 t.Logf("Error invoking <%s>: %s", ccID, err) 1094 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1095 return 1096 } 1097 } 1098 1099 //The following range query for "marble001" to "marble011" should return 10 marbles 1100 f = "keys" 1101 args = util.ToChaincodeArgs(f, "marble001", "marble011") 1102 1103 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1104 _, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1105 nextBlockNumber++ 1106 if err != nil { 1107 t.Fail() 1108 t.Logf("Error invoking <%s>: %s", ccID, err) 1109 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1110 return 1111 } 1112 1113 var keys []interface{} 1114 err = json.Unmarshal(retval, &keys) 1115 if len(keys) != 10 { 1116 t.Fail() 1117 t.Logf("Error detected with the range query, should have returned 10 but returned %v", len(keys)) 1118 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1119 return 1120 } 1121 1122 // querying for all marbles will return 101 marbles 1123 // this query should return exactly 101 results (one call to Next()) 1124 //The following range query for "marble001" to "marble102" should return 101 marbles 1125 f = "keys" 1126 args = util.ToChaincodeArgs(f, "marble001", "marble102") 1127 1128 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1129 _, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1130 nextBlockNumber++ 1131 if err != nil { 1132 t.Fail() 1133 t.Logf("Error invoking <%s>: %s", ccID, err) 1134 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1135 return 1136 } 1137 1138 //unmarshal the results 1139 err = json.Unmarshal(retval, &keys) 1140 1141 //check to see if there are 101 values 1142 //default query limit of 10000 is used, this query is effectively unlimited 1143 if len(keys) != 101 { 1144 t.Fail() 1145 t.Logf("Error detected with the range query, should have returned 101 but returned %v", len(keys)) 1146 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1147 return 1148 } 1149 1150 // ExecuteQuery supported only for CouchDB and 1151 // query limits apply for CouchDB range and rich queries only 1152 if ledgerconfig.IsCouchDBEnabled() == true { 1153 1154 // corner cases for shim batching. currnt shim batch size is 100 1155 // this query should return exactly 100 results (no call to Next()) 1156 f = "query" 1157 args = util.ToChaincodeArgs(f, "{\"selector\":{\"color\":\"blue\"}}") 1158 1159 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1160 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1161 nextBlockNumber++ 1162 1163 if err != nil { 1164 t.Fail() 1165 t.Logf("Error invoking <%s>: %s", ccID, err) 1166 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1167 return 1168 } 1169 1170 //unmarshal the results 1171 err = json.Unmarshal(retval, &keys) 1172 1173 //check to see if there are 100 values 1174 if len(keys) != 100 { 1175 t.Fail() 1176 t.Logf("Error detected with the rich query, should have returned 100 but returned %v %s", len(keys), keys) 1177 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1178 return 1179 } 1180 1181 //Reset the query limit to 5 1182 viper.Set("ledger.state.queryLimit", 5) 1183 1184 //The following range query for "marble01" to "marble11" should return 5 marbles due to the queryLimit 1185 f = "keys" 1186 args = util.ToChaincodeArgs(f, "marble001", "marble011") 1187 1188 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1189 _, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1190 nextBlockNumber++ 1191 if err != nil { 1192 t.Fail() 1193 t.Logf("Error invoking <%s>: %s", ccID, err) 1194 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1195 return 1196 } 1197 1198 //unmarshal the results 1199 err = json.Unmarshal(retval, &keys) 1200 1201 //check to see if there are 5 values 1202 if len(keys) != 5 { 1203 t.Fail() 1204 t.Logf("Error detected with the range query, should have returned 5 but returned %v", len(keys)) 1205 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1206 return 1207 } 1208 1209 //Reset the query limit to 10000 1210 viper.Set("ledger.state.queryLimit", 10000) 1211 1212 //The following rich query for should return 50 marbles 1213 f = "query" 1214 args = util.ToChaincodeArgs(f, "{\"selector\":{\"owner\":\"jerry\"}}") 1215 1216 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1217 _, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1218 nextBlockNumber++ 1219 1220 if err != nil { 1221 t.Fail() 1222 t.Logf("Error invoking <%s>: %s", ccID, err) 1223 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1224 return 1225 } 1226 1227 //unmarshal the results 1228 err = json.Unmarshal(retval, &keys) 1229 1230 //check to see if there are 50 values 1231 //default query limit of 10000 is used, this query is effectively unlimited 1232 if len(keys) != 50 { 1233 t.Fail() 1234 t.Logf("Error detected with the rich query, should have returned 9 but returned %v", len(keys)) 1235 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1236 return 1237 } 1238 1239 //Reset the query limit to 5 1240 viper.Set("ledger.state.queryLimit", 5) 1241 1242 //The following rich query should return 5 marbles due to the queryLimit 1243 f = "query" 1244 args = util.ToChaincodeArgs(f, "{\"selector\":{\"owner\":\"jerry\"}}") 1245 1246 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1247 _, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1248 nextBlockNumber++ 1249 if err != nil { 1250 t.Fail() 1251 t.Logf("Error invoking <%s>: %s", ccID, err) 1252 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1253 return 1254 } 1255 1256 //unmarshal the results 1257 err = json.Unmarshal(retval, &keys) 1258 1259 //check to see if there are 5 values 1260 if len(keys) != 5 { 1261 t.Fail() 1262 t.Logf("Error detected with the rich query, should have returned 5 but returned %v", len(keys)) 1263 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1264 return 1265 } 1266 1267 } 1268 1269 // modifications for history query 1270 f = "put" 1271 args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}") 1272 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1273 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1274 nextBlockNumber++ 1275 if err != nil { 1276 t.Fail() 1277 t.Logf("Error invoking <%s>: %s", ccID, err) 1278 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1279 return 1280 } 1281 1282 f = "put" 1283 args = util.ToChaincodeArgs(f, "marble012", "{\"docType\":\"marble\",\"name\":\"marble012\",\"color\":\"red\",\"size\":30,\"owner\":\"jerry\"}") 1284 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1285 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1286 nextBlockNumber++ 1287 if err != nil { 1288 t.Fail() 1289 t.Logf("Error invoking <%s>: %s", ccID, err) 1290 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1291 return 1292 } 1293 1294 //The following history query for "marble12" should return 3 records 1295 f = "history" 1296 args = util.ToChaincodeArgs(f, "marble012") 1297 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1298 _, _, retval, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1299 nextBlockNumber++ 1300 if err != nil { 1301 t.Fail() 1302 t.Logf("Error invoking <%s>: %s", ccID, err) 1303 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1304 return 1305 } 1306 1307 var history []interface{} 1308 err = json.Unmarshal(retval, &history) 1309 if len(history) != 3 { 1310 t.Fail() 1311 t.Logf("Error detected with the history query, should have returned 3 but returned %v", len(keys)) 1312 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1313 return 1314 } 1315 1316 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1317 } 1318 1319 func TestGetEvent(t *testing.T) { 1320 1321 testCases := []struct { 1322 chaincodeType pb.ChaincodeSpec_Type 1323 chaincodePath string 1324 }{ 1325 {pb.ChaincodeSpec_GOLANG, chaincodeEventSenderGolangPath}, 1326 {pb.ChaincodeSpec_JAVA, chaincodeEventSenderJavaPath}, 1327 } 1328 1329 chainID := util.GetTestChainID() 1330 var nextBlockNumber uint64 1331 1332 lis, err := initPeer(chainID) 1333 if err != nil { 1334 t.Fail() 1335 t.Logf("Error creating peer: %s", err) 1336 } 1337 1338 nextBlockNumber++ 1339 1340 defer finitPeer(lis, chainID) 1341 1342 for _, tc := range testCases { 1343 t.Run(tc.chaincodeType.String(), func(t *testing.T) { 1344 1345 if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" { 1346 t.Skip("No Java chaincode support yet on non-x86_64.") 1347 } 1348 1349 var ctxt = context.Background() 1350 1351 cID := &pb.ChaincodeID{Name: generateChaincodeName(tc.chaincodeType), Path: tc.chaincodePath, Version: "0"} 1352 f := "init" 1353 spec := &pb.ChaincodeSpec{Type: tc.chaincodeType, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: util.ToChaincodeArgs(f)}} 1354 1355 cccid := ccprovider.NewCCContext(chainID, cID.Name, cID.Version, "", false, nil, nil) 1356 _, err = deploy(ctxt, cccid, spec, nextBlockNumber) 1357 nextBlockNumber++ 1358 ccID := spec.ChaincodeId.Name 1359 if err != nil { 1360 t.Fail() 1361 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 1362 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1363 return 1364 } 1365 1366 time.Sleep(time.Second) 1367 1368 args := util.ToChaincodeArgs("invoke", "i", "am", "satoshi") 1369 1370 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1371 1372 var ccevt *pb.ChaincodeEvent 1373 ccevt, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1374 nextBlockNumber++ 1375 1376 if err != nil { 1377 t.Logf("Error invoking chaincode %s(%s)", ccID, err) 1378 t.Fail() 1379 } 1380 1381 if ccevt == nil { 1382 t.Logf("Error ccevt is nil %s(%s)", ccID, err) 1383 t.Fail() 1384 } 1385 1386 if ccevt.ChaincodeId != ccID { 1387 t.Logf("Error ccevt id(%s) != cid(%s)", ccevt.ChaincodeId, ccID) 1388 t.Fail() 1389 } 1390 1391 if strings.Index(string(ccevt.Payload), "i,am,satoshi") < 0 { 1392 t.Logf("Error expected event not found (%s)", string(ccevt.Payload)) 1393 t.Fail() 1394 } 1395 1396 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1397 }) 1398 } 1399 1400 } 1401 1402 // Test the execution of a chaincode that queries another chaincode 1403 // example02 implements "query" as a function in Invoke. example05 calls example02 1404 func TestChaincodeQueryChaincodeUsingInvoke(t *testing.T) { 1405 //this is essentially same as the ChaincodeInvokeChaincode now that 1406 //we don't distinguish between Invoke and Query (there's no separate "Query") 1407 t.Skip() 1408 chainID := util.GetTestChainID() 1409 1410 var peerLis net.Listener 1411 var err error 1412 if peerLis, err = initPeer(chainID); err != nil { 1413 t.Fail() 1414 t.Logf("Error registering user %s", err) 1415 return 1416 } 1417 1418 defer finitPeer(peerLis, chainID) 1419 1420 var ctxt = context.Background() 1421 1422 // Deploy first chaincode 1423 url1 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example02" 1424 1425 cID1 := &pb.ChaincodeID{Name: "example02", Path: url1, Version: "0"} 1426 f := "init" 1427 args := util.ToChaincodeArgs(f, "a", "100", "b", "200") 1428 1429 spec1 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID1, Input: &pb.ChaincodeInput{Args: args}} 1430 1431 sProp, prop := putils.MockSignedEndorserProposalOrPanic(util.GetTestChainID(), spec1, []byte([]byte("Alice")), nil) 1432 cccid1 := ccprovider.NewCCContext(chainID, "example02", "0", "", false, sProp, prop) 1433 var nextBlockNumber uint64 1434 _, err = deploy(ctxt, cccid1, spec1, nextBlockNumber) 1435 nextBlockNumber++ 1436 ccID1 := spec1.ChaincodeId.Name 1437 if err != nil { 1438 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1439 t.Fail() 1440 t.Logf("Error initializing chaincode %s(%s)", ccID1, err) 1441 return 1442 } 1443 1444 time.Sleep(time.Second) 1445 1446 // Deploy second chaincode 1447 url2 := "github.com/hyperledger/fabric/examples/chaincode/go/chaincode_example05" 1448 1449 cID2 := &pb.ChaincodeID{Name: "example05", Path: url2, Version: "0"} 1450 f = "init" 1451 args = util.ToChaincodeArgs(f, "sum", "0") 1452 1453 spec2 := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1454 1455 cccid2 := ccprovider.NewCCContext(chainID, "example05", "0", "", false, sProp, prop) 1456 1457 _, err = deploy(ctxt, cccid2, spec2, nextBlockNumber) 1458 nextBlockNumber++ 1459 ccID2 := spec2.ChaincodeId.Name 1460 if err != nil { 1461 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1462 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1463 t.Fail() 1464 t.Logf("Error initializing chaincode %s(%s)", ccID2, err) 1465 return 1466 } 1467 1468 time.Sleep(time.Second) 1469 1470 // Invoke second chaincode, which will inturn query the first chaincode 1471 f = "invoke" 1472 args = util.ToChaincodeArgs(f, ccID1, "sum") 1473 1474 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1475 // Invoke chaincode 1476 var retVal []byte 1477 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice")) 1478 nextBlockNumber++ 1479 if err != nil { 1480 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1481 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1482 t.Fail() 1483 t.Logf("Error invoking <%s>: %s", ccID2, err) 1484 return 1485 } 1486 1487 // Check the return value 1488 result, err := strconv.Atoi(string(retVal)) 1489 if err != nil || result != 300 { 1490 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1491 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1492 t.Fail() 1493 t.Logf("Incorrect final state after transaction for <%s>: %s", ccID1, err) 1494 return 1495 } 1496 1497 // Query second chaincode, which will inturn query the first chaincode 1498 f = "query" 1499 args = util.ToChaincodeArgs(f, ccID1, "sum") 1500 1501 spec2 = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID2, Input: &pb.ChaincodeInput{Args: args}} 1502 // Invoke chaincode 1503 _, _, retVal, err = invoke(ctxt, chainID, spec2, nextBlockNumber, []byte("Alice")) 1504 1505 if err != nil { 1506 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1507 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1508 t.Fail() 1509 t.Logf("Error querying <%s>: %s", ccID2, err) 1510 return 1511 } 1512 1513 // Check the return value 1514 result, err = strconv.Atoi(string(retVal)) 1515 if err != nil || result != 300 { 1516 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1517 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1518 t.Fail() 1519 t.Logf("Incorrect final value after query for <%s>: %s", ccID1, err) 1520 return 1521 } 1522 1523 theChaincodeSupport.Stop(ctxt, cccid1, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec1}) 1524 theChaincodeSupport.Stop(ctxt, cccid2, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec2}) 1525 } 1526 1527 // test that invoking a security-sensitive system chaincode fails 1528 func TestChaincodeInvokesForbiddenSystemChaincode(t *testing.T) { 1529 chainID := util.GetTestChainID() 1530 1531 lis, err := initPeer(chainID) 1532 if err != nil { 1533 t.Fail() 1534 t.Logf("Error creating peer: %s", err) 1535 } 1536 1537 defer finitPeer(lis, chainID) 1538 1539 var ctxt = context.Background() 1540 1541 var nextBlockNumber uint64 = 1 1542 1543 // Deploy second chaincode 1544 url := "github.com/hyperledger/fabric/examples/chaincode/go/passthru" 1545 1546 cID := &pb.ChaincodeID{Name: "pthru", Path: url, Version: "0"} 1547 f := "init" 1548 args := util.ToChaincodeArgs(f) 1549 1550 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1551 1552 cccid := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil) 1553 1554 _, err = deploy(ctxt, cccid, spec, nextBlockNumber) 1555 nextBlockNumber++ 1556 ccID := spec.ChaincodeId.Name 1557 if err != nil { 1558 t.Fail() 1559 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 1560 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1561 return 1562 } 1563 1564 time.Sleep(time.Second) 1565 1566 // send an invoke to pass thru to invoke "escc" system chaincode 1567 // this should fail 1568 args = util.ToChaincodeArgs("escc/"+chainID, "getid", chainID, "pthru") 1569 1570 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1571 // Invoke chaincode 1572 _, _, _, err = invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1573 if err == nil { 1574 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1575 t.Logf("invoking <%s> should have failed", ccID) 1576 t.Fail() 1577 return 1578 } 1579 } 1580 1581 // Test the execution of a chaincode that invokes system chaincode 1582 // uses the "pthru" chaincode to query "lscc" for the "pthru" chaincode 1583 func TestChaincodeInvokesSystemChaincode(t *testing.T) { 1584 chainID := util.GetTestChainID() 1585 1586 lis, err := initPeer(chainID) 1587 if err != nil { 1588 t.Fail() 1589 t.Logf("Error creating peer: %s", err) 1590 } 1591 1592 defer finitPeer(lis, chainID) 1593 1594 var ctxt = context.Background() 1595 1596 var nextBlockNumber uint64 = 1 1597 1598 // Deploy second chaincode 1599 url := "github.com/hyperledger/fabric/examples/chaincode/go/passthru" 1600 1601 cID := &pb.ChaincodeID{Name: "pthru", Path: url, Version: "0"} 1602 f := "init" 1603 args := util.ToChaincodeArgs(f) 1604 1605 spec := &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1606 1607 cccid := ccprovider.NewCCContext(chainID, "pthru", "0", "", false, nil, nil) 1608 1609 _, err = deploy(ctxt, cccid, spec, nextBlockNumber) 1610 nextBlockNumber++ 1611 ccID := spec.ChaincodeId.Name 1612 if err != nil { 1613 t.Fail() 1614 t.Logf("Error initializing chaincode %s(%s)", ccID, err) 1615 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1616 return 1617 } 1618 1619 time.Sleep(time.Second) 1620 1621 //send an invoke to pass thru to query "lscc" system chaincode on chainID to get 1622 //information about "pthru" 1623 args = util.ToChaincodeArgs("lscc/"+chainID, "getid", chainID, "pthru") 1624 1625 spec = &pb.ChaincodeSpec{Type: 1, ChaincodeId: cID, Input: &pb.ChaincodeInput{Args: args}} 1626 // Invoke chaincode 1627 _, _, retval, err := invoke(ctxt, chainID, spec, nextBlockNumber, nil) 1628 1629 if err != nil { 1630 t.Fail() 1631 t.Logf("Error invoking <%s>: %s", ccID, err) 1632 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1633 return 1634 } 1635 1636 if string(retval) != "pthru" { 1637 t.Fail() 1638 t.Logf("Expected to get back \"pthru\" from lscc but got back %s", string(retval)) 1639 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1640 return 1641 } 1642 1643 theChaincodeSupport.Stop(ctxt, cccid, &pb.ChaincodeDeploymentSpec{ChaincodeSpec: spec}) 1644 } 1645 1646 func TestChaincodeInitializeInitError(t *testing.T) { 1647 testCases := []struct { 1648 name string 1649 chaincodeType pb.ChaincodeSpec_Type 1650 chaincodePath string 1651 args []string 1652 }{ 1653 {"NotSuccessResponse", pb.ChaincodeSpec_GOLANG, chaincodeExample02GolangPath, []string{"init", "not", "enough", "args"}}, 1654 {"NotSuccessResponse", pb.ChaincodeSpec_JAVA, chaincodeExample02JavaPath, []string{"init", "not", "enough", "args"}}, 1655 {"RuntimeException", pb.ChaincodeSpec_JAVA, chaincodeExample06JavaPath, []string{"runtimeException"}}, 1656 } 1657 1658 channelID := util.GetTestChainID() 1659 1660 for _, tc := range testCases { 1661 t.Run(tc.name+"_"+tc.chaincodeType.String(), func(t *testing.T) { 1662 1663 if tc.chaincodeType == pb.ChaincodeSpec_JAVA && runtime.GOARCH != "amd64" { 1664 t.Skip("No Java chaincode support yet on non-x86_64.") 1665 } 1666 1667 // initialize peer 1668 if listener, err := initPeer(channelID); err != nil { 1669 t.Errorf("Error creating peer: %s", err) 1670 } else { 1671 defer finitPeer(listener, channelID) 1672 } 1673 1674 var nextBlockNumber uint64 1675 1676 // the chaincode to install and instanciate 1677 chaincodeName := generateChaincodeName(tc.chaincodeType) 1678 chaincodePath := tc.chaincodePath 1679 chaincodeVersion := "1.0.0.0" 1680 chaincodeType := tc.chaincodeType 1681 chaincodeDeployArgs := util.ArrayToChaincodeArgs(tc.args) 1682 1683 // new chaincode context for passing around parameters 1684 chaincodeCtx := ccprovider.NewCCContext(channelID, chaincodeName, chaincodeVersion, "", false, nil, nil) 1685 1686 // attempt to deploy chaincode 1687 _, err := deployChaincode(context.Background(), chaincodeCtx, chaincodeType, chaincodePath, chaincodeDeployArgs, nextBlockNumber) 1688 1689 // deploy should of failed 1690 if err == nil { 1691 t.Fatal("Deployment should have failed.") 1692 } 1693 t.Log(err) 1694 1695 }) 1696 } 1697 } 1698 1699 func TestMain(m *testing.M) { 1700 var err error 1701 1702 msptesttools.LoadMSPSetupForTesting() 1703 signer, err = mspmgmt.GetLocalMSP().GetDefaultSigningIdentity() 1704 if err != nil { 1705 os.Exit(-1) 1706 fmt.Print("Could not initialize msp/signer") 1707 return 1708 } 1709 1710 SetupTestConfig() 1711 os.Exit(m.Run()) 1712 } 1713 1714 func deployChaincode(ctx context.Context, chaincodeCtx *ccprovider.CCContext, chaincodeType pb.ChaincodeSpec_Type, path string, args [][]byte, nextBlockNumber uint64) ([]byte, error) { 1715 1716 chaincodeSpec := &pb.ChaincodeSpec{ 1717 ChaincodeId: &pb.ChaincodeID{ 1718 Name: chaincodeCtx.Name, 1719 Version: chaincodeCtx.Version, 1720 Path: path, 1721 }, 1722 Type: chaincodeType, 1723 Input: &pb.ChaincodeInput{ 1724 Args: args, 1725 }, 1726 } 1727 1728 result, err := deploy(ctx, chaincodeCtx, chaincodeSpec, nextBlockNumber) 1729 if err != nil { 1730 return nil, fmt.Errorf("Error deploying <%s:%s>: %s", chaincodeSpec.ChaincodeId.Name, chaincodeSpec.ChaincodeId.Version, err) 1731 } 1732 return result, nil 1733 } 1734 1735 var signer msp.SigningIdentity 1736 1737 var rng *rand.Rand = rand.New(rand.NewSource(time.Now().UnixNano())) 1738 1739 func generateChaincodeName(chaincodeType pb.ChaincodeSpec_Type) string { 1740 prefix := "cc_" 1741 switch chaincodeType { 1742 case pb.ChaincodeSpec_GOLANG: 1743 prefix = "cc_go_" 1744 case pb.ChaincodeSpec_JAVA: 1745 prefix = "cc_java_" 1746 case pb.ChaincodeSpec_NODE: 1747 prefix = "cc_js_" 1748 } 1749 return fmt.Sprintf("%s%06d", prefix, rng.Intn(999999)) 1750 } 1751 1752 type CreatorPolicy struct { 1753 Creators [][]byte 1754 } 1755 1756 // Evaluate takes a set of SignedData and evaluates whether this set of signatures satisfies the policy 1757 func (c *CreatorPolicy) Evaluate(signatureSet []*common.SignedData) error { 1758 for _, value := range c.Creators { 1759 if bytes.Compare(signatureSet[0].Identity, value) == 0 { 1760 return nil 1761 } 1762 } 1763 return fmt.Errorf("Creator not recognized [%s]", string(signatureSet[0].Identity)) 1764 } 1765 1766 type mockPolicyCheckerFactory struct{} 1767 1768 func (f *mockPolicyCheckerFactory) NewPolicyChecker() policy.PolicyChecker { 1769 return policy.NewPolicyChecker( 1770 peer.NewChannelPolicyManagerGetter(), 1771 &policy.MockIdentityDeserializer{[]byte("Admin"), []byte("msg1")}, 1772 &policy.MockMSPPrincipalGetter{Principal: []byte("Admin")}, 1773 ) 1774 }